When a function call uses up all argument registers, and needs IP for
the static chain, there aren't any call-clobbered registers left for
reload to assign as the sibcall target, when -mlong-calls is enabled.
Use the same logic that does the job for indirect calls to prevent
tail calls in this case.
With this change, it is possible to bootstrap armv7a-linux-gnu with
both -O3 and lto, but only with both -mlong-calls and
-ffunction-sections.
Without -mlong-calls, linker veneer thunks may clobber the static
chain register set up by callers in one lto unit, preventing them from
reaching the callee in a separate lto unit. -ffunction-sections is
required for -mlong-calls to be effective, because both caller and
callee are in the same section, and that disables long-calls when
!flag_reorder_blocks_and_partition.
gcc/ChangeLog
PR target/119430
* config/arm/arm.cc (arm_function_ok_for_sibcall): Disable
sibcalls for long-calls that use all call-clobbered
general-purpose registers, including the static chain.
address. But we only have r0-r3 and ip in that class. If r0-r3 all hold
function arguments, then we can only use IP. But IP may be needed in the
epilogue (for PAC validation), or for passing the static chain. We have
- to disable the tail call if nothing is available. */
- if (!decl
- && ((CALL_EXPR_BY_DESCRIPTOR (exp) && !flag_trampolines)
- || arm_current_function_pac_enabled_p()))
+ to disable the tail call if nothing is available. Long-calls are
+ effectively handled as indirect calls, so handle that as well. */
+ if ((!decl
+ && ((CALL_EXPR_BY_DESCRIPTOR (exp) && !flag_trampolines)
+ || arm_current_function_pac_enabled_p ()))
+ || (decl && arm_is_long_call_p (decl)
+ && (CALL_EXPR_STATIC_CHAIN (exp)
+ || arm_current_function_pac_enabled_p ())))
{
tree fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp)));
CUMULATIVE_ARGS cum;