Darwin, X86: Adjust call clobbers to allow for lazy-binding [PR 100152].

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.

(cherry picked from commit 41bd1b1903)
This commit is contained in:
Iain Sandoe 2021-05-03 08:22:53 +01:00
parent cfad91385a
commit b6a762bf46
1 changed files with 15 additions and 1 deletions

View File

@ -7943,6 +7943,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
@ -7955,7 +7956,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))
@ -8118,6 +8118,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);