https://gcc.gnu.org/g:39ba75fa8d3132416015dd29be9a4a6670af7ba9
commit r17-3862-g39ba75fa8d3132416015dd29be9a4a6670af7ba9 Author: Bohan Lei <[email protected]> Date: Mon Aug 31 15:51:57 2026 +0800 RISC-V: Avoid using fmv_cost for memory roundtrips In riscv_register_move_cost, the function `riscv_secondary_memory_needed` call is at the end, and has no impact on the early-returned values. Even if the move has to go through memory, the register move cost is still used, which can lead to suboptimal code generation, and even crashes. Actually the current testcase can lead to an ICE without the patch when using `-mtune=xt-c9501fdvt`, whose `fmv_cost` is 2 at present. I didn't write that in the testcase as the fmv_cost being 2 does not correctly reflect our design and we may change it in the future, in a separate patch. Regtested on rv64gcv and rv32gcv, no regression. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_register_move_cost): Check secondary memory necessity before early return. gcc/testsuite/ChangeLog: * gcc.target/riscv/rv32-fmv-cost-memory.c: New test. Diff: --- gcc/config/riscv/riscv.cc | 6 +++++- gcc/testsuite/gcc.target/riscv/rv32-fmv-cost-memory.c | 11 +++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 62fa062cf58b..aafbcd5db0a3 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -11285,6 +11285,10 @@ riscv_register_move_cost (machine_mode mode, bool from_is_gpr = reg_class_subset_p (from, GR_REGS); bool to_is_fpr = reg_class_subset_p (to, FP_REGS); bool to_is_gpr = reg_class_subset_p (to, GR_REGS); + + if (riscv_secondary_memory_needed (mode, from, to)) + return 8; + if ((from_is_fpr && to_is_gpr) || (from_is_gpr && to_is_fpr)) return tune_param->fmv_cost; @@ -11304,7 +11308,7 @@ riscv_register_move_cost (machine_mode mode, return get_fr2vr_cost (); } - return riscv_secondary_memory_needed (mode, from, to) ? 8 : 2; + return 2; } /* Implement TARGET_HARD_REGNO_NREGS. */ diff --git a/gcc/testsuite/gcc.target/riscv/rv32-fmv-cost-memory.c b/gcc/testsuite/gcc.target/riscv/rv32-fmv-cost-memory.c new file mode 100644 index 000000000000..2d23eaf9145c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rv32-fmv-cost-memory.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc -mabi=ilp32 -O2 -mtune=xt-c908" } */ + +double +foo (int c, double x, double y) +{ + return c ? x : y; +} + +/* { dg-final { scan-assembler-not {\mfld\M} } } */ +/* { dg-final { scan-assembler-not {\mfsd\M} } } */
