[llvm] 4958c4c - [NewPM] Extract logic for X86 SLH into a separate class (#175718)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 13 12:57:34 PST 2026
Author: Anshul Nigham
Date: 2026-01-13T20:57:29Z
New Revision: 4958c4c1c3f698d60be54d04e67503e9f9c32b6d
URL: https://github.com/llvm/llvm-project/commit/4958c4c1c3f698d60be54d04e67503e9f9c32b6d
DIFF: https://github.com/llvm/llvm-project/commit/4958c4c1c3f698d60be54d04e67503e9f9c32b6d.diff
LOG: [NewPM] Extract logic for X86 SLH into a separate class (#175718)
This will enable easier migration to NewPM
Added:
Modified:
llvm/lib/Target/X86/X86SpeculativeLoadHardening.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86SpeculativeLoadHardening.cpp b/llvm/lib/Target/X86/X86SpeculativeLoadHardening.cpp
index 829a32eb37118..c69bda3448a87 100644
--- a/llvm/lib/Target/X86/X86SpeculativeLoadHardening.cpp
+++ b/llvm/lib/Target/X86/X86SpeculativeLoadHardening.cpp
@@ -117,18 +117,25 @@ static cl::opt<bool> HardenIndirectCallsAndJumps(
namespace {
+constexpr StringRef X86SLHPassName = "X86 speculative load hardening";
+
class X86SpeculativeLoadHardeningPass : public MachineFunctionPass {
public:
X86SpeculativeLoadHardeningPass() : MachineFunctionPass(ID) { }
- StringRef getPassName() const override {
- return "X86 speculative load hardening";
- }
+ StringRef getPassName() const override { return X86SLHPassName; }
bool runOnMachineFunction(MachineFunction &MF) override;
void getAnalysisUsage(AnalysisUsage &AU) const override;
/// Pass identification, replacement for typeid.
static char ID;
+};
+
+class X86SpeculativeLoadHardeningImpl {
+public:
+ X86SpeculativeLoadHardeningImpl() = default;
+
+ bool run(MachineFunction &MF);
private:
/// The information about a block's conditional terminators needed to trace
@@ -211,6 +218,15 @@ class X86SpeculativeLoadHardeningPass : public MachineFunctionPass {
} // end anonymous namespace
+bool X86SpeculativeLoadHardeningPass::runOnMachineFunction(
+ MachineFunction &MF) {
+ X86SpeculativeLoadHardeningImpl Impl;
+ bool Changed = Impl.run(MF);
+ LLVM_DEBUG(dbgs() << "Final speculative load hardened function:\n"; MF.dump();
+ dbgs() << "\n"; MF.verify(this));
+ return Changed;
+}
+
char X86SpeculativeLoadHardeningPass::ID = 0;
void X86SpeculativeLoadHardeningPass::getAnalysisUsage(
@@ -392,9 +408,8 @@ static bool hasVulnerableLoad(MachineFunction &MF) {
return false;
}
-bool X86SpeculativeLoadHardeningPass::runOnMachineFunction(
- MachineFunction &MF) {
- LLVM_DEBUG(dbgs() << "********** " << getPassName() << " : " << MF.getName()
+bool X86SpeculativeLoadHardeningImpl::run(MachineFunction &MF) {
+ LLVM_DEBUG(dbgs() << "********** " << X86SLHPassName << " : " << MF.getName()
<< " **********\n");
// Only run if this pass is forced enabled or we detect the relevant function
@@ -549,8 +564,6 @@ bool X86SpeculativeLoadHardeningPass::runOnMachineFunction(
PS->SSA.RewriteUse(Op);
}
- LLVM_DEBUG(dbgs() << "Final speculative load hardened function:\n"; MF.dump();
- dbgs() << "\n"; MF.verify(this));
return true;
}
@@ -560,7 +573,7 @@ bool X86SpeculativeLoadHardeningPass::runOnMachineFunction(
/// We include this as an alternative mostly for the purpose of comparison. The
/// performance impact of this is expected to be extremely severe and not
/// practical for any real-world users.
-void X86SpeculativeLoadHardeningPass::hardenEdgesWithLFENCE(
+void X86SpeculativeLoadHardeningImpl::hardenEdgesWithLFENCE(
MachineFunction &MF) {
// First, we scan the function looking for blocks that are reached along edges
// that we might want to harden.
@@ -592,8 +605,8 @@ void X86SpeculativeLoadHardeningPass::hardenEdgesWithLFENCE(
}
}
-SmallVector<X86SpeculativeLoadHardeningPass::BlockCondInfo, 16>
-X86SpeculativeLoadHardeningPass::collectBlockCondInfo(MachineFunction &MF) {
+SmallVector<X86SpeculativeLoadHardeningImpl::BlockCondInfo, 16>
+X86SpeculativeLoadHardeningImpl::collectBlockCondInfo(MachineFunction &MF) {
SmallVector<BlockCondInfo, 16> Infos;
// Walk the function and build up a summary for each block's conditions that
@@ -685,7 +698,7 @@ X86SpeculativeLoadHardeningPass::collectBlockCondInfo(MachineFunction &MF) {
/// uses of the predicate state rewritten into proper SSA form once it is
/// complete.
SmallVector<MachineInstr *, 16>
-X86SpeculativeLoadHardeningPass::tracePredStateThroughCFG(
+X86SpeculativeLoadHardeningImpl::tracePredStateThroughCFG(
MachineFunction &MF, ArrayRef<BlockCondInfo> Infos) {
// Collect the inserted cmov instructions so we can rewrite their uses of the
// predicate state into SSA form.
@@ -843,7 +856,7 @@ getRegClassForUnfoldedLoad(const X86InstrInfo &TII, unsigned Opcode) {
return TII.getRegClass(MCID, Index);
}
-void X86SpeculativeLoadHardeningPass::unfoldCallAndJumpLoads(
+void X86SpeculativeLoadHardeningImpl::unfoldCallAndJumpLoads(
MachineFunction &MF) {
for (MachineBasicBlock &MBB : MF)
// We use make_early_inc_range here so we can remove instructions if needed
@@ -954,7 +967,7 @@ void X86SpeculativeLoadHardeningPass::unfoldCallAndJumpLoads(
/// calls, however, cannot be mitigated through this technique without changing
/// the ABI in a fundamental way.
SmallVector<MachineInstr *, 16>
-X86SpeculativeLoadHardeningPass::tracePredStateThroughIndirectBranches(
+X86SpeculativeLoadHardeningImpl::tracePredStateThroughIndirectBranches(
MachineFunction &MF) {
// We use the SSAUpdater to insert PHI nodes for the target addresses of
// indirect branches. We don't actually need the full power of the SSA updater
@@ -1258,7 +1271,7 @@ static bool isEFLAGSLive(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
///
/// These two passes are applied to each basic block. We operate one block at a
/// time to simplify reasoning about reachability and sequencing.
-void X86SpeculativeLoadHardeningPass::tracePredStateThroughBlocksAndHarden(
+void X86SpeculativeLoadHardeningImpl::tracePredStateThroughBlocksAndHarden(
MachineFunction &MF) {
SmallPtrSet<MachineInstr *, 16> HardenPostLoad;
SmallPtrSet<MachineInstr *, 16> HardenLoadAddr;
@@ -1487,7 +1500,7 @@ void X86SpeculativeLoadHardeningPass::tracePredStateThroughBlocksAndHarden(
/// Note that LLVM can only lower very simple patterns of saved and restored
/// EFLAGS registers. The restore should always be within the same basic block
/// as the save so that no PHI nodes are inserted.
-Register X86SpeculativeLoadHardeningPass::saveEFLAGS(
+Register X86SpeculativeLoadHardeningImpl::saveEFLAGS(
MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertPt,
const DebugLoc &Loc) {
// FIXME: Hard coding this to a 32-bit register class seems weird, but matches
@@ -1505,7 +1518,7 @@ Register X86SpeculativeLoadHardeningPass::saveEFLAGS(
///
/// This must be done within the same basic block as the save in order to
/// reliably lower.
-void X86SpeculativeLoadHardeningPass::restoreEFLAGS(
+void X86SpeculativeLoadHardeningImpl::restoreEFLAGS(
MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertPt,
const DebugLoc &Loc, Register Reg) {
BuildMI(MBB, InsertPt, Loc, TII->get(X86::COPY), X86::EFLAGS).addReg(Reg);
@@ -1516,7 +1529,7 @@ void X86SpeculativeLoadHardeningPass::restoreEFLAGS(
/// stack pointer. The state is essentially a single bit, but we merge this in
/// a way that won't form non-canonical pointers and also will be preserved
/// across normal stack adjustments.
-void X86SpeculativeLoadHardeningPass::mergePredStateIntoSP(
+void X86SpeculativeLoadHardeningImpl::mergePredStateIntoSP(
MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertPt,
const DebugLoc &Loc, Register PredStateReg) {
Register TmpReg = MRI->createVirtualRegister(PS->RC);
@@ -1536,7 +1549,7 @@ void X86SpeculativeLoadHardeningPass::mergePredStateIntoSP(
}
/// Extracts the predicate state stored in the high bits of the stack pointer.
-Register X86SpeculativeLoadHardeningPass::extractPredStateFromSP(
+Register X86SpeculativeLoadHardeningImpl::extractPredStateFromSP(
MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertPt,
const DebugLoc &Loc) {
Register PredStateReg = MRI->createVirtualRegister(PS->RC);
@@ -1557,7 +1570,7 @@ Register X86SpeculativeLoadHardeningPass::extractPredStateFromSP(
return PredStateReg;
}
-void X86SpeculativeLoadHardeningPass::hardenLoadAddr(
+void X86SpeculativeLoadHardeningImpl::hardenLoadAddr(
MachineInstr &MI, MachineOperand &BaseMO, MachineOperand &IndexMO,
SmallDenseMap<Register, Register, 32> &AddrRegToHardenedReg) {
MachineBasicBlock &MBB = *MI.getParent();
@@ -1759,7 +1772,7 @@ void X86SpeculativeLoadHardeningPass::hardenLoadAddr(
restoreEFLAGS(MBB, InsertPt, Loc, FlagsReg);
}
-MachineInstr *X86SpeculativeLoadHardeningPass::sinkPostLoadHardenedInst(
+MachineInstr *X86SpeculativeLoadHardeningImpl::sinkPostLoadHardenedInst(
MachineInstr &InitialMI, SmallPtrSetImpl<MachineInstr *> &HardenedInstrs) {
assert(X86InstrInfo::isDataInvariantLoad(InitialMI) &&
"Cannot get here with a non-invariant load!");
@@ -1849,7 +1862,7 @@ MachineInstr *X86SpeculativeLoadHardeningPass::sinkPostLoadHardenedInst(
return MI;
}
-bool X86SpeculativeLoadHardeningPass::canHardenRegister(Register Reg) {
+bool X86SpeculativeLoadHardeningImpl::canHardenRegister(Register Reg) {
// We only support hardening virtual registers.
if (!Reg.isVirtual())
return false;
@@ -1896,7 +1909,7 @@ bool X86SpeculativeLoadHardeningPass::canHardenRegister(Register Reg) {
///
/// The new, hardened virtual register is returned. It will have the same
/// register class as `Reg`.
-Register X86SpeculativeLoadHardeningPass::hardenValueInRegister(
+Register X86SpeculativeLoadHardeningImpl::hardenValueInRegister(
Register Reg, MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertPt,
const DebugLoc &Loc) {
assert(canHardenRegister(Reg) && "Cannot harden this register!");
@@ -1946,7 +1959,7 @@ Register X86SpeculativeLoadHardeningPass::hardenValueInRegister(
/// execution and coercing them to one is sufficient.
///
/// Returns the newly hardened register.
-Register X86SpeculativeLoadHardeningPass::hardenPostLoad(MachineInstr &MI) {
+Register X86SpeculativeLoadHardeningImpl::hardenPostLoad(MachineInstr &MI) {
MachineBasicBlock &MBB = *MI.getParent();
const DebugLoc &Loc = MI.getDebugLoc();
@@ -1997,7 +2010,7 @@ Register X86SpeculativeLoadHardeningPass::hardenPostLoad(MachineInstr &MI) {
/// speculatively even during a BCBS-attacked return until the steering takes
/// effect. Whenever this happens, the caller can recover the (poisoned)
/// predicate state from the stack pointer and continue to harden loads.
-void X86SpeculativeLoadHardeningPass::hardenReturnInstr(MachineInstr &MI) {
+void X86SpeculativeLoadHardeningImpl::hardenReturnInstr(MachineInstr &MI) {
MachineBasicBlock &MBB = *MI.getParent();
const DebugLoc &Loc = MI.getDebugLoc();
auto InsertPt = MI.getIterator();
@@ -2043,7 +2056,7 @@ void X86SpeculativeLoadHardeningPass::hardenReturnInstr(MachineInstr &MI) {
/// immediately following the call (the observed return address). If these
/// mismatch, we have detected misspeculation and can poison our predicate
/// state.
-void X86SpeculativeLoadHardeningPass::tracePredStateThroughCall(
+void X86SpeculativeLoadHardeningImpl::tracePredStateThroughCall(
MachineInstr &MI) {
MachineBasicBlock &MBB = *MI.getParent();
MachineFunction &MF = *MBB.getParent();
@@ -2203,7 +2216,7 @@ void X86SpeculativeLoadHardeningPass::tracePredStateThroughCall(
/// execution. We forcibly unfolded all relevant loads above and so will always
/// have an opportunity to post-load harden here, we just need to scan for cases
/// not already flagged and add them.
-void X86SpeculativeLoadHardeningPass::hardenIndirectCallOrJumpInstr(
+void X86SpeculativeLoadHardeningImpl::hardenIndirectCallOrJumpInstr(
MachineInstr &MI,
SmallDenseMap<Register, Register, 32> &AddrRegToHardenedReg) {
switch (MI.getOpcode()) {
More information about the llvm-commits
mailing list