[llvm] ad611b6 - [X86] Do not hold GOT base for indirect call or absolute address (#203192)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jun 14 22:56:06 PDT 2026
Author: Phoebe Wang
Date: 2026-06-15T05:56:02Z
New Revision: ad611b62095e55a1fa534ccbac99603ba02634a9
URL: https://github.com/llvm/llvm-project/commit/ad611b62095e55a1fa534ccbac99603ba02634a9
DIFF: https://github.com/llvm/llvm-project/commit/ad611b62095e55a1fa534ccbac99603ba02634a9.diff
LOG: [X86] Do not hold GOT base for indirect call or absolute address (#203192)
Fixes:
https://github.com/llvm/llvm-project/pull/202370#discussion_r3384983368
Assisted-by: Claude Sonnet 4.6
Added:
Modified:
llvm/lib/Target/X86/X86ISelLoweringCall.cpp
llvm/test/CodeGen/X86/abi-isel.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
index 89775eb70e038..7c068115df481 100644
--- a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
+++ b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
@@ -2392,12 +2392,13 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
if (Subtarget.isPICStyleGOT()) {
// ELF / PIC requires GOT in the EBX register before function calls via PLT
- // GOT pointer (except regcall).
+ // GOT pointer.
if (!isTailCall) {
- // Indirect call with RegCall calling convertion may use up all the
- // general registers, so it is not suitable to bind EBX reister for
- // GOT address, just let register allocator handle it.
- if (CallConv != CallingConv::X86_RegCall)
+ // Only PLT calls (GlobalAddress or ExternalSymbol) require the GOT in
+ // EBX. Indirect calls through a register or an absolute address do not
+ // go through the PLT and do not need EBX to hold the GOT base.
+ if ((Callee->getOpcode() == ISD::GlobalAddress ||
+ Callee->getOpcode() == ISD::ExternalSymbol))
RegsToPass.push_back(std::make_pair(
Register(X86::EBX), DAG.getNode(X86ISD::GlobalBaseReg, SDLoc(),
getPointerTy(DAG.getDataLayout()))));
diff --git a/llvm/test/CodeGen/X86/abi-isel.ll b/llvm/test/CodeGen/X86/abi-isel.ll
index 2ac392c729d19..d5e99e919b820 100644
--- a/llvm/test/CodeGen/X86/abi-isel.ll
+++ b/llvm/test/CodeGen/X86/abi-isel.ll
@@ -11608,20 +11608,18 @@ define dso_local void @icaller() nounwind {
;
; LINUX-32-PIC-LABEL: icaller:
; LINUX-32-PIC: # %bb.0: # %entry
-; LINUX-32-PIC-NEXT: pushl %ebx
; LINUX-32-PIC-NEXT: pushl %esi
-; LINUX-32-PIC-NEXT: pushl %eax
+; LINUX-32-PIC-NEXT: subl $8, %esp
; LINUX-32-PIC-NEXT: calll .L142$pb
; LINUX-32-PIC-NEXT: .L142$pb:
-; LINUX-32-PIC-NEXT: popl %ebx
+; LINUX-32-PIC-NEXT: popl %eax
; LINUX-32-PIC-NEXT: .Ltmp142:
-; LINUX-32-PIC-NEXT: addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp142-.L142$pb), %ebx
-; LINUX-32-PIC-NEXT: movl ifunc at GOT(%ebx), %esi
+; LINUX-32-PIC-NEXT: addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp142-.L142$pb), %eax
+; LINUX-32-PIC-NEXT: movl ifunc at GOT(%eax), %esi
; LINUX-32-PIC-NEXT: calll *(%esi)
; LINUX-32-PIC-NEXT: calll *(%esi)
-; LINUX-32-PIC-NEXT: addl $4, %esp
+; LINUX-32-PIC-NEXT: addl $8, %esp
; LINUX-32-PIC-NEXT: popl %esi
-; LINUX-32-PIC-NEXT: popl %ebx
; LINUX-32-PIC-NEXT: retl
;
; LINUX-64-PIC-LABEL: icaller:
@@ -11720,17 +11718,17 @@ define dso_local void @dicaller() nounwind {
;
; LINUX-32-PIC-LABEL: dicaller:
; LINUX-32-PIC: # %bb.0: # %entry
-; LINUX-32-PIC-NEXT: pushl %ebx
+; LINUX-32-PIC-NEXT: pushl %esi
; LINUX-32-PIC-NEXT: subl $8, %esp
; LINUX-32-PIC-NEXT: calll .L143$pb
; LINUX-32-PIC-NEXT: .L143$pb:
-; LINUX-32-PIC-NEXT: popl %ebx
+; LINUX-32-PIC-NEXT: popl %esi
; LINUX-32-PIC-NEXT: .Ltmp143:
-; LINUX-32-PIC-NEXT: addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp143-.L143$pb), %ebx
-; LINUX-32-PIC-NEXT: calll *.Ldifunc$local at GOTOFF(%ebx)
-; LINUX-32-PIC-NEXT: calll *.Ldifunc$local at GOTOFF(%ebx)
+; LINUX-32-PIC-NEXT: addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp143-.L143$pb), %esi
+; LINUX-32-PIC-NEXT: calll *.Ldifunc$local at GOTOFF(%esi)
+; LINUX-32-PIC-NEXT: calll *.Ldifunc$local at GOTOFF(%esi)
; LINUX-32-PIC-NEXT: addl $8, %esp
-; LINUX-32-PIC-NEXT: popl %ebx
+; LINUX-32-PIC-NEXT: popl %esi
; LINUX-32-PIC-NEXT: retl
;
; LINUX-64-PIC-LABEL: dicaller:
@@ -11821,17 +11819,17 @@ define dso_local void @licaller() nounwind {
;
; LINUX-32-PIC-LABEL: licaller:
; LINUX-32-PIC: # %bb.0: # %entry
-; LINUX-32-PIC-NEXT: pushl %ebx
+; LINUX-32-PIC-NEXT: pushl %esi
; LINUX-32-PIC-NEXT: subl $8, %esp
; LINUX-32-PIC-NEXT: calll .L144$pb
; LINUX-32-PIC-NEXT: .L144$pb:
-; LINUX-32-PIC-NEXT: popl %ebx
+; LINUX-32-PIC-NEXT: popl %esi
; LINUX-32-PIC-NEXT: .Ltmp144:
-; LINUX-32-PIC-NEXT: addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp144-.L144$pb), %ebx
-; LINUX-32-PIC-NEXT: calll *lifunc at GOTOFF(%ebx)
-; LINUX-32-PIC-NEXT: calll *lifunc at GOTOFF(%ebx)
+; LINUX-32-PIC-NEXT: addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp144-.L144$pb), %esi
+; LINUX-32-PIC-NEXT: calll *lifunc at GOTOFF(%esi)
+; LINUX-32-PIC-NEXT: calll *lifunc at GOTOFF(%esi)
; LINUX-32-PIC-NEXT: addl $8, %esp
-; LINUX-32-PIC-NEXT: popl %ebx
+; LINUX-32-PIC-NEXT: popl %esi
; LINUX-32-PIC-NEXT: retl
;
; LINUX-64-PIC-LABEL: licaller:
@@ -11923,20 +11921,18 @@ define dso_local void @itailcaller() nounwind {
;
; LINUX-32-PIC-LABEL: itailcaller:
; LINUX-32-PIC: # %bb.0: # %entry
-; LINUX-32-PIC-NEXT: pushl %ebx
; LINUX-32-PIC-NEXT: pushl %esi
-; LINUX-32-PIC-NEXT: pushl %eax
+; LINUX-32-PIC-NEXT: subl $8, %esp
; LINUX-32-PIC-NEXT: calll .L145$pb
; LINUX-32-PIC-NEXT: .L145$pb:
-; LINUX-32-PIC-NEXT: popl %ebx
+; LINUX-32-PIC-NEXT: popl %eax
; LINUX-32-PIC-NEXT: .Ltmp145:
-; LINUX-32-PIC-NEXT: addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp145-.L145$pb), %ebx
-; LINUX-32-PIC-NEXT: movl ifunc at GOT(%ebx), %esi
+; LINUX-32-PIC-NEXT: addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp145-.L145$pb), %eax
+; LINUX-32-PIC-NEXT: movl ifunc at GOT(%eax), %esi
; LINUX-32-PIC-NEXT: calll *(%esi)
; LINUX-32-PIC-NEXT: calll *(%esi)
-; LINUX-32-PIC-NEXT: addl $4, %esp
+; LINUX-32-PIC-NEXT: addl $8, %esp
; LINUX-32-PIC-NEXT: popl %esi
-; LINUX-32-PIC-NEXT: popl %ebx
; LINUX-32-PIC-NEXT: retl
;
; LINUX-64-PIC-LABEL: itailcaller:
@@ -12033,16 +12029,14 @@ define dso_local void @ditailcaller() nounwind {
;
; LINUX-32-PIC-LABEL: ditailcaller:
; LINUX-32-PIC: # %bb.0: # %entry
-; LINUX-32-PIC-NEXT: pushl %ebx
-; LINUX-32-PIC-NEXT: subl $8, %esp
+; LINUX-32-PIC-NEXT: subl $12, %esp
; LINUX-32-PIC-NEXT: calll .L146$pb
; LINUX-32-PIC-NEXT: .L146$pb:
-; LINUX-32-PIC-NEXT: popl %ebx
+; LINUX-32-PIC-NEXT: popl %eax
; LINUX-32-PIC-NEXT: .Ltmp146:
-; LINUX-32-PIC-NEXT: addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp146-.L146$pb), %ebx
-; LINUX-32-PIC-NEXT: calll *.Ldifunc$local at GOTOFF(%ebx)
-; LINUX-32-PIC-NEXT: addl $8, %esp
-; LINUX-32-PIC-NEXT: popl %ebx
+; LINUX-32-PIC-NEXT: addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp146-.L146$pb), %eax
+; LINUX-32-PIC-NEXT: calll *.Ldifunc$local at GOTOFF(%eax)
+; LINUX-32-PIC-NEXT: addl $12, %esp
; LINUX-32-PIC-NEXT: retl
;
; LINUX-64-PIC-LABEL: ditailcaller:
@@ -12120,16 +12114,14 @@ define dso_local void @litailcaller() nounwind {
;
; LINUX-32-PIC-LABEL: litailcaller:
; LINUX-32-PIC: # %bb.0: # %entry
-; LINUX-32-PIC-NEXT: pushl %ebx
-; LINUX-32-PIC-NEXT: subl $8, %esp
+; LINUX-32-PIC-NEXT: subl $12, %esp
; LINUX-32-PIC-NEXT: calll .L147$pb
; LINUX-32-PIC-NEXT: .L147$pb:
-; LINUX-32-PIC-NEXT: popl %ebx
+; LINUX-32-PIC-NEXT: popl %eax
; LINUX-32-PIC-NEXT: .Ltmp147:
-; LINUX-32-PIC-NEXT: addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp147-.L147$pb), %ebx
-; LINUX-32-PIC-NEXT: calll *lifunc at GOTOFF(%ebx)
-; LINUX-32-PIC-NEXT: addl $8, %esp
-; LINUX-32-PIC-NEXT: popl %ebx
+; LINUX-32-PIC-NEXT: addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp147-.L147$pb), %eax
+; LINUX-32-PIC-NEXT: calll *lifunc at GOTOFF(%eax)
+; LINUX-32-PIC-NEXT: addl $12, %esp
; LINUX-32-PIC-NEXT: retl
;
; LINUX-64-PIC-LABEL: litailcaller:
More information about the llvm-commits
mailing list