aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorHaochen Gui <guihaoc@gcc.gnu.org>2023-12-11 08:40:34 +0800
committerHaochen Gui <guihaoc@gcc.gnu.org>2023-12-11 08:46:10 +0800
commit46e342b985e6b4058db73875103cced2666e84e2 (patch)
tree27fd48c21a1d5b50e123130613c337ab9fe1065c /gcc
parent4a6613e2a417512077ea39b5097c0c602055f028 (diff)
downloadgcc-46e342b985e6b4058db73875103cced2666e84e2.zip
gcc-46e342b985e6b4058db73875103cced2666e84e2.tar.gz
gcc-46e342b985e6b4058db73875103cced2666e84e2.tar.bz2
rs6000: Enable lrint<mode>si2 on old archs with stfiwx enabled
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/rs6000/rs6000.md30
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr112707-1.c16
2 files changed, 45 insertions, 1 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 28482e3..3d94917 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -6740,7 +6740,27 @@
"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))]
@@ -6748,6 +6768,14 @@
"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
index 0000000..cce6bd7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr112707-1.c
@@ -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);
+}