On Tue, Jul 7, 2026 at 1:33 PM Hongtao Liu <[email protected]> wrote:
>
> 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.

Good catch.  I changed it to

      /* Get all live caller-saved registers for TLS_GD and TLS_LD_BASE
         instructions.  */
      if (kind != X86_CSE_TLSDESC)
        {
          const predefined_function_abi &tls_abi
            = ix86_tls_get_addr_abi ();
          for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
            if (tls_abi.clobbers_full_reg_p (i)
                && !fixed_regs[i]
                && bitmap_bit_p (in, i))
              bitmap_set_bit (live_caller_saved_regs, i);
        }

in v4.

Thanks.

-- 
H.J.

Reply via email to