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.
---
 gcc/config/riscv/riscv.cc                             |  6 +++++-
 gcc/testsuite/gcc.target/riscv/rv32-fmv-cost-memory.c | 11 +++++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rv32-fmv-cost-memory.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 62fa062cf58..aafbcd5db0a 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 00000000000..2d23eaf9145
--- /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} } } */
-- 
2.47.1

Reply via email to