https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123626
--- Comment #3 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Jeff Law <[email protected]>: https://gcc.gnu.org/g:6b79f1a5b8b62ce711d590a7f3e6ecb40b465464 commit r16-6939-g6b79f1a5b8b62ce711d590a7f3e6ecb40b465464 Author: Jeff Law <[email protected]> Date: Tue Jan 20 13:57:10 2026 -0700 [RISC-V][PR target/123626] Fix VXRM state after calls This is a partial fix for a long standing issue that Richard S. raised about a year ago. Specifically he indicated that he believed our handling of VXRM mode switching was wrong and could lead to incorrect code, particularly WRT handling of calls. Without rehashing everything related to VXRM, its sufficient to say that it has no known value at function entry or upon returning from a call. If we look at the main scan loop in mode-switching we have: > FOR_BB_INSNS (bb, insn) > { > if (NONDEBUG_INSN_P (insn)) > { > int mode = targetm.mode_switching.needed (e, insn, live_now); > rtx link; > > if (mode != no_mode && mode != last_mode) > { > ptr = new_seginfo (last_mode, mode, insn, live_now); > add_seginfo (&tail_ptr, ptr); > bitmap_clear_bit (transp_all, bb->index); > any_set_required = true; > last_mode = mode; > } The way to think about this is if INSN requests a mode and it is not the same as the last mode, then we've got a new point where we need to logically insert a mode switch and we clear TRANSP. A CALL_INSN in the RISC-V backend produces NO_MODE (it doesn't need VXRM state). So we never get into the then clause of that inner if statement and TRANSP stays on. The fix is quite simple. We need one more state in the VXRM mode switching that indicates we don't know VXRM's state after a call. While I could have hacked up the various hooks to special case CALLs, it was just as easy to adjust the attribute's generic handling so that any CALL_P is given the VXRM_MODE_CLOBBER state. Out of an abundance of caution if we'll filter out any actual code generation setting it to CLOBBER state. This is enough to make the testcase pass for rv64. It's still failing rv32, but likely for completely different reasons. It obviously doesn't cause any regressions on riscv{32,64}-elf and bootstraps will fire up later today on the Pioneer and BPI. PR target/123626 gcc/ * config/riscv/vector.md (vxrm_mode): Handle CALL_INSNs, which set the attribute to the new VXRM_MODE_CLOBBER state. * config/riscv/riscv.cc (riscv_emit_mode_set): Don't emit code when VXRM's state changes to VXRM_MODE_CLOBBER. gcc/testsuite * gcc.target/riscv/rvv/base/pr123626.c: New test.
