]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rs6000: Enable lrint<mode>si2 on old archs with stfiwx enabled
authorHaochen Gui <guihaoc@gcc.gnu.org>
Mon, 11 Dec 2023 00:40:34 +0000 (08:40 +0800)
committerHaochen Gui <guihaoc@gcc.gnu.org>
Mon, 11 Dec 2023 00:46:10 +0000 (08:46 +0800)
The powerpc 32-bit processors (e.g. 5470) supports "fctiw" instruction,
but the instruction can't be generated on such platforms as the insn is
guard by TARGET_POPCNTD.  The root cause is SImode in float register is
supported from Power7.  Actually implementation of "fctiw" only needs
stfiwx which is supported by the old 32-bit processors.  This patch
enables "fctiw" expand for these processors.

gcc/
PR target/112707
* config/rs6000/rs6000.md (expand lrint<mode>si2): New.
(insn lrint<mode>si2): Rename to...
(*lrint<mode>si): ...this.
(lrint<mode>si_di): New.

gcc/testsuite/
PR target/112707
* gcc.target/powerpc/pr112707-1.c: New.

gcc/config/rs6000/rs6000.md
gcc/testsuite/gcc.target/powerpc/pr112707-1.c [new file with mode: 0644]

index 28482e3617e6ba4ca95e756a16e9cbaa2af9c9b0..3d9491769fc4d6977458818a3f8a3cdaa123de55 100644 (file)
   "fctid %0,%1"
   [(set_attr "type" "fp")])
 
-(define_insn "lrint<mode>si2"
+(define_expand "lrint<mode>si2"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=d")
+       (unspec:SI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
+                  UNSPEC_FCTIW))]
+  "TARGET_HARD_FLOAT && TARGET_STFIWX"
+{
+  /* For those old archs in which SImode can't be hold in float registers,
+     call lrint<mode>si_di to put the result in DImode then convert it via
+     stack.  */
+  if (!TARGET_POPCNTD)
+    {
+      rtx tmp = gen_reg_rtx (DImode);
+      emit_insn (gen_lrint<mode>si_di (tmp, operands[1]));
+      rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
+      emit_insn (gen_stfiwx (stack, tmp));
+      emit_move_insn (operands[0], stack);
+      DONE;
+    }
+})
+
+(define_insn "*lrint<mode>si"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=d")
        (unspec:SI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
                   UNSPEC_FCTIW))]
   "fctiw %0,%1"
   [(set_attr "type" "fp")])
 
+(define_insn "lrint<mode>si_di"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
+       (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
+                  UNSPEC_FCTIW))]
+  "TARGET_HARD_FLOAT && !TARGET_POPCNTD"
+  "fctiw %0,%1"
+  [(set_attr "type" "fp")])
+
 (define_insn "btrunc<mode>2"
   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,wa")
        (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "d,wa")]
diff --git a/gcc/testsuite/gcc.target/powerpc/pr112707-1.c b/gcc/testsuite/gcc.target/powerpc/pr112707-1.c
new file mode 100644 (file)
index 0000000..cce6bd7
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=7450 -fno-math-errno" } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-skip-if "" { has_arch_ppc64 } } */
+/* { dg-final { scan-assembler-times {\mfctiw\M} 2 } }  */
+/* { dg-final { scan-assembler-times {\mstfiwx\M} 2 } }  */
+
+int test1 (double a)
+{
+  return __builtin_irint (a);
+}
+
+int test2 (float a)
+{
+  return __builtin_irint (a);
+}