[gcc(refs/vendors/riscv/heads/gcc-15-with-riscv-opts)] RISC-V: Allow different dynamic floating point mode to be merged [PR119832]
Jeff Law
law@gcc.gnu.org
Fri Jan 30 06:32:36 GMT 2026
https://gcc.gnu.org/g:fb897450e96776893307f08ac6204b548a2f02f5
commit fb897450e96776893307f08ac6204b548a2f02f5
Author: Kito Cheng <kito.cheng@sifive.com>
Date: Tue Apr 29 11:35:00 2025 +0800
RISC-V: Allow different dynamic floating point mode to be merged [PR119832]
Although we already try to set the mode needed to FRM_DYN after a function call,
there are still some corner cases where both FRM_DYN and FRM_DYN_CALL may appear
on incoming edges.
Therefore, we use TARGET_MODE_CONFLUENCE to tell GCC that FRM_DYN, FRM_DYN_CALL,
and FRM_DYN_EXIT modes are compatible.
gcc/ChangeLog:
PR target/119832
* config/riscv/riscv.cc (riscv_dynamic_frm_mode_p): New.
(riscv_mode_confluence): New.
(TARGET_MODE_CONFLUENCE): Define to riscv_mode_confluence.
gcc/testsuite/ChangeLog:
PR target/119832
* g++.target/riscv/pr119832.C: New test.
(cherry picked from commit e5d1f538bb7d2c7a7a4acf4a4516fa8933dc2888)
Diff:
---
gcc/config/riscv/riscv.cc | 37 +++++++++++++++++++++++++++++++
gcc/testsuite/g++.target/riscv/pr119832.C | 27 ++++++++++++++++++++++
2 files changed, 64 insertions(+)
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index bc6d568084f6..3ad2b52f285a 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -12291,6 +12291,41 @@ riscv_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET)
}
}
+/* Return TRUE if the rouding mode is dynamic. */
+
+static bool
+riscv_dynamic_frm_mode_p (int mode)
+{
+ return mode == riscv_vector::FRM_DYN
+ || mode == riscv_vector::FRM_DYN_CALL
+ || mode == riscv_vector::FRM_DYN_EXIT;
+}
+
+/* Implement TARGET_MODE_CONFLUENCE. */
+
+static int
+riscv_mode_confluence (int entity, int mode1, int mode2)
+{
+ switch (entity)
+ {
+ case RISCV_VXRM:
+ return VXRM_MODE_NONE;
+ case RISCV_FRM:
+ {
+ /* FRM_DYN, FRM_DYN_CALL and FRM_DYN_EXIT are all compatible.
+ Although we already try to set the mode needed to FRM_DYN after a
+ function call, there are still some corner cases where both FRM_DYN
+ and FRM_DYN_CALL may appear on incoming edges. */
+ if (riscv_dynamic_frm_mode_p (mode1)
+ && riscv_dynamic_frm_mode_p (mode2))
+ return riscv_vector::FRM_DYN;
+ return riscv_vector::FRM_NONE;
+ }
+ default:
+ gcc_unreachable ();
+ }
+}
+
/* Return TRUE that an insn is asm. */
static bool
@@ -14374,6 +14409,8 @@ bool need_shadow_stack_push_pop_p ()
#define TARGET_MODE_EMIT riscv_emit_mode_set
#undef TARGET_MODE_NEEDED
#define TARGET_MODE_NEEDED riscv_mode_needed
+#undef TARGET_MODE_CONFLUENCE
+#define TARGET_MODE_CONFLUENCE riscv_mode_confluence
#undef TARGET_MODE_AFTER
#define TARGET_MODE_AFTER riscv_mode_after
#undef TARGET_MODE_ENTRY
diff --git a/gcc/testsuite/g++.target/riscv/pr119832.C b/gcc/testsuite/g++.target/riscv/pr119832.C
new file mode 100644
index 000000000000..f4dc480e6d59
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/pr119832.C
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=rv64gcv -mabi=lp64 -ffast-math" } */
+
+struct ac {
+ ~ac();
+ void u();
+};
+struct ae {
+ int s;
+ float *ag;
+};
+
+float c;
+
+void ak(ae *al, int n) {
+ ac d;
+ for (int i;i<n;++i) {
+ float a = 0;
+ for (long j; j < al[i].s; j++)
+ a += al[i].ag[j];
+ c = a;
+ d.u();
+ }
+}
+
+/* { dg-final { scan-assembler-not "frrm\t" } } */
+/* { dg-final { scan-assembler-not "fsrm\t" } } */
More information about the Gcc-cvs
mailing list