On Tue, Jul 7, 2026 at 5:44 AM H.J. Lu <[email protected]> wrote: > > Implement TARGET_FNTYPE_ABI to avoid spills of callee-saved registers > when calling functions with no_caller_saved_registers attribute. > > After > > commit 754c6600fe058f1026098fde57860bbc38cc28fe > Author: Richard Sandiford <[email protected]> > Date: Wed Jun 3 13:11:17 2026 +0100 > > Add CALL_INSN_ABI_ID > > there is no need for ix86_expand_call to add clobbers for when one ABI > calls another ABI. > > ABI_ALTERNATE is the alternate function ABI from the system ABI. If > ix86_abi is SYSV_ABI, ABI_ALTERNATE is the function ABI for MS_ABI. > Otherwise, ABI_ALTERNATE is the function ABI for SYSV_ABI. > > This target hook also properly marks the implicit __tls_get_addr call: > > (call_insn/u 9 8 10 (parallel [ > (set (reg:DI 0 ax) > (call:DI (mem:QI (symbol_ref:DI ("__tls_get_addr")) [0 S1 > A8]) > (const_int 0 [0]))) > (unspec:DI [ > (reg/f:DI 7 sp) > ] UNSPEC_TLS_LD_BASE) > (clobber (reg:DI 5 di)) > ]) "x.c":7:16 -1 > (expr_list:REG_EH_REGION (const_int -2147483648 [0xffffffff80000000]) > (nil)) > (nil) 0) > > with ABI_DEFAULT function ABI. > > Tested on Linux/x86-64 and with CPython 3.14.4. > > gcc/ > > PR target/124798 > PR target/125436 > * config/i386/i386-expand.cc: Include "function-abi.h". > (x86_64_ms_sysv_extra_clobbered_registers): Removed. > (ix86_expand_call): Don't add explicit call and ABI-switch > clobbers. > * config/i386/i386-features.cc (ix86_place_single_tls_call): > Set CALL_INSN_ABI_ID on TLS calls. > * config/i386/i386-options.cc (ix86_set_current_function): Don't > call reinit_regs. > * config/i386/i386-protos.h > (ix86_type_no_callee_saved_registers_p): Removed. > (ix86_tls_get_addr_abi): New. > * config/i386/i386.cc (ix86_alternate_abi): New prototype. > (ix86_conditional_register_usage): Changed to describe the > system ABI. > (ix86_type_no_callee_saved_registers_p): Make it static. > (ix86_function_value_regno_p): Replace ix86_cfun_abi () with > ix86_abi. > (ix86_save_reg): Only check TYPE_NO_CALLEE_SAVED_REGISTERS as > a special case. > (ix86_tls_get_addr_abi): New. > (legitimize_tls_address): Set CALL_INSN_ABI_ID on TLS calls. > Call ix86_alternate_abi to initialize the alternate function ABI. > (ix86_initialize_abi): New function. > (ix86_no_callee_saved_abi): Likewise. > (ix86_no_caller_saved_abi): Likewise. > (ix86_standard_abi): Likewise. > (ix86_alternate_abi): Likewise. > (ix86_function_abi_id): Likewise. > (ix86_fntype_abi): Likewise. > (ix86_hard_regno_call_part_clobbered): Handle newly added ABIs. > (TARGET_FNTYPE_ABI): New. > * config/i386/i386.md: Add ABI_ALTERNATE, ABI_NO_CALLEE_SAVED, > ABI_NO_CALLER_SAVED_RETURN_VOID, ABI_NO_CALLER_SAVED_RETURN_AX, > ABI_NO_CALLER_SAVED_RETURN_AX_DX, > ABI_NO_CALLER_SAVED_RETURN_AX_XMM0, > ABI_NO_CALLER_SAVED_RETURN_XMM0 and > ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1. > > gcc/testsuite/ > > PR target/124798 > PR target/125436 > * gcc.target/i386/abi-mix-1.c: New test. > * gcc.target/i386/abi-mix-2.c: Likewise. > * gcc.target/i386/no-callee-saved-20.c: Likewise. > * gcc.target/i386/no-caller-saved-1-ms.c: Likewise. > * gcc.target/i386/no-caller-saved-1-sysv.c: Likewise. > * gcc.target/i386/no-caller-saved-1.c: Likewise. > * gcc.target/i386/no-caller-saved-2.c: Likewise. > * gcc.target/i386/no-caller-saved-3.c: Likewise. > * gcc.target/i386/no-caller-saved-4.c: Likewise. > * gcc.target/i386/no-caller-saved-5.c: Likewise. > * gcc.target/i386/no-caller-saved-6.c: Likewise. > * gcc.target/i386/no-caller-saved-7.c: Likewise. > * gcc.target/i386/no-caller-saved-8.c: Likewise. > * gcc.target/i386/no-caller-saved-9.c: Likewise. > * gcc.target/i386/no-caller-saved-10.c: Likewise. > * gcc.target/i386/no-caller-saved-11.c: Likewise. > * gcc.target/i386/pr125436-1a.c: Likewise. > * gcc.target/i386/pr125436-1b.c: Likewise. > * gcc.target/i386/pr125436-2a.c: Likewise. > * gcc.target/i386/pr125436-2b.c: Likewise. > * gcc.target/i386/pr125436-3.c: Likewise. > * gcc.target/i386/pr125436-4.c: Likewise. > * gcc.target/i386/pr119784b.c: Adjusted for unused RBP. > * gcc.target/i386/no-callee-saved-18.c: Don't check frame > register. > * gcc.target/i386/no-callee-saved-19b.c: Update the expected > instruction order. > * gcc.target/i386/no-callee-saved-19d.c: Likewise. > * gcc.target/i386/no-callee-saved-19e.c: Likewise. > * gcc.target/i386/no-callee-saved-2.c: Check frame register isn't > saved nor restored in 64-bit mode. > * gcc.target/i386/no-callee-saved-8.c: Expect no saving nor > restoring caller-saved registers. > * gcc.target/i386/no-callee-saved-9.c: Likewise. > * gcc.target/i386/preserve-none-14.c: Don't check frame register. > * gcc.target/i386/preserve-none-23.c: Likewise. > * gcc.target/i386/preserve-none-7.c: Check frame register isn't > saved nor restored in 64-bit mode. > > Signed-off-by: H.J. Lu <[email protected]> > Co-Authored by: Richard Sandiford <[email protected]> > > Signed-off-by: H.J. Lu <[email protected]>
On Tue, Jul 7, 2026 at 5:44 AM H.J. Lu <[email protected]> wrote: > > Implement TARGET_FNTYPE_ABI to avoid spills of callee-saved registers > when calling functions with no_caller_saved_registers attribute. > > After > > commit 754c6600fe058f1026098fde57860bbc38cc28fe > Author: Richard Sandiford <[email protected]> > Date: Wed Jun 3 13:11:17 2026 +0100 > > Add CALL_INSN_ABI_ID > > there is no need for ix86_expand_call to add clobbers for when one ABI > calls another ABI. > > ABI_ALTERNATE is the alternate function ABI from the system ABI. If > ix86_abi is SYSV_ABI, ABI_ALTERNATE is the function ABI for MS_ABI. > Otherwise, ABI_ALTERNATE is the function ABI for SYSV_ABI. > > This target hook also properly marks the implicit __tls_get_addr call: > > (call_insn/u 9 8 10 (parallel [ > (set (reg:DI 0 ax) > (call:DI (mem:QI (symbol_ref:DI ("__tls_get_addr")) [0 S1 > A8]) > (const_int 0 [0]))) > (unspec:DI [ > (reg/f:DI 7 sp) > ] UNSPEC_TLS_LD_BASE) > (clobber (reg:DI 5 di)) > ]) "x.c":7:16 -1 > (expr_list:REG_EH_REGION (const_int -2147483648 [0xffffffff80000000]) > (nil)) > (nil) 0) > > with ABI_DEFAULT function ABI. > > Tested on Linux/x86-64 and with CPython 3.14.4. > > gcc/ > > PR target/124798 > PR target/125436 > * config/i386/i386-expand.cc: Include "function-abi.h". > (x86_64_ms_sysv_extra_clobbered_registers): Removed. > (ix86_expand_call): Don't add explicit call and ABI-switch > clobbers. > * config/i386/i386-features.cc (ix86_place_single_tls_call): > Set CALL_INSN_ABI_ID on TLS calls. > * config/i386/i386-options.cc (ix86_set_current_function): Don't > call reinit_regs. > * config/i386/i386-protos.h > (ix86_type_no_callee_saved_registers_p): Removed. > (ix86_tls_get_addr_abi): New. > * config/i386/i386.cc (ix86_alternate_abi): New prototype. > (ix86_conditional_register_usage): Changed to describe the > system ABI. > (ix86_type_no_callee_saved_registers_p): Make it static. > (ix86_function_value_regno_p): Replace ix86_cfun_abi () with > ix86_abi. > (ix86_save_reg): Only check TYPE_NO_CALLEE_SAVED_REGISTERS as > a special case. > (ix86_tls_get_addr_abi): New. > (legitimize_tls_address): Set CALL_INSN_ABI_ID on TLS calls. > Call ix86_alternate_abi to initialize the alternate function ABI. > (ix86_initialize_abi): New function. > (ix86_no_callee_saved_abi): Likewise. > (ix86_no_caller_saved_abi): Likewise. > (ix86_standard_abi): Likewise. > (ix86_alternate_abi): Likewise. > (ix86_function_abi_id): Likewise. > (ix86_fntype_abi): Likewise. > (ix86_hard_regno_call_part_clobbered): Handle newly added ABIs. > (TARGET_FNTYPE_ABI): New. > * config/i386/i386.md: Add ABI_ALTERNATE, ABI_NO_CALLEE_SAVED, > ABI_NO_CALLER_SAVED_RETURN_VOID, ABI_NO_CALLER_SAVED_RETURN_AX, > ABI_NO_CALLER_SAVED_RETURN_AX_DX, > ABI_NO_CALLER_SAVED_RETURN_AX_XMM0, > ABI_NO_CALLER_SAVED_RETURN_XMM0 and > ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1. > > gcc/testsuite/ > > PR target/124798 > PR target/125436 > * gcc.target/i386/abi-mix-1.c: New test. > * gcc.target/i386/abi-mix-2.c: Likewise. > * gcc.target/i386/no-callee-saved-20.c: Likewise. > * gcc.target/i386/no-caller-saved-1-ms.c: Likewise. > * gcc.target/i386/no-caller-saved-1-sysv.c: Likewise. > * gcc.target/i386/no-caller-saved-1.c: Likewise. > * gcc.target/i386/no-caller-saved-2.c: Likewise. > * gcc.target/i386/no-caller-saved-3.c: Likewise. > * gcc.target/i386/no-caller-saved-4.c: Likewise. > * gcc.target/i386/no-caller-saved-5.c: Likewise. > * gcc.target/i386/no-caller-saved-6.c: Likewise. > * gcc.target/i386/no-caller-saved-7.c: Likewise. > * gcc.target/i386/no-caller-saved-8.c: Likewise. > * gcc.target/i386/no-caller-saved-9.c: Likewise. > * gcc.target/i386/no-caller-saved-10.c: Likewise. > * gcc.target/i386/no-caller-saved-11.c: Likewise. > * gcc.target/i386/pr125436-1a.c: Likewise. > * gcc.target/i386/pr125436-1b.c: Likewise. > * gcc.target/i386/pr125436-2a.c: Likewise. > * gcc.target/i386/pr125436-2b.c: Likewise. > * gcc.target/i386/pr125436-3.c: Likewise. > * gcc.target/i386/pr125436-4.c: Likewise. > * gcc.target/i386/pr119784b.c: Adjusted for unused RBP. > * gcc.target/i386/no-callee-saved-18.c: Don't check frame > register. > * gcc.target/i386/no-callee-saved-19b.c: Update the expected > instruction order. > * gcc.target/i386/no-callee-saved-19d.c: Likewise. > * gcc.target/i386/no-callee-saved-19e.c: Likewise. > * gcc.target/i386/no-callee-saved-2.c: Check frame register isn't > saved nor restored in 64-bit mode. > * gcc.target/i386/no-callee-saved-8.c: Expect no saving nor > restoring caller-saved registers. > * gcc.target/i386/no-callee-saved-9.c: Likewise. > * gcc.target/i386/preserve-none-14.c: Don't check frame register. > * gcc.target/i386/preserve-none-23.c: Likewise. > * gcc.target/i386/preserve-none-7.c: Check frame register isn't > saved nor restored in 64-bit mode. > > Signed-off-by: H.J. Lu <[email protected]> > Co-Authored by: Richard Sandiford <[email protected]> > > Signed-off-by: H.J. Lu <[email protected]> gcc/config/i386/i386-features.cc:4353, should we also use ix86_tls_get_addr_abi().clobbers_full_reg_p(i) instead of default_function_abi.clobbers_full_reg_p (i)? 4349 /* Get all live caller-saved registers for TLS_GD and TLS_LD_BASE 4350 instructions. */ 4351 if (kind != X86_CSE_TLSDESC) 4352 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 4353 if (default_function_abi.clobbers_full_reg_p (i) 4354 && !fixed_regs[i] 4355 && bitmap_bit_p (in, i)) 4356 bitmap_set_bit (live_caller_saved_regs, i); Other LGTM.
