https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118646
Bug ID: 118646 Summary: RISC-V: Needed FSRM getting eliminated - SPEC2017 527.cam4 failures Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: vineetg at gcc dot gnu.org Reporter: vineetg at gcc dot gnu.org CC: jeffreyalaw at gmail dot com, juzhe.zhong at rivai dot ai, pan2.li at intel dot com, rdapp at gcc dot gnu.org Target Milestone: --- RV Vector FP-INT instructions use the Rounding mode in FRM register and depending on the insn, say VFNCVT.x.f.w it could be explicitly set to a RV-specific Round Model *RMM*(4) "Round to Nearest, ties to Max". While the psABI Calling Convention spec [1] is not explicit about FRM being a caller-saved or callee saved, gcc currently saves/restores if explicitly set (with mode_sw LCM placing it at the optimal point). However When running SPEC2017 cam4 we were hitting abort in glibc: round_away () because it found RISC-V RMM while glibc only expects standard rounding modes. Essentially due to a gcc codegen bug, RM was not being restored in some function, "leaking" out into glibc. After a lot of debugging (QEMU tracing hacks) found the culprit function setting RMM but not restoring it back. My initial suspect was obviously mode switch backend bits, but turns out it was generating save/restore, but getting eliminated by subsequent passes (sched1 DCE and late-combine) because the problem case eliminable variant gen_fsrmi_restore () was being used iso gen_fsrmi_restore_volatile () Side-note: When initially triaging the issue, I bisected this to an unrelated change dbb95f0808c3 ("RISC-V: Disable by pieces for vector setmem length > UNITS_PER_WORD"). Turns out the bisection was right and wrong. The patch changed some inline heuristics, so a nearby memset call gets elided, changing the behavior of mode switch - leading to save/restore being retained. So it was essentially masking the latent issue. [1] https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc