https://gcc.gnu.org/g:22a3dcacf2fb9e90bea2708a4a3d8a56bc873d9e
commit r17-3956-g22a3dcacf2fb9e90bea2708a4a3d8a56bc873d9e Author: Iain Sandoe <[email protected]> Date: Sun Aug 30 14:54:38 2026 +0100 X86, Darwin: Handle lazy resolver stub clobbers for no_caller_saved_registers. For Darwin versions up to darwin21, lazy symbol resolution requires use of a stub that clobbers d10 and d11 on x86_64. However, this requirement is overidden by the user specifying that a call is no_caller_saved_regs. The current mechanism (querying an attribute) is a bit unfortunate on a relatively hot path. However, testing did not show anything outside the noise level in extra compile time - perhaps reflecting that relatively few functions carry attributes. TODO: consider dropping this check for Darwin21+ where the dynamic linker has been revised to use a different approach. gcc/ChangeLog: * config/i386/i386-expand.cc (ix86_expand_call): User setting of no_caller_saved_registers overrides lazy symbol stub reservations. Signed-off-by: Iain Sandoe <[email protected]> Diff: --- gcc/config/i386/i386-expand.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index 2d250fa57b26..7fa9d7f6b8d3 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -11520,15 +11520,18 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1, } if (TARGET_MACHO && TARGET_64BIT && !sibcall - && ((SYMBOL_REF_P (addr) && !SYMBOL_REF_LOCAL_P (addr)) - || !fndecl || TREE_PUBLIC (fndecl))) + && (!fndecl || TREE_PUBLIC (fndecl) + || (SYMBOL_REF_P (addr) && !SYMBOL_REF_LOCAL_P (addr))) + && (!fndecl || !lookup_attribute ("no_caller_saved_registers", + TYPE_ATTRIBUTES (TREE_TYPE (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. */ + resolver could be used which clobbers R11 and R10. + User specification of "no caller saved regs" overides. */ clobber_reg (&use, gen_rtx_REG (DImode, R11_REG)); clobber_reg (&use, gen_rtx_REG (DImode, R10_REG)); }
