On 8/27/24 3:17 AM, Xianmiao Qu 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.
I pushed this to the trunk.
jeff

Reply via email to