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 <[email protected]>
---
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