===================================================================
@@ -17568,11 +17568,27 @@ thumb_force_lr_save (void)
|| df_regs_ever_live_p (LR_REGNUM));
}
+/* We do not know if r3 will be available because
+ we do have an indirect tailcall happening in this
+ particular case. */
+static bool
+is_indirect_tailcall_p (rtx call)
+{
+ rtx pat = PATTERN (call);
+
+ /* Indirect tail call. */
+ pat = XVECEXP (pat, 0, 0);
+ if (GET_CODE (pat) == SET)
+ pat = SET_SRC (pat);
+
+ pat = XEXP (XEXP (pat, 0), 0);
+ return REG_P (pat);
+}
/* Return true if r3 is used by any of the tail call insns in the
current function. */
static bool
-any_sibcall_uses_r3 (void)
+any_sibcall_could_use_r3 (void)
{
edge_iterator ei;
edge e;
@@ -17586,7 +17602,8 @@ any_sibcall_uses_r3 (void)
if (!CALL_P (call))
call = prev_nonnote_nondebug_insn (call);
gcc_assert (CALL_P (call) && SIBLING_CALL_P (call));
- if (find_regno_fusage (call, USE, 3))
+ if (find_regno_fusage (call, USE, 3)
+ || is_indirect_tailcall_p (call))
return true;
}
return false;
@@ -17753,7 +17770,7 @@ arm_get_frame_offsets (void)
/* If it is safe to use r3, then do so. This sometimes
generates better code on Thumb-2 by avoiding the need to
use 32-bit push/pop instructions. */
- if (! any_sibcall_uses_r3 ()
+ if (! any_sibcall_could_use_r3 ()
&& arm_size_return_regs () <= 12
&& (offsets->saved_regs_mask & (1 << 3)) == 0
&& (TARGET_THUMB2 || !current_tune->prefer_ldrd_strd))