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);
> +}


Reply via email to