[llvm] 1b32574 - [X86][GISel] lower GOT-relative G_GLOBAL_VALUEs (#181983)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 23 05:34:52 PDT 2026
Author: Rose Hudson
Date: 2026-04-23T13:34:47+01:00
New Revision: 1b325745f13471bdb11ba32cd5dece51dcf299ac
URL: https://github.com/llvm/llvm-project/commit/1b325745f13471bdb11ba32cd5dece51dcf299ac
DIFF: https://github.com/llvm/llvm-project/commit/1b325745f13471bdb11ba32cd5dece51dcf299ac.diff
LOG: [X86][GISel] lower GOT-relative G_GLOBAL_VALUEs (#181983)
During selection if we see a GOT-relative G_GLOBAL_VALUE, don't try to
fold it into an X86AddressMode (like we would with other modes of
accessing globals) because it needs a load from the GOT. Then select mov
for the G_GLOBAL_VALUE to do that load.
Added:
Modified:
llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
llvm/test/CodeGen/X86/GlobalISel/GV.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
index 19cbb307529d7..985a9eb30b5f5 100644
--- a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
+++ b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
@@ -633,12 +633,18 @@ static bool X86SelectAddress(MachineInstr &I, const X86TargetMachine &TM,
// Can't handle alternate code models yet.
if (TM.getCodeModel() != CodeModel::Small)
return false;
- AM.GV = GV;
- AM.GVOpFlags = STI.classifyGlobalReference(GV);
- // TODO: The ABI requires an extra load. not supported yet.
- if (isGlobalStubReference(AM.GVOpFlags))
- return false;
+ unsigned int GVOpFlags = STI.classifyGlobalReference(GV);
+
+ // If it's a stub, we need to do a load to find the real address, and we
+ // can't fold that into just an AM. The load will come from lowering this
+ // G_GLOBAL_VALUE later.
+ if (isGlobalStubReference(GVOpFlags))
+ break;
+
+ // If it's not a stub, point AM directly at the global.
+ AM.GV = GV;
+ AM.GVOpFlags = GVOpFlags;
// TODO: This reference is relative to the pic base. not supported yet.
if (isGlobalRelativeToPICBase(AM.GVOpFlags))
@@ -773,12 +779,27 @@ bool X86InstructionSelector::selectGlobalValue(MachineInstr &I,
"unexpected instruction");
X86AddressMode AM;
- if (!X86SelectAddress(I, TM, MRI, STI, AM))
- return false;
+ unsigned NewOpc;
- const Register DefReg = I.getOperand(0).getReg();
- LLT Ty = MRI.getType(DefReg);
- unsigned NewOpc = getLeaOP(Ty, STI);
+ const GlobalValue *GV = I.getOperand(1).getGlobal();
+ const auto GVOpFlags = STI.classifyGlobalReference(GV);
+ if (isGlobalStubReference(GVOpFlags)) {
+ // If it's a stub, we need a load from the GOT instead of lea.
+ AM.GV = GV;
+ AM.GVOpFlags = GVOpFlags;
+ if (STI.isPICStyleRIPRel() || AM.GVOpFlags == X86II::MO_GOTPCREL ||
+ AM.GVOpFlags == X86II::MO_GOTPCREL_NORELAX)
+ AM.Base.Reg = X86::RIP;
+
+ NewOpc = STI.isTarget64BitLP64() ? X86::MOV64rm : X86::MOV32rm;
+ } else {
+ if (!X86SelectAddress(I, TM, MRI, STI, AM))
+ return false;
+
+ const Register DefReg = I.getOperand(0).getReg();
+ LLT Ty = MRI.getType(DefReg);
+ NewOpc = getLeaOP(Ty, STI);
+ }
I.setDesc(TII.get(NewOpc));
MachineInstrBuilder MIB(MF, I);
diff --git a/llvm/test/CodeGen/X86/GlobalISel/GV.ll b/llvm/test/CodeGen/X86/GlobalISel/GV.ll
index c161a32fd6b95..1681992ddca4d 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/GV.ll
+++ b/llvm/test/CodeGen/X86/GlobalISel/GV.ll
@@ -5,6 +5,7 @@
; RUN: llc -mtriple=x86_64-linux-gnux32 -global-isel -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=X32ABI
@g_int = dso_local global i32 0, align 4
+ at external_g_int = external global i32, align 4
; Function Attrs: noinline nounwind optnone uwtable
define dso_local ptr @test_global_ptrv() #3 {
@@ -58,3 +59,55 @@ entry:
ret i32 %0
}
+define dso_local ptr @test_external_global_ptrv() {
+; X64-LABEL: test_external_global_ptrv:
+; X64: # %bb.0: # %entry
+; X64-NEXT: movq external_g_int at GOTPCREL(%rip), %rax
+; X64-NEXT: retq
+;
+; X64_DARWIN_PIC-LABEL: test_external_global_ptrv:
+; X64_DARWIN_PIC: ## %bb.0: ## %entry
+; X64_DARWIN_PIC-NEXT: movq _external_g_int at GOTPCREL(%rip), %rax
+; X64_DARWIN_PIC-NEXT: retq
+;
+; X32-LABEL: test_external_global_ptrv:
+; X32: # %bb.0: # %entry
+; X32-NEXT: leal external_g_int, %eax
+; X32-NEXT: retl
+;
+; X32ABI-LABEL: test_external_global_ptrv:
+; X32ABI: # %bb.0: # %entry
+; X32ABI-NEXT: movl external_g_int at GOTPCREL(%rip), %eax
+; X32ABI-NEXT: movl %eax, %eax
+; X32ABI-NEXT: retq
+entry:
+ ret ptr @external_g_int
+}
+
+define dso_local i32 @test_external_global_valv() {
+; X64-LABEL: test_external_global_valv:
+; X64: # %bb.0: # %entry
+; X64-NEXT: movq external_g_int at GOTPCREL(%rip), %rax
+; X64-NEXT: movl (%rax), %eax
+; X64-NEXT: retq
+;
+; X64_DARWIN_PIC-LABEL: test_external_global_valv:
+; X64_DARWIN_PIC: ## %bb.0: ## %entry
+; X64_DARWIN_PIC-NEXT: movq _external_g_int at GOTPCREL(%rip), %rax
+; X64_DARWIN_PIC-NEXT: movl (%rax), %eax
+; X64_DARWIN_PIC-NEXT: retq
+;
+; X32-LABEL: test_external_global_valv:
+; X32: # %bb.0: # %entry
+; X32-NEXT: movl external_g_int, %eax
+; X32-NEXT: retl
+;
+; X32ABI-LABEL: test_external_global_valv:
+; X32ABI: # %bb.0: # %entry
+; X32ABI-NEXT: movl external_g_int at GOTPCREL(%rip), %eax
+; X32ABI-NEXT: movl (%eax), %eax
+; X32ABI-NEXT: retq
+entry:
+ %0 = load i32, ptr @external_g_int, align 4
+ ret i32 %0
+}
More information about the llvm-commits
mailing list