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} } } */

Reply via email to