diff options
author | Haochen Gui <guihaoc@gcc.gnu.org> | 2023-12-11 08:40:34 +0800 |
---|---|---|
committer | Haochen Gui <guihaoc@gcc.gnu.org> | 2023-12-11 08:46:10 +0800 |
commit | 46e342b985e6b4058db73875103cced2666e84e2 (patch) | |
tree | 27fd48c21a1d5b50e123130613c337ab9fe1065c /gcc | |
parent | 4a6613e2a417512077ea39b5097c0c602055f028 (diff) | |
download | gcc-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.md | 30 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/powerpc/pr112707-1.c | 16 |
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); +} |