https://gcc.gnu.org/bugzilla/show_bug.cgi?id=74563
Jeffrey A. Law <law at redhat dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2017-04-14 Ever confirmed|0 |1 --- Comment #5 from Jeffrey A. Law <law at redhat dot com> --- So what's happening here is the compact-branch support broke mips16. It's pretty obvious if we look at mips.md: (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")]) ;; Normal return. (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")]) Where RETURN_ADDR_REGNUM is always 31, even on mips16. So no matter what if we generate any of the return insns matching those patterns we'll emit a jr $31. I'm not familiar with this aspect of the MIPS port (it's 15+ years since I've done any serious MIPS work), but ISTM that at least for the _internal version we shouldn't be overwriting operands[0] -- whatever generates that pattern should be passing us the right register. For return and simple_return, we might need to conditionalize the assignment to operands[0] since the return register is not provided.