FRM mode switching state machine has DYN as default state which it also
fallsback to after transitioning to other states such as DYN_CALL.
Currently TARGET_MODE_EMIT generates a FRM restore on any transition to
DYN leading to spurious/extraneous FRM restores.

Only do this if an interim static Rounding Mode was observed in the state
machine.

Fixes the extraneous FRM read/write in PR119164 (and also PR119832 w/o need
for TARGET_MODE_CONFLUENCE). Also reduces the number of FRM writes in
SPEC2017 -Ofast -mrv64gcv build significantly.

                   Before            After
              -------------      -------------
              frrm fsrmi fsrm   frrm fsrmi frrm
  perlbench_r   42    0    4      17    0    1
     cpugcc_r  167    0   17      11    0    0
     bwaves_r   16    0    1      16    0    1
        mcf_r   11    0    0      11    0    0
 cactusBSSN_r   76    0   27      19    0    1
       namd_r  119    0   63      14    0    1
     parest_r  168    0  114      24    0    1
     povray_r  123    1   17      26    1    6
        lbm_r    6    0    0       6    0    0
    omnetpp_r   17    0    1      17    0    1
        wrf_r 2287   13 1956    1268   13 1603
   cpuxalan_r   17    0    1      17    0    1
     ldecod_r   11    0    0      11    0    0
       x264_r   14    0    1      11    0    0
    blender_r  724   12  182      61   12   42
       cam4_r  324   13  169      45   13   20
  deepsjeng_r   11    0    0      11    0    0
    imagick_r  265   16   34     132   16   25
      leela_r   12    0    0      12    0    0
        nab_r   13    0    1      13    0    1
  exchange2_r   16    0    1      16    0    1
  fotonik3d_r   20    0   11      19    0    1
       roms_r   33    0   23      21    0    1
         xz_r    6    0    0       6    0    0
             ---------------    --------------
              4498   55 2623    1804   55 1707
             ---------------    --------------
                        7176              3566
             ---------------    --------------

        PR target/119164

gcc/ChangeLog:

        * config/riscv/riscv.cc (riscv_emit_frm_mode_set): check
        STATIC_FRM_P for transition to DYN.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/rvv/base/pr119164.c: New test.

Signed-off-by: Vineet Gupta <vine...@rivosinc.com>
---
 gcc/config/riscv/riscv.cc                     |  2 +-
 .../gcc.target/riscv/rvv/base/pr119164.c      | 22 +++++++++++++++++++
 2 files changed, 23 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr119164.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a1bb51af2be4..1e56ee5dcb63 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -12277,7 +12277,7 @@ riscv_emit_frm_mode_set (int mode, int prev_mode)
          && prev_mode != riscv_vector::FRM_DYN
          && prev_mode != riscv_vector::FRM_DYN_CALL)
       /* Restore frm value when switch to DYN mode.  */
-      || (mode == riscv_vector::FRM_DYN
+      || (STATIC_FRM_P (cfun) && mode == riscv_vector::FRM_DYN
          && prev_mode != riscv_vector::FRM_DYN_CALL);
 
   if (restore_p)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr119164.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/pr119164.c
new file mode 100644
index 000000000000..a39a7f177f05
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr119164.c
@@ -0,0 +1,22 @@
+/* Reduced from SPEC2017 blender: node_texture_util.c.
+   The conditional function call was tripping mode switching state machine */
+
+/* { dg-do compile } */
+/* { dg-options " -Ofast -march=rv64gcv_zvl256b -ftree-vectorize 
-mrvv-vector-bits=zvl" } */
+
+void *a;
+float *b;
+short c;
+void d();
+void e() {
+  if (a)
+    d();
+  if (c) {
+    b[0] = b[0] * 0.5f + 0.5f;
+    b[1] = b[1] * 0.5f + 0.5f;
+  }
+}
+
+/* { dg-final { scan-assembler-not {frrm\s+[axs][0-9]+} } } */
+/* { dg-final { scan-assembler-not {fsrmi\s+[01234]} } } */
+/* { dg-final { scan-assembler-not {fsrm\s+[axs][0-9]+} } } */
-- 
2.43.0

Reply via email to