https://gcc.gnu.org/bugzilla/show_bug.cgi?id=74563
--- Comment #8 from Jeffrey A. Law <law at redhat dot com> --- So AFAICT this pattern: (define_insn "*<optab>" [(any_return)] "" { operands[0] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); return mips_output_jump (operands, 0, -1, false); } [(set_attr "type" "jump") (set_attr "mode" "none")]) Is used for shrink-wrapping -- in particular it may be used while the return pointer is still sitting in $31. The _internal pattern: (define_insn "<optab>_internal" [(any_return) (use (match_operand 0 "pmode_register_operand" ""))] "" { operands[0] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); return mips_output_jump (operands, 0, -1, false); } [(set_attr "type" "jump") (set_attr "mode" "none")]) Is used directly by mips.c which should be passing in the right RETURN_ADDR_REGNUM. So like you, I think the solution is to just remove the offending line. I'm going to spin one more test. But I think we're converging on the solution.