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")])
```

Reply via email to