LGTM


juzhe.zh...@rivai.ai
 
From: Kito Cheng
Date: 2025-04-29 11:35
To: gcc-patches; kito.cheng; palmer; jeffreyalaw; rdapp; juzhe.zhong; pan2.li; 
vineetg
CC: Kito Cheng
Subject: [PATCH] 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.
---
gcc/config/riscv/riscv.cc                 | 37 +++++++++++++++++++++++
gcc/testsuite/g++.target/riscv/pr119832.C | 27 +++++++++++++++++
2 files changed, 64 insertions(+)
create mode 100644 gcc/testsuite/g++.target/riscv/pr119832.C
 
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index bad59e248d0..198fe72ef68 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -12273,6 +12273,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
@@ -14356,6 +14391,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 00000000000..f4dc480e6d5
--- /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" } } */
-- 
2.37.1
 
 

Reply via email to