Darwin, X86: Adjust call clobbers to allow for lazy-binding [PR 100152].
authorIain Sandoe <iain@sandoe.co.uk>
Mon, 3 May 2021 07:22:53 +0000 (08:22 +0100)
committerIain Sandoe <iain@sandoe.co.uk>
Fri, 9 Jul 2021 16:41:55 +0000 (17:41 +0100)
We allow public functions defined in a TU to bind locally for PIC
code (the default) on 64bit Mach-O.

If such functions are not inlined, we cannot tell at compile-time if
they might be called via the lazy symbol resolver (this can depend on
options given at link-time).  Therefore, we must assume that the lazy
resolver could be used which clobbers R11 and R10.

Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
gcc/ChangeLog:

PR target/100152
* config/i386/i386-expand.c (ix86_expand_call): If a call is
to a non-local-binding, or local but to a public symbol, then
assume that it might be indirected via the lazy symbol binder.
Mark R10 and R10 as clobbered in that case.

gcc/config/i386/i386-expand.c

index 65764ad..69ea79e 100644 (file)
@@ -8410,6 +8410,7 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
     pop = NULL;
   gcc_assert (!TARGET_64BIT || !pop);
 
+  rtx addr = XEXP (fnaddr, 0);
   if (TARGET_MACHO && !TARGET_64BIT)
     {
 #if TARGET_MACHO
@@ -8422,7 +8423,6 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
       /* Static functions and indirect calls don't need the pic register.  Also,
         check if PLT was explicitly avoided via no-plt or "noplt" attribute, making
         it an indirect call.  */
-      rtx addr = XEXP (fnaddr, 0);
       if (flag_pic
          && GET_CODE (addr) == SYMBOL_REF
          && !SYMBOL_REF_LOCAL_P (addr))
@@ -8585,6 +8585,20 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
        }
     }
 
+  if (TARGET_MACHO && TARGET_64BIT && !sibcall
+      && ((GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (addr))
+         || !fndecl || TREE_PUBLIC (fndecl)))
+    {
+      /* We allow public functions defined in a TU to bind locally for PIC
+        code (the default) on 64bit Mach-O.
+        If such functions are not inlined, we cannot tell at compile-time if
+        they will be called via the lazy symbol resolver (this can depend on
+        options given at link-time).  Therefore, we must assume that the lazy
+        resolver could be used which clobbers R11 and R10.  */
+      clobber_reg (&use, gen_rtx_REG (DImode, R11_REG));
+      clobber_reg (&use, gen_rtx_REG (DImode, R10_REG));
+    }
+
   if (vec_len > 1)
     call = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (vec_len, vec));
   rtx_insn *call_insn = emit_call_insn (call);