Message ID | df01d123-2ae1-4d43-b0c9-2e2f9b5d29e1@linux.ibm.com |
---|---|
State | New |
Headers | show |
Series | [patch-1v2,rs6000] enable fctiw on old archs [PR112707] | expand |
Hi, on 2023/12/6 16:13, HAO CHEN GUI wrote: > Hi, > SImode in float register is supported on P7 above. It causes "fctiw" > can't be generated on old 32-bit processors as the output operand of > fctiw insn is an SImode in float/double register. This patch fixes the > problem by adding one expand and one insn pattern for fctiw. The output > of new pattern is DImode. When the targets don't support SImode in > float register, it calls the new insn pattern and convert the DImode > to SImode via stack. > > Compared to last version, > https://gcc.gnu.org/pipermail/gcc-patches/2023-December/638860.html > the main change is to change the mode of output operand of the new > insn from SFmode to DImode so that it can call stfiwx pattern directly. > No need additional unspecs. > > Bootstrapped and tested on x86 and powerpc64-linux BE and LE with > no regressions. Is this OK for trunk? > > Thanks > Gui Haochen > > ChangeLog > rs6000: enable fctiw on old archs Nit: s/rchs/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. > > patch.diff > diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md > index 2a1b5ecfaee..dfb7f19c6ad 100644 > --- a/gcc/config/rs6000/rs6000.md > +++ b/gcc/config/rs6000/rs6000.md > @@ -6722,7 +6722,27 @@ (define_insn "lrint<mode>di2" > "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_internal2 to put the result in SFmode then Nit: s/_internal2/_di/ s/SFmode/DImode/ OK for trunk with the above nits fixed, thanks! BR, Kewen > + 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))] > @@ -6730,6 +6750,14 @@ (define_insn "lrint<mode>si2" > "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 00000000000..cce6bd7f690 > --- /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); > +}
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 2a1b5ecfaee..dfb7f19c6ad 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -6722,7 +6722,27 @@ (define_insn "lrint<mode>di2" "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_internal2 to put the result in SFmode 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))] @@ -6730,6 +6750,14 @@ (define_insn "lrint<mode>si2" "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 00000000000..cce6bd7f690 --- /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); +}