https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121498
--- Comment #9 from liu mirko <lw297073896 at gmail dot com> --- (In reply to Jeffrey A. Law from comment #7) > Note that GCC considers RA a fixed register because of its hidden uses. RA > is not available to the regsiter allocator. There is special code to > save/restore RA if the function is not a leaf function OR if the function is > large enough to potentially need long branch/call sequences. > > If RA is not being saved in a function that has long branches/calls, then > that's a bug and I'd love to have a compilable testcase to investigate why. I used GDB to debug the GCC code and found that in the following function: ``` bool requires_stack_frame_p (rtx_insn *insn, HARD_REG_SET prologue_used, HARD_REG_SET set_up_by_prologue) { df_ref def, use; HARD_REG_SET hardregs; unsigned regno; if (CALL_P (insn) && !FAKE_CALL_P (insn)) return !SIBLING_CALL_P (insn); /* We need a frame to get the unique CFA expected by the unwinder. */ if (cfun->can_throw_non_call_exceptions && can_throw_internal (insn)) return true; CLEAR_HARD_REG_SET (hardregs); FOR_EACH_INSN_DEF (def, insn) { rtx dreg = DF_REF_REG (def); if (!REG_P (dreg)) continue; add_to_hard_reg_set (&hardregs, GET_MODE (dreg), REGNO (dreg)); } if (hard_reg_set_intersect_p (hardregs, prologue_used)) return true; hardregs &= ~crtl->abi->full_reg_clobbers (); for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (TEST_HARD_REG_BIT (hardregs, regno) && df_regs_ever_live_p (regno)) return true; FOR_EACH_INSN_USE (use, insn) { rtx reg = DF_REF_REG (use); if (!REG_P (reg)) continue; add_to_hard_reg_set (&hardregs, GET_MODE (reg), REGNO (reg)); } if (hard_reg_set_intersect_p (hardregs, set_up_by_prologue)) return true; return false; } ``` there was no judgment made for the following branch which 'get_attr_length (insn) == 12' ``` (define_insn "*branch<mode>" [(set (pc) (if_then_else (match_operator 1 "ordered_comparison_operator" [(match_operand:X 2 "register_operand" "r") (match_operand:X 3 "reg_or_0_operand" "rJ")]) (label_ref (match_operand 0 "" "")) (pc)))] "!TARGET_XCVBI" { if (get_attr_length (insn) == 12) return "b%r1\t%2,%z3,1f; jump\t%l0,ra; 1:"; return "b%C1\t%2,%z3,%l0"; } [(set_attr "type" "branch") (set_attr "mode" "none")]) ```