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.

Reply via email to