https://gcc.gnu.org/g:f5166f5badb190eec5d3707fe25ad33febf1969e

commit r16-6650-gf5166f5badb190eec5d3707fe25ad33febf1969e
Author: Alexandre Oliva <[email protected]>
Date:   Thu Jul 10 22:21:31 2025 -0300

    arm: prevent impossible tail- long-calls with static chain [PR119430]
    
    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.

Diff:
---
 gcc/config/arm/arm.cc | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index ec21fb96b668..0a1f6612d07f 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -7983,10 +7983,14 @@ arm_function_ok_for_sibcall (tree decl, tree exp)
      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;

Reply via email to