RV-Vector FP-INT insns use the rounding mode in FRM register which if explicitly set for V insn needs, is saved/restored (although from the psABI CC Spec, it is not clear if it actually a caller-saved or callee-saved).
Anyhow in the failure case the save/restore were generated by the Mode Switch pass, but then eliminated by sched1:DCE and Late-Combine. Fix this by using unspec_volatile variant which won't be eliminated. This showed up as SPEC2017 527.cam4 runtime aborts in glibc:round_away() which checks for standard rounding modes and the "leaking" rounding mode due to the bug happened to be a non-standard RISC-V specific RMM "Round to Nearest, ties to Max". This is testsuite clean: | | # of unexpected case / # of unique unexpected case | | gcc | g++ | gfortran | | rv64imafdcv_zvl256b_zba_zbb_zbs_zicond/ lp64d/ medlow | 393 / 107 | 12 / 4 | 7 / 2 | | rv64imafdcv_zvl256b_zba_zbb_zbs_zicond/ lp64d/ medlow | 393 / 107 | 12 / 4 | 7 / 2 | PR target/118646 PR target/118103 gcc/ChangeLog: * config/riscv/riscv.cc (riscv_emit_frm_mode_set): Use volatile fsrmi restore. gcc/testsuite/ChangeLog: * gfortran.target/riscv/rvv/pr118646.f90 (New Test). Signed-off-by: Vineet Gupta <vine...@rivosinc.com> --- gcc/config/riscv/riscv.cc | 2 +- .../gfortran.target/riscv/rvv/pr118646.f90 | 44 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gfortran.target/riscv/rvv/pr118646.f90 diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 5a3a05041773..e8eb602ef5bc 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -12045,7 +12045,7 @@ riscv_emit_frm_mode_set (int mode, int prev_mode) else if (mode == riscv_vector::FRM_DYN && prev_mode != riscv_vector::FRM_DYN_CALL) /* Restore frm value from backup when switch to DYN mode. */ - emit_insn (gen_fsrmsi_restore (backup_reg)); + emit_insn (gen_fsrmsi_restore_volatile (backup_reg)); else if (riscv_static_frm_mode_p (mode)) /* Set frm value when switch to static mode. */ emit_insn (gen_fsrmsi_restore (frm)); diff --git a/gcc/testsuite/gfortran.target/riscv/rvv/pr118646.f90 b/gcc/testsuite/gfortran.target/riscv/rvv/pr118646.f90 new file mode 100644 index 000000000000..e63800e86269 --- /dev/null +++ b/gcc/testsuite/gfortran.target/riscv/rvv/pr118646.f90 @@ -0,0 +1,44 @@ +! Reduced from SPEC2017 527.cam4 zm_conv.F90 + +! { dg-do run } +! { dg-options "-march=rv64gcv_zvl256b_zba_zbb_zbs_zicond -ftree-vectorize -mabi=lp64d -Ofast " } + +module a + contains +subroutine b(f) + + real d(4) + integer e(4) + integer f(4) + real hmax(4) + real g(4) + + integer h(4) + integer l(4,5) + do i = 1,c + h(i) = 0 + end do + do k = j ,1 + do i = 1,c + q = g(i) + hmax(i) + if (k >= nint(d(i)) .and. k <= e(i) .and. q > 1.e4) then + f(i) = k + end if + if (k < o ) then + if (buoy<= 0.) then + l(i,h) = k + end if + end if + end do + end do + do n = 1,5 + do k = 1,m + do i = 1,c + if (k > l(i,n)) then + p = r() + end if + end do + end do + end do +end +end -- 2.43.0