LGTM, good catch, and I am a little suppressed that we don't handle
"case REG" in riscv_rtx_costs...but adding that might disturb too much
at once, so this fix is fine for now, and ...and I guess we should
improve that in future.


On Tue, Aug 27, 2024 at 5:19 PM Xianmiao Qu <cooper...@linux.alibaba.com> wrote:
>
> Currently, in RV32, even with the D extension enabled, the cost of DFmode
> register moves is still set to 'COSTS_N_INSNS (2)'. This results in the
> 'lower-subreg' pass splitting DFmode register moves into two SImode SUBREG
> register moves, leading to the generation of many redundant instructions.
>
> As an example, consider the following test case:
>   double foo (int t, double a, double b)
>   {
>     if (t > 0)
>       return a;
>     else
>       return b;
>   }
>
> When compiling with -march=rv32imafdc -mabi=ilp32d, the following code is 
> generated:
>           .cfi_startproc
>           addi    sp,sp,-32
>           .cfi_def_cfa_offset 32
>           fsd     fa0,8(sp)
>           fsd     fa1,16(sp)
>           lw      a4,8(sp)
>           lw      a5,12(sp)
>           lw      a2,16(sp)
>           lw      a3,20(sp)
>           bgt     a0,zero,.L1
>           mv      a4,a2
>           mv      a5,a3
>   .L1:
>           sw      a4,24(sp)
>           sw      a5,28(sp)
>           fld     fa0,24(sp)
>           addi    sp,sp,32
>           .cfi_def_cfa_offset 0
>           jr      ra
>           .cfi_endproc
>
> After adjust the DFmode register move's cost to 'COSTS_N_INSNS (1)', the
> generated code is as follows, with a significant reduction in the number
> of instructions.
>           .cfi_startproc
>           ble     a0,zero,.L5
>           ret
>   .L5:
>           fmv.d   fa0,fa1
>           ret
>           .cfi_endproc
>
> gcc/
>         * config/riscv/riscv.cc (riscv_rtx_costs): Optimize the cost of the
>         DFmode register move for RV32.
>
> gcc/testsuite/
>         * gcc.target/riscv/rv32-movdf-cost.c: New test.
> ---
>  gcc/config/riscv/riscv.cc                        |  5 +++++
>  gcc/testsuite/gcc.target/riscv/rv32-movdf-cost.c | 13 +++++++++++++
>  2 files changed, 18 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rv32-movdf-cost.c
>
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index 1f544c1287ec..a47dedf73c10 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -3560,6 +3560,11 @@ riscv_rtx_costs (rtx x, machine_mode mode, int 
> outer_code, int opno ATTRIBUTE_UN
>        if (outer_code == INSN
>           && register_operand (SET_DEST (x), GET_MODE (SET_DEST (x))))
>         {
> +         if (REG_P (SET_SRC (x)) && TARGET_DOUBLE_FLOAT && mode == DFmode)
> +           {
> +             *total = COSTS_N_INSNS (1);
> +             return true;
> +           }
>           riscv_rtx_costs (SET_SRC (x), mode, outer_code, opno, total, speed);
>           return true;
>         }
> diff --git a/gcc/testsuite/gcc.target/riscv/rv32-movdf-cost.c 
> b/gcc/testsuite/gcc.target/riscv/rv32-movdf-cost.c
> new file mode 100644
> index 000000000000..cb679e7b95fb
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rv32-movdf-cost.c
> @@ -0,0 +1,13 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv32imafdc -mabi=ilp32d" } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" } } */
> +
> +double foo (int t, double a, double b)
> +{
> +  if (t > 0)
> +    return a;
> +  else
> +    return b;
> +}
> +
> +/* { dg-final { scan-assembler-not "fsd\t" } } */
> --
> 2.43.0
>

Reply via email to