https://gcc.gnu.org/g:3c0f3b74bf6011b12fe12821ba6e1079309d9445
commit r16-1290-g3c0f3b74bf6011b12fe12821ba6e1079309d9445 Author: Vineet Gupta <vine...@rivosinc.com> Date: Sun Jun 8 14:55:01 2025 -0700 RISC-V: frm/mode-switch: Reduce FRM restores on DYN transition [PR119164] 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> Diff: --- gcc/config/riscv/riscv.cc | 2 +- gcc/testsuite/gcc.target/riscv/rvv/base/pr119164.c | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) 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]+} } } */