[llvm] a56b877 - [NewPM] Port x86-global-base-reg (#180119)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 9 22:54:46 PST 2026
Author: Kyungtak Woo
Date: 2026-02-09T22:54:41-08:00
New Revision: a56b877056ab5ad9e599d86d48c3189350e5b2a2
URL: https://github.com/llvm/llvm-project/commit/a56b877056ab5ad9e599d86d48c3189350e5b2a2
DIFF: https://github.com/llvm/llvm-project/commit/a56b877056ab5ad9e599d86d48c3189350e5b2a2.diff
LOG: [NewPM] Port x86-global-base-reg (#180119)
Had to move X86GlobalBaseRegPass to its own file like in
https://github.com/llvm/llvm-project/pull/179864
No test coverage added for now as there are no MIR->MIR tests exercising
this pass and we do not have enough ported to run any end to end tests.
This is a redo of https://github.com/llvm/llvm-project/pull/180070
Added:
llvm/lib/Target/X86/X86GlobalBaseReg.cpp
Modified:
llvm/lib/Target/X86/CMakeLists.txt
llvm/lib/Target/X86/X86.h
llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
llvm/lib/Target/X86/X86InstrInfo.cpp
llvm/lib/Target/X86/X86PassRegistry.def
llvm/lib/Target/X86/X86TargetMachine.cpp
llvm/test/CodeGen/X86/llc-pipeline-npm.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/CMakeLists.txt b/llvm/lib/Target/X86/CMakeLists.txt
index 5cffe98e8dc81..086dd6963286d 100644
--- a/llvm/lib/Target/X86/CMakeLists.txt
+++ b/llvm/lib/Target/X86/CMakeLists.txt
@@ -35,6 +35,7 @@ set(sources
X86CmovConversion.cpp
X86CodeGenPassBuilder.cpp
X86DomainReassignment.cpp
+ X86GlobalBaseReg.cpp
X86LowerTileCopy.cpp
X86LowerAMXType.cpp
X86LowerAMXIntrinsics.cpp
diff --git a/llvm/lib/Target/X86/X86.h b/llvm/lib/Target/X86/X86.h
index 8f2a852faef28..6e81d9a748e22 100644
--- a/llvm/lib/Target/X86/X86.h
+++ b/llvm/lib/Target/X86/X86.h
@@ -35,7 +35,13 @@ class X86TargetMachine;
FunctionPass *createX86ISelDag(X86TargetMachine &TM, CodeGenOptLevel OptLevel);
/// This pass initializes a global base register for PIC on x86-32.
-FunctionPass *createX86GlobalBaseRegPass();
+class X86GlobalBaseRegPass : public PassInfoMixin<X86GlobalBaseRegPass> {
+public:
+ PreservedAnalyses run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM);
+};
+
+FunctionPass *createX86GlobalBaseRegLegacyPass();
/// This pass combines multiple accesses to local-dynamic TLS variables so that
/// the TLS base address for the module is only fetched once per execution path
diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
index 9405761fb6714..53171564ce1ad 100644
--- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
@@ -108,8 +108,7 @@ Error X86CodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
addMachineFunctionPass(X86CleanupLocalDynamicTLSPass(), PMW);
}
- // TODO(boomanaiden154): Add X86GlobalPassRegPass here once it has been
- // ported.
+ addMachineFunctionPass(X86GlobalBaseRegPass(), PMW);
addMachineFunctionPass(X86ArgumentStackSlotPass(), PMW);
return Error::success();
}
diff --git a/llvm/lib/Target/X86/X86GlobalBaseReg.cpp b/llvm/lib/Target/X86/X86GlobalBaseReg.cpp
new file mode 100644
index 0000000000000..f758e785e5231
--- /dev/null
+++ b/llvm/lib/Target/X86/X86GlobalBaseReg.cpp
@@ -0,0 +1,145 @@
+//===- X86GlobalBaseReg.cpp - PIC Global Base Register Initialization -----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the pass that initializes the PIC global base register
+// for x86-32.
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86.h"
+#include "X86InstrInfo.h"
+#include "X86MachineFunctionInfo.h"
+#include "X86Subtarget.h"
+#include "X86TargetMachine.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/InitializePasses.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "x86-global-base-reg"
+
+namespace {
+class X86GlobalBaseRegLegacy : public MachineFunctionPass {
+public:
+ static char ID;
+ X86GlobalBaseRegLegacy() : MachineFunctionPass(ID) {}
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+ StringRef getPassName() const override {
+ return "X86 PIC Global Base Reg Initialization";
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesCFG();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+};
+} // end anonymous namespace
+
+char X86GlobalBaseRegLegacy::ID = 0;
+
+FunctionPass *llvm::createX86GlobalBaseRegLegacyPass() {
+ return new X86GlobalBaseRegLegacy();
+}
+
+static bool initGlobalBaseReg(MachineFunction &MF) {
+ const X86TargetMachine *TM =
+ static_cast<const X86TargetMachine *>(&MF.getTarget());
+ const X86Subtarget &STI = MF.getSubtarget<X86Subtarget>();
+
+ // Only emit a global base reg in PIC mode.
+ if (!TM->isPositionIndependent())
+ return false;
+
+ X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
+ Register GlobalBaseReg = X86FI->getGlobalBaseReg();
+
+ // If we didn't need a GlobalBaseReg, don't insert code.
+ if (GlobalBaseReg == 0)
+ return false;
+
+ // Insert the set of GlobalBaseReg into the first MBB of the function
+ MachineBasicBlock &FirstMBB = MF.front();
+ MachineBasicBlock::iterator MBBI = FirstMBB.begin();
+ DebugLoc DL = FirstMBB.findDebugLoc(MBBI);
+ MachineRegisterInfo &RegInfo = MF.getRegInfo();
+ const X86InstrInfo *TII = STI.getInstrInfo();
+
+ Register PC;
+ if (STI.isPICStyleGOT())
+ PC = RegInfo.createVirtualRegister(&X86::GR32RegClass);
+ else
+ PC = GlobalBaseReg;
+
+ if (STI.is64Bit()) {
+ if (TM->getCodeModel() == CodeModel::Large) {
+ // In the large code model, we are aiming for this code, though the
+ // register allocation may vary:
+ // leaq .LN$pb(%rip), %rax
+ // movq $_GLOBAL_OFFSET_TABLE_ - .LN$pb, %rcx
+ // addq %rcx, %rax
+ // RAX now holds address of _GLOBAL_OFFSET_TABLE_.
+ Register PBReg = RegInfo.createVirtualRegister(&X86::GR64RegClass);
+ Register GOTReg = RegInfo.createVirtualRegister(&X86::GR64RegClass);
+ BuildMI(FirstMBB, MBBI, DL, TII->get(X86::LEA64r), PBReg)
+ .addReg(X86::RIP)
+ .addImm(0)
+ .addReg(0)
+ .addSym(MF.getPICBaseSymbol())
+ .addReg(0);
+ std::prev(MBBI)->setPreInstrSymbol(MF, MF.getPICBaseSymbol());
+ BuildMI(FirstMBB, MBBI, DL, TII->get(X86::MOV64ri), GOTReg)
+ .addExternalSymbol("_GLOBAL_OFFSET_TABLE_",
+ X86II::MO_PIC_BASE_OFFSET);
+ BuildMI(FirstMBB, MBBI, DL, TII->get(X86::ADD64rr), PC)
+ .addReg(PBReg, RegState::Kill)
+ .addReg(GOTReg, RegState::Kill);
+ } else {
+ // In other code models, use a RIP-relative LEA to materialize the
+ // GOT.
+ BuildMI(FirstMBB, MBBI, DL, TII->get(X86::LEA64r), PC)
+ .addReg(X86::RIP)
+ .addImm(0)
+ .addReg(0)
+ .addExternalSymbol("_GLOBAL_OFFSET_TABLE_")
+ .addReg(0);
+ }
+ } else {
+ // Operand of MovePCtoStack is completely ignored by asm printer. It's
+ // only used in JIT code emission as displacement to pc.
+ BuildMI(FirstMBB, MBBI, DL, TII->get(X86::MOVPC32r), PC).addImm(0);
+
+ // If we're using vanilla 'GOT' PIC style, we should use relative
+ // addressing not to pc, but to _GLOBAL_OFFSET_TABLE_ external.
+ if (STI.isPICStyleGOT()) {
+ // Generate addl $__GLOBAL_OFFSET_TABLE_ + [.-piclabel],
+ // %some_register
+ BuildMI(FirstMBB, MBBI, DL, TII->get(X86::ADD32ri), GlobalBaseReg)
+ .addReg(PC)
+ .addExternalSymbol("_GLOBAL_OFFSET_TABLE_",
+ X86II::MO_GOT_ABSOLUTE_ADDRESS);
+ }
+ }
+
+ return true;
+}
+
+bool X86GlobalBaseRegLegacy::runOnMachineFunction(MachineFunction &MF) {
+ return initGlobalBaseReg(MF);
+}
+
+PreservedAnalyses
+X86GlobalBaseRegPass::run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM) {
+ return initGlobalBaseReg(MF) ? getMachineFunctionPassPreservedAnalyses()
+ .preserveSet<CFGAnalyses>()
+ : PreservedAnalyses::all();
+}
diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp
index d85d9b600c2d6..2479a8dccfb00 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -10404,109 +10404,6 @@ X86InstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
return ArrayRef(TargetFlags);
}
-namespace {
-/// Create Global Base Reg pass. This initializes the PIC
-/// global base register for x86-32.
-struct CGBR : public MachineFunctionPass {
- static char ID;
- CGBR() : MachineFunctionPass(ID) {}
-
- bool runOnMachineFunction(MachineFunction &MF) override {
- const X86TargetMachine *TM =
- static_cast<const X86TargetMachine *>(&MF.getTarget());
- const X86Subtarget &STI = MF.getSubtarget<X86Subtarget>();
-
- // Only emit a global base reg in PIC mode.
- if (!TM->isPositionIndependent())
- return false;
-
- X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
- Register GlobalBaseReg = X86FI->getGlobalBaseReg();
-
- // If we didn't need a GlobalBaseReg, don't insert code.
- if (GlobalBaseReg == 0)
- return false;
-
- // Insert the set of GlobalBaseReg into the first MBB of the function
- MachineBasicBlock &FirstMBB = MF.front();
- MachineBasicBlock::iterator MBBI = FirstMBB.begin();
- DebugLoc DL = FirstMBB.findDebugLoc(MBBI);
- MachineRegisterInfo &RegInfo = MF.getRegInfo();
- const X86InstrInfo *TII = STI.getInstrInfo();
-
- Register PC;
- if (STI.isPICStyleGOT())
- PC = RegInfo.createVirtualRegister(&X86::GR32RegClass);
- else
- PC = GlobalBaseReg;
-
- if (STI.is64Bit()) {
- if (TM->getCodeModel() == CodeModel::Large) {
- // In the large code model, we are aiming for this code, though the
- // register allocation may vary:
- // leaq .LN$pb(%rip), %rax
- // movq $_GLOBAL_OFFSET_TABLE_ - .LN$pb, %rcx
- // addq %rcx, %rax
- // RAX now holds address of _GLOBAL_OFFSET_TABLE_.
- Register PBReg = RegInfo.createVirtualRegister(&X86::GR64RegClass);
- Register GOTReg = RegInfo.createVirtualRegister(&X86::GR64RegClass);
- BuildMI(FirstMBB, MBBI, DL, TII->get(X86::LEA64r), PBReg)
- .addReg(X86::RIP)
- .addImm(0)
- .addReg(0)
- .addSym(MF.getPICBaseSymbol())
- .addReg(0);
- std::prev(MBBI)->setPreInstrSymbol(MF, MF.getPICBaseSymbol());
- BuildMI(FirstMBB, MBBI, DL, TII->get(X86::MOV64ri), GOTReg)
- .addExternalSymbol("_GLOBAL_OFFSET_TABLE_",
- X86II::MO_PIC_BASE_OFFSET);
- BuildMI(FirstMBB, MBBI, DL, TII->get(X86::ADD64rr), PC)
- .addReg(PBReg, RegState::Kill)
- .addReg(GOTReg, RegState::Kill);
- } else {
- // In other code models, use a RIP-relative LEA to materialize the
- // GOT.
- BuildMI(FirstMBB, MBBI, DL, TII->get(X86::LEA64r), PC)
- .addReg(X86::RIP)
- .addImm(0)
- .addReg(0)
- .addExternalSymbol("_GLOBAL_OFFSET_TABLE_")
- .addReg(0);
- }
- } else {
- // Operand of MovePCtoStack is completely ignored by asm printer. It's
- // only used in JIT code emission as displacement to pc.
- BuildMI(FirstMBB, MBBI, DL, TII->get(X86::MOVPC32r), PC).addImm(0);
-
- // If we're using vanilla 'GOT' PIC style, we should use relative
- // addressing not to pc, but to _GLOBAL_OFFSET_TABLE_ external.
- if (STI.isPICStyleGOT()) {
- // Generate addl $__GLOBAL_OFFSET_TABLE_ + [.-piclabel],
- // %some_register
- BuildMI(FirstMBB, MBBI, DL, TII->get(X86::ADD32ri), GlobalBaseReg)
- .addReg(PC)
- .addExternalSymbol("_GLOBAL_OFFSET_TABLE_",
- X86II::MO_GOT_ABSOLUTE_ADDRESS);
- }
- }
-
- return true;
- }
-
- StringRef getPassName() const override {
- return "X86 PIC Global Base Reg Initialization";
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesCFG();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
-};
-} // namespace
-
-char CGBR::ID = 0;
-FunctionPass *llvm::createX86GlobalBaseRegPass() { return new CGBR(); }
-
/// Constants defining how certain sequences should be outlined.
///
/// \p MachineOutlinerDefault implies that the function is called with a call
diff --git a/llvm/lib/Target/X86/X86PassRegistry.def b/llvm/lib/Target/X86/X86PassRegistry.def
index 91156260d2c7c..4cdaca2854fe8 100644
--- a/llvm/lib/Target/X86/X86PassRegistry.def
+++ b/llvm/lib/Target/X86/X86PassRegistry.def
@@ -48,6 +48,7 @@ MACHINE_FUNCTION_PASS("x86-fixup-setcc", X86FixupSetCCPass())
MACHINE_FUNCTION_PASS("x86-fixup-vector-constants", X86FixupVectorConstantsPass())
MACHINE_FUNCTION_PASS("x86-flags-copy-lowering", X86FlagsCopyLoweringPass())
MACHINE_FUNCTION_PASS("x86-fp-stackifier", X86FPStackifierPass())
+MACHINE_FUNCTION_PASS("x86-global-base-reg", X86GlobalBaseRegPass())
MACHINE_FUNCTION_PASS("x86-indirect-branch-tracking", X86IndirectBranchTrackingPass())
MACHINE_FUNCTION_PASS("x86-isel", X86ISelDAGToDAGPass(*this))
MACHINE_FUNCTION_PASS("x86-lower-tile-copy", X86LowerTileCopyPass())
@@ -67,7 +68,6 @@ MACHINE_FUNCTION_PASS("x86-wineh-unwindv2", X86WinEHUnwindV2Pass())
#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME)
#endif
DUMMY_MACHINE_FUNCTION_PASS("x86-execution-domain-fix", X86ExecutionDomainFix())
-DUMMY_MACHINE_FUNCTION_PASS("x86-global-base-reg", X86GlobalBaseRegPass())
DUMMY_MACHINE_FUNCTION_PASS("x86-indirect-thunks", X86IndirectThunks())
DUMMY_MACHINE_FUNCTION_PASS("x86-insert-x87-wait", X86InsertX87WaitPass())
DUMMY_MACHINE_FUNCTION_PASS("x86-issue-vzero-upper", X86IssueVZeroUpperPass())
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index 95ad484d04ccd..7154380cd6c02 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -462,7 +462,7 @@ bool X86PassConfig::addInstSelector() {
getOptLevel() != CodeGenOptLevel::None)
addPass(createCleanupLocalDynamicTLSLegacyPass());
- addPass(createX86GlobalBaseRegPass());
+ addPass(createX86GlobalBaseRegLegacyPass());
addPass(createX86ArgumentStackSlotLegacyPass());
return false;
}
@@ -492,7 +492,7 @@ bool X86PassConfig::addGlobalInstructionSelect() {
addPass(new InstructionSelect(getOptLevel()));
// Add GlobalBaseReg in case there is no SelectionDAG passes afterwards
if (isGlobalISelAbortEnabled())
- addPass(createX86GlobalBaseRegPass());
+ addPass(createX86GlobalBaseRegLegacyPass());
return false;
}
diff --git a/llvm/test/CodeGen/X86/llc-pipeline-npm.ll b/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
index 3b1992388ff63..37c76babfc5ff 100644
--- a/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
+++ b/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
@@ -34,6 +34,7 @@
; O0-NEXT: stack-protector
; O0-NEXT: verify)
; O0-NEXT: function(machine-function(x86-isel
+; O0-NEXT: x86-global-base-reg
; O0-NEXT: x86-argument-stack-slot
; O0-NEXT: finalize-isel
; O0-NEXT: localstackalloc
@@ -105,6 +106,7 @@
; O2-NEXT: verify)
; O2-NEXT: function(machine-function(x86-isel
; O2-NEXT: x86-cleanup-local-dynamic-tls
+; O2-NEXT: x86-global-base-reg
; O2-NEXT: x86-argument-stack-slot
; O2-NEXT: finalize-isel
; O2-NEXT: early-tailduplication
@@ -209,6 +211,7 @@
; O0-WINDOWS-NEXT: stack-protector
; O0-WINDOWS-NEXT: verify)
; O0-WINDOWS-NEXT: function(machine-function(x86-isel
+; O0-WINDOWS-NEXT: x86-global-base-reg
; O0-WINDOWS-NEXT: x86-argument-stack-slot
; O0-WINDOWS-NEXT: finalize-isel
; O0-WINDOWS-NEXT: localstackalloc
@@ -283,6 +286,7 @@
; O3-WINDOWS-NEXT: stack-protector
; O3-WINDOWS-NEXT: verify)
; O3-WINDOWS-NEXT: function(machine-function(x86-isel
+; O3-WINDOWS-NEXT: x86-global-base-reg
; O3-WINDOWS-NEXT: x86-argument-stack-slot
; O3-WINDOWS-NEXT: finalize-isel
; O3-WINDOWS-NEXT: early-tailduplication
More information about the llvm-commits
mailing list