[llvm] [NewPM] Port x86-indirect-branch-tracking (PR #179874)
Kyungtak Woo via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 5 00:08:56 PST 2026
https://github.com/kevinwkt updated https://github.com/llvm/llvm-project/pull/179874
>From 939ba4a2eccc92eff0caf5f05c591b996d943ace Mon Sep 17 00:00:00 2001
From: Kyungtak Woo <kevinwkt at google.com>
Date: Thu, 5 Feb 2026 07:28:20 +0000
Subject: [PATCH 1/3] [X86] Port X86IndirectBranchTracking to New Pass Manager
---
llvm/lib/Target/X86/X86.h | 10 ++-
llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp | 3 +-
.../Target/X86/X86IndirectBranchTracking.cpp | 69 +++++++++++--------
llvm/lib/Target/X86/X86PassRegistry.def | 2 +-
llvm/lib/Target/X86/X86TargetMachine.cpp | 2 +-
llvm/test/CodeGen/X86/llc-pipeline-npm.ll | 4 ++
6 files changed, 55 insertions(+), 35 deletions(-)
diff --git a/llvm/lib/Target/X86/X86.h b/llvm/lib/Target/X86/X86.h
index 89ebd59539686..422149a8ca0d0 100644
--- a/llvm/lib/Target/X86/X86.h
+++ b/llvm/lib/Target/X86/X86.h
@@ -59,7 +59,14 @@ FunctionPass *createX86IssueVZeroUpperPass();
/// This pass inserts ENDBR instructions before indirect jump/call
/// destinations as part of CET IBT mechanism.
-FunctionPass *createX86IndirectBranchTrackingPass();
+class X86IndirectBranchTrackingPass
+ : public PassInfoMixin<X86IndirectBranchTrackingPass> {
+public:
+ PreservedAnalyses run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM);
+};
+
+FunctionPass *createX86IndirectBranchTrackingLegacyPass();
/// Return a pass that pads short functions with NOOPs.
/// This will prevent a stall when returning on the Atom.
@@ -429,6 +436,7 @@ void initializeX86FastPreTileConfigLegacyPass(PassRegistry &);
void initializeX86FastTileConfigLegacyPass(PassRegistry &);
void initializeX86FixupSetCCLegacyPass(PassRegistry &);
void initializeX86FlagsCopyLoweringLegacyPass(PassRegistry &);
+void initializeX86IndirectBranchTrackingLegacyPass(PassRegistry &);
void initializeX86LoadValueInjectionLoadHardeningLegacyPass(PassRegistry &);
void initializeX86LoadValueInjectionRetHardeningLegacyPass(PassRegistry &);
void initializeX86LowerAMXIntrinsicsLegacyPassPass(PassRegistry &);
diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
index 1e2198a95bbae..1b3201f3980fe 100644
--- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
@@ -174,8 +174,7 @@ void X86CodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) const {
addMachineFunctionPass(BreakFalseDepsPass(), PMW);
}
- // TODO(boomanaiden154): Add X86IndirectBranchTrackingPass here once it has
- // been ported.
+ addMachineFunctionPass(X86IndirectBranchTrackingPass(), PMW);
// TODO(boomanaiden154): Add X86IssueVZeroUpperPass here once it has been
// ported.
diff --git a/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp b/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp
index 52be14228e555..1c9de4693e1da 100644
--- a/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp
+++ b/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp
@@ -36,42 +36,29 @@ cl::opt<bool> IndirectBranchTracking(
STATISTIC(NumEndBranchAdded, "Number of ENDBR instructions added");
namespace {
-class X86IndirectBranchTrackingPass : public MachineFunctionPass {
+class X86IndirectBranchTrackingLegacy : public MachineFunctionPass {
public:
- X86IndirectBranchTrackingPass() : MachineFunctionPass(ID) {}
+ static char ID;
+
+ X86IndirectBranchTrackingLegacy() : MachineFunctionPass(ID) {}
StringRef getPassName() const override {
return "X86 Indirect Branch Tracking";
}
bool runOnMachineFunction(MachineFunction &MF) override;
-
-private:
- static char ID;
-
- /// Machine instruction info used throughout the class.
- const X86InstrInfo *TII = nullptr;
-
- /// Endbr opcode for the current machine function.
- unsigned int EndbrOpcode = 0;
-
- /// Adds a new ENDBR instruction to the beginning of the MBB.
- /// The function will not add it if already exists.
- /// It will add ENDBR32 or ENDBR64 opcode, depending on the target.
- /// \returns true if the ENDBR was added and false otherwise.
- bool addENDBR(MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const;
};
-} // end anonymous namespace
-
-char X86IndirectBranchTrackingPass::ID = 0;
-
-FunctionPass *llvm::createX86IndirectBranchTrackingPass() {
- return new X86IndirectBranchTrackingPass();
-}
+/// Adds a new ENDBR instruction to the beginning of the MBB.
+/// The function will not add it if already exists.
+/// It will add ENDBR32 or ENDBR64 opcode, depending on the target.
+/// \returns true if the ENDBR was added and false otherwise.
+static bool addENDBR(MachineBasicBlock &MBB, MachineBasicBlock::iterator I) {
+ MachineFunction &MF = *MBB.getParent();
+ const X86Subtarget &SubTarget = MF.getSubtarget<X86Subtarget>();
+ const X86InstrInfo *TII = SubTarget.getInstrInfo();
+ unsigned EndbrOpcode = SubTarget.is64Bit() ? X86::ENDBR64 : X86::ENDBR32;
-bool X86IndirectBranchTrackingPass::addENDBR(
- MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const {
assert(TII && "Target instruction info was not initialized");
assert((X86::ENDBR64 == EndbrOpcode || X86::ENDBR32 == EndbrOpcode) &&
"Unexpected Endbr opcode");
@@ -86,6 +73,17 @@ bool X86IndirectBranchTrackingPass::addENDBR(
return false;
}
+} // end anonymous namespace
+
+char X86IndirectBranchTrackingLegacy::ID = 0;
+
+INITIALIZE_PASS(X86IndirectBranchTrackingLegacy, DEBUG_TYPE,
+ "X86 Indirect Branch Tracking", false, false)
+
+FunctionPass *llvm::createX86IndirectBranchTrackingLegacyPass() {
+ return new X86IndirectBranchTrackingLegacy();
+}
+
static bool IsCallReturnTwice(llvm::MachineOperand &MOp) {
if (!MOp.isGlobal())
return false;
@@ -113,7 +111,7 @@ static bool needsPrologueENDBR(MachineFunction &MF, const Module *M) {
}
}
-bool X86IndirectBranchTrackingPass::runOnMachineFunction(MachineFunction &MF) {
+static bool runIndirectBranchTracking(MachineFunction &MF) {
const X86Subtarget &SubTarget = MF.getSubtarget<X86Subtarget>();
const Module *M = MF.getFunction().getParent();
@@ -135,9 +133,6 @@ bool X86IndirectBranchTrackingPass::runOnMachineFunction(MachineFunction &MF) {
// True if the current MF was changed and false otherwise.
bool Changed = false;
- TII = SubTarget.getInstrInfo();
- EndbrOpcode = SubTarget.is64Bit() ? X86::ENDBR64 : X86::ENDBR32;
-
// If function is reachable indirectly, mark the first BB with ENDBR.
if (needsPrologueENDBR(MF, M)) {
auto MBB = MF.begin();
@@ -189,3 +184,17 @@ bool X86IndirectBranchTrackingPass::runOnMachineFunction(MachineFunction &MF) {
}
return Changed;
}
+
+bool X86IndirectBranchTrackingLegacy::runOnMachineFunction(
+ MachineFunction &MF) {
+ return runIndirectBranchTracking(MF);
+}
+
+PreservedAnalyses
+X86IndirectBranchTrackingPass::run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM) {
+ return runIndirectBranchTracking(MF)
+ ? getMachineFunctionPassPreservedAnalyses()
+ .preserveSet<CFGAnalyses>()
+ : PreservedAnalyses::all();
+}
diff --git a/llvm/lib/Target/X86/X86PassRegistry.def b/llvm/lib/Target/X86/X86PassRegistry.def
index 4fb6935712818..6fae244e56bf7 100644
--- a/llvm/lib/Target/X86/X86PassRegistry.def
+++ b/llvm/lib/Target/X86/X86PassRegistry.def
@@ -45,6 +45,7 @@ MACHINE_FUNCTION_PASS("x86-fixup-inst-tuning", X86FixupInstTuningPass())
MACHINE_FUNCTION_PASS("x86-fixup-leas", X86FixupLEAsPass())
MACHINE_FUNCTION_PASS("x86-fixup-setcc", X86FixupSetCCPass())
MACHINE_FUNCTION_PASS("x86-fixup-vector-constants", X86FixupVectorConstantsPass())
+MACHINE_FUNCTION_PASS("x86-indirect-branch-tracking", X86IndirectBranchTrackingPass())
MACHINE_FUNCTION_PASS("x86-flags-copy-lowering", X86FlagsCopyLoweringPass())
MACHINE_FUNCTION_PASS("x86-fp-stackifier", X86FPStackifierPass())
MACHINE_FUNCTION_PASS("x86-isel", X86ISelDAGToDAGPass(*this))
@@ -67,7 +68,6 @@ MACHINE_FUNCTION_PASS("x86-wineh-unwindv2", X86WinEHUnwindV2Pass())
DUMMY_MACHINE_FUNCTION_PASS("x86-cleanup-local-dynamic-tls", X86CleanupLocalDynamicTLSPass())
DUMMY_MACHINE_FUNCTION_PASS("x86-execution-domain-fix", X86ExecutionDomainFix())
DUMMY_MACHINE_FUNCTION_PASS("x86-global-base-reg", X86GlobalBaseRegPass())
-DUMMY_MACHINE_FUNCTION_PASS("x86-indirect-branch-tracking", X86IndirectBranchTrackingPass())
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 81c18fecd43b0..a1e9ed3d10840 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -566,7 +566,7 @@ void X86PassConfig::addPreEmitPass() {
addPass(createBreakFalseDeps());
}
- addPass(createX86IndirectBranchTrackingPass());
+ addPass(createX86IndirectBranchTrackingLegacyPass());
addPass(createX86IssueVZeroUpperPass());
diff --git a/llvm/test/CodeGen/X86/llc-pipeline-npm.ll b/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
index 7c0ddc69ebec7..a5a77b719fba2 100644
--- a/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
+++ b/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
@@ -55,6 +55,7 @@
; O0-NEXT: fentry-insert
; O0-NEXT: xray-instrumentation
; O0-NEXT: patchable-function
+; O0-NEXT: x86-indirect-branch-tracking
; O0-NEXT: x86-compress-evex
; O0-NEXT: FuncletLayoutPass
; O0-NEXT: remove-loads-into-fake-uses
@@ -163,6 +164,7 @@
; O2-NEXT: xray-instrumentation
; O2-NEXT: patchable-function
; O2-NEXT: BreakFalseDepsPass
+; O2-NEXT: x86-indirect-branch-tracking
; O2-NEXT: x86-fixup-bw-insts
; O2-NEXT: x86-fixup-leas
; O2-NEXT: x86-fixup-inst-tuning
@@ -227,6 +229,7 @@
; O0-WINDOWS-NEXT: fentry-insert
; O0-WINDOWS-NEXT: xray-instrumentation
; O0-WINDOWS-NEXT: patchable-function
+; O0-WINDOWS-NEXT: x86-indirect-branch-tracking
; O0-WINDOWS-NEXT: x86-compress-evex
; O0-WINDOWS-NEXT: FuncletLayoutPass
; O0-WINDOWS-NEXT: remove-loads-into-fake-uses
@@ -339,6 +342,7 @@
; O3-WINDOWS-NEXT: xray-instrumentation
; O3-WINDOWS-NEXT: patchable-function
; O3-WINDOWS-NEXT: BreakFalseDepsPass
+; O3-WINDOWS-NEXT: x86-indirect-branch-tracking
; O3-WINDOWS-NEXT: x86-fixup-bw-insts
; O3-WINDOWS-NEXT: x86-fixup-leas
; O3-WINDOWS-NEXT: x86-fixup-inst-tuning
>From 10859aec2058cfa0b32910882f63fe23b4eb4ddc Mon Sep 17 00:00:00 2001
From: Kyungtak Woo <kevinwkt at google.com>
Date: Thu, 5 Feb 2026 08:01:40 +0000
Subject: [PATCH 2/3] get rid of unsed var
---
llvm/lib/Target/X86/X86IndirectBranchTracking.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp b/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp
index 1c9de4693e1da..a45a6623760c5 100644
--- a/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp
+++ b/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp
@@ -112,7 +112,7 @@ static bool needsPrologueENDBR(MachineFunction &MF, const Module *M) {
}
static bool runIndirectBranchTracking(MachineFunction &MF) {
- const X86Subtarget &SubTarget = MF.getSubtarget<X86Subtarget>();
+
const Module *M = MF.getFunction().getParent();
// Check that the cf-protection-branch is enabled.
>From 2b77c029a7946f50be641a2bcdd6b11f8802e115 Mon Sep 17 00:00:00 2001
From: Kyungtak Woo <kevinwkt at google.com>
Date: Thu, 5 Feb 2026 08:08:37 +0000
Subject: [PATCH 3/3] not sure why my clang format behaves different
---
llvm/lib/Target/X86/X86IndirectBranchTracking.cpp | 2 --
1 file changed, 2 deletions(-)
diff --git a/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp b/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp
index a45a6623760c5..6ccad26a890dd 100644
--- a/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp
+++ b/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp
@@ -112,8 +112,6 @@ static bool needsPrologueENDBR(MachineFunction &MF, const Module *M) {
}
static bool runIndirectBranchTracking(MachineFunction &MF) {
-
-
const Module *M = MF.getFunction().getParent();
// Check that the cf-protection-branch is enabled.
Metadata *isCFProtectionSupported = M->getModuleFlag("cf-protection-branch");
More information about the llvm-commits
mailing list