[llvm] 6e967f6 - [NewPM] Port EHContGuardTargets to the new pass manager (#217843)

via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 22 17:51:36 PDT 2026


Author: Bill Wendling
Date: 2026-08-22T17:51:32-07:00
New Revision: 6e967f688adc02a6bd98255b82e77e48c21083fd

URL: https://github.com/llvm/llvm-project/commit/6e967f688adc02a6bd98255b82e77e48c21083fd
DIFF: https://github.com/llvm/llvm-project/commit/6e967f688adc02a6bd98255b82e77e48c21083fd.diff

LOG: [NewPM] Port EHContGuardTargets to the new pass manager (#217843)

Adds a newPM pass for EHContGuardTargets (eh-cont-guard-targets).

- Extracts the pass's logic (which has no per-instance state) into a
shared runEHContGuardTargets free function, called by both the legacy
pass and the new pass manager pass.
- Renames the old pass with the "Legacy" suffix, and (matching the same
convention already applied to CFIInstrInserter) renames
createEHContGuardTargetsPass() to createEHContGuardTargetsLegacy() at
all three legacy call sites (X86, AArch64, ARM).
- Adds the new pass manager pass EHContGuardTargetsPass, using
RequiredPassInfoMixin: the legacy pass's runOnMachineFunction never
calls skipFunction, so it always runs unconditionally and should not be
skippable in the new PM either.
- Updates MachinePassRegistry.def and PassBuilder.
- Wires the pass into X86's newPM pipeline, replacing an existing TODO
inside the already-correct TT.isOSWindows() conditional in
X86CodeGenPassBuilder.cpp. AArch64 and ARM have no newPM
CodeGenPassBuilder yet (legacy-only), so no wiring was needed there.
- Adds a -enable-new-pm RUN line to ehcontguard.ll (X86 only, the only
target with newPM support), since no dedicated unit test existed to
extend, and updates llc-pipeline-npm.ll's O0-WINDOWS/O3-WINDOWS
pipeline-dump expectations (verified empirically where the pass lands in
the dump).

Assisted-by: Claude Sonnet 5

Added: 
    llvm/include/llvm/CodeGen/EHContGuardTargets.h

Modified: 
    llvm/include/llvm/CodeGen/Passes.h
    llvm/include/llvm/InitializePasses.h
    llvm/include/llvm/Passes/MachinePassRegistry.def
    llvm/lib/CodeGen/CodeGen.cpp
    llvm/lib/CodeGen/EHContGuardTargets.cpp
    llvm/lib/Passes/PassBuilder.cpp
    llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
    llvm/lib/Target/ARM/ARMTargetMachine.cpp
    llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
    llvm/lib/Target/X86/X86TargetMachine.cpp
    llvm/test/CodeGen/X86/ehcontguard.ll
    llvm/test/CodeGen/X86/llc-pipeline-npm.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/EHContGuardTargets.h b/llvm/include/llvm/CodeGen/EHContGuardTargets.h
new file mode 100644
index 0000000000000..052183d39226a
--- /dev/null
+++ b/llvm/include/llvm/CodeGen/EHContGuardTargets.h
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_EHCONTGUARDTARGETS_H
+#define LLVM_CODEGEN_EHCONTGUARDTARGETS_H
+
+#include "llvm/CodeGen/MachinePassManager.h"
+
+namespace llvm {
+
+class EHContGuardTargetsPass
+    : public RequiredPassInfoMixin<EHContGuardTargetsPass> {
+public:
+  LLVM_ABI PreservedAnalyses run(MachineFunction &MF,
+                                 MachineFunctionAnalysisManager &MFAM);
+};
+
+} // namespace llvm
+
+#endif // LLVM_CODEGEN_EHCONTGUARDTARGETS_H

diff  --git a/llvm/include/llvm/CodeGen/Passes.h b/llvm/include/llvm/CodeGen/Passes.h
index 0009373a68c78..8c2b923aeb807 100644
--- a/llvm/include/llvm/CodeGen/Passes.h
+++ b/llvm/include/llvm/CodeGen/Passes.h
@@ -580,7 +580,7 @@ LLVM_ABI FunctionPass *createCFGuardLongjmpPass();
 
 /// Creates Windows EH Continuation Guard target identification pass.
 /// \see EHContGuardTargets.cpp
-LLVM_ABI FunctionPass *createEHContGuardTargetsPass();
+LLVM_ABI FunctionPass *createEHContGuardTargetsLegacy();
 
 /// Create Hardware Loop pass. \see HardwareLoops.cpp
 LLVM_ABI FunctionPass *createHardwareLoopsLegacyPass();

diff  --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index 0a74a04b3e759..dec7a5ff0845d 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -111,7 +111,7 @@ LLVM_ABI void initializeEarlyIfPredicatorPass(PassRegistry &);
 LLVM_ABI void initializeEarlyMachineLICMPass(PassRegistry &);
 LLVM_ABI void initializeEarlyTailDuplicateLegacyPass(PassRegistry &);
 LLVM_ABI void initializeEdgeBundlesWrapperLegacyPass(PassRegistry &);
-LLVM_ABI void initializeEHContGuardTargetsPass(PassRegistry &);
+LLVM_ABI void initializeEHContGuardTargetsLegacyPass(PassRegistry &);
 LLVM_ABI void initializeExpandIRInstsLegacyPassPass(PassRegistry &);
 LLVM_ABI void initializeExpandPostRALegacyPass(PassRegistry &);
 LLVM_ABI void initializeExpandReductionsPass(PassRegistry &);

diff  --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def
index dd42e30205a02..1bdfd72c9d736 100644
--- a/llvm/include/llvm/Passes/MachinePassRegistry.def
+++ b/llvm/include/llvm/Passes/MachinePassRegistry.def
@@ -76,6 +76,7 @@ MACHINE_FUNCTION_PASS("dot-machine-cfg", MachineCFGPrinterPass())
 MACHINE_FUNCTION_PASS("early-ifcvt", EarlyIfConverterPass())
 MACHINE_FUNCTION_PASS("early-machinelicm", EarlyMachineLICMPass())
 MACHINE_FUNCTION_PASS("early-tailduplication", EarlyTailDuplicatePass())
+MACHINE_FUNCTION_PASS("eh-cont-guard-targets", EHContGuardTargetsPass())
 MACHINE_FUNCTION_PASS("fentry-insert", FEntryInserterPass())
 MACHINE_FUNCTION_PASS("finalize-isel", FinalizeISelPass())
 MACHINE_FUNCTION_PASS("finalizebundle-test", FinalizeBundleTestPass())
@@ -246,7 +247,6 @@ DUMMY_MACHINE_MODULE_PASS("pseudo-probe-inserter", PseudoProbeInserterPass)
 DUMMY_MACHINE_FUNCTION_PASS("bbsections-prepare", BasicBlockSectionsPass)
 DUMMY_MACHINE_FUNCTION_PASS("bbsections-profile-reader", BasicBlockSectionsProfileReaderPass)
 DUMMY_MACHINE_FUNCTION_PASS("cfguard-longjmp", CFGuardLongjmpPass)
-DUMMY_MACHINE_FUNCTION_PASS("eh-cont-guard-targets", EHContGuardTargetsPass)
 DUMMY_MACHINE_FUNCTION_PASS("fs-profile-loader", MIRProfileLoaderNewPass)
 DUMMY_MACHINE_FUNCTION_PASS("lrshrink", LiveRangeShrinkPass)
 DUMMY_MACHINE_FUNCTION_PASS("machine-function-splitter", MachineFunctionSplitterPass)

diff  --git a/llvm/lib/CodeGen/CodeGen.cpp b/llvm/lib/CodeGen/CodeGen.cpp
index 6be46b0f6cef1..7fb2fca6b6494 100644
--- a/llvm/lib/CodeGen/CodeGen.cpp
+++ b/llvm/lib/CodeGen/CodeGen.cpp
@@ -38,7 +38,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
   initializeDetectDeadLanesLegacyPass(Registry);
   initializeDummyCGSCCPassPass(Registry);
   initializeDwarfEHPrepareLegacyPassPass(Registry);
-  initializeEHContGuardTargetsPass(Registry);
+  initializeEHContGuardTargetsLegacyPass(Registry);
   initializeEarlyIfConverterLegacyPass(Registry);
   initializeEarlyIfPredicatorPass(Registry);
   initializeEarlyMachineLICMPass(Registry);

diff  --git a/llvm/lib/CodeGen/EHContGuardTargets.cpp b/llvm/lib/CodeGen/EHContGuardTargets.cpp
index 9ad3f671798c9..f4db86506c218 100644
--- a/llvm/lib/CodeGen/EHContGuardTargets.cpp
+++ b/llvm/lib/CodeGen/EHContGuardTargets.cpp
@@ -15,6 +15,7 @@
 ///
 //===----------------------------------------------------------------------===//
 
+#include "llvm/CodeGen/EHContGuardTargets.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
@@ -29,53 +30,68 @@ using namespace llvm;
 
 STATISTIC(EHContGuardTargetsFound, "Number of EHCont Guard targets");
 
+static bool runEHContGuardTargets(MachineFunction &MF) {
+  // Skip modules for which the ehcontguard flag is not set.
+  if (!MF.getFunction().getParent()->getModuleFlag("ehcontguard"))
+    return false;
+
+  // Skip functions that do not have targets
+  if (!MF.hasEHContTarget())
+    return false;
+
+  bool Result = false;
+
+  for (MachineBasicBlock &MBB : MF) {
+    if (MBB.isEHContTarget()) {
+      MF.addEHContTarget(MBB.getEHContSymbol());
+      EHContGuardTargetsFound++;
+      Result = true;
+    }
+  }
+
+  return Result;
+}
+
 namespace {
 
 /// MachineFunction pass to insert a symbol before each valid catchret target
 /// and store these in the MachineFunction's CatchRetTargets vector.
-class EHContGuardTargets : public MachineFunctionPass {
+class EHContGuardTargetsLegacy : public MachineFunctionPass {
 public:
   static char ID;
 
-  EHContGuardTargets() : MachineFunctionPass(ID) {}
+  EHContGuardTargetsLegacy() : MachineFunctionPass(ID) {}
 
   StringRef getPassName() const override {
     return "EH Cont Guard catchret targets";
   }
 
-  bool runOnMachineFunction(MachineFunction &MF) override;
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.setPreservesCFG();
+    MachineFunctionPass::getAnalysisUsage(AU);
+  }
+
+  bool runOnMachineFunction(MachineFunction &MF) override {
+    return runEHContGuardTargets(MF);
+  }
 };
 
 } // end anonymous namespace
 
-char EHContGuardTargets::ID = 0;
+char EHContGuardTargetsLegacy::ID = 0;
 
-INITIALIZE_PASS(EHContGuardTargets, "EHContGuardTargets",
+INITIALIZE_PASS(EHContGuardTargetsLegacy, "EHContGuardTargets",
                 "Insert symbols at valid targets for /guard:ehcont", false,
                 false)
-FunctionPass *llvm::createEHContGuardTargetsPass() {
-  return new EHContGuardTargets();
+FunctionPass *llvm::createEHContGuardTargetsLegacy() {
+  return new EHContGuardTargetsLegacy();
 }
 
-bool EHContGuardTargets::runOnMachineFunction(MachineFunction &MF) {
-
-  // Skip modules for which the ehcontguard flag is not set.
-  if (!MF.getFunction().getParent()->getModuleFlag("ehcontguard"))
-    return false;
+PreservedAnalyses
+EHContGuardTargetsPass::run(MachineFunction &MF,
+                            MachineFunctionAnalysisManager &MFAM) {
+  if (!runEHContGuardTargets(MF))
+    return PreservedAnalyses::all();
 
-  // Skip functions that do not have targets
-  if (!MF.hasEHContTarget())
-    return false;
-
-  bool Result = false;
-
-  for (MachineBasicBlock &MBB : MF) {
-    if (MBB.isEHContTarget()) {
-      MF.addEHContTarget(MBB.getEHContSymbol());
-      EHContGuardTargetsFound++;
-      Result = true;
-    }
-  }
-
-  return Result;
+  return getMachineFunctionPassPreservedAnalyses().preserveSet<CFGAnalyses>();
 }

diff  --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index d92e7b1708657..545b2905bdaaa 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -94,6 +94,7 @@
 #include "llvm/CodeGen/DeadMachineInstructionElim.h"
 #include "llvm/CodeGen/DetectDeadLanes.h"
 #include "llvm/CodeGen/DwarfEHPrepare.h"
+#include "llvm/CodeGen/EHContGuardTargets.h"
 #include "llvm/CodeGen/EarlyIfConversion.h"
 #include "llvm/CodeGen/EdgeBundles.h"
 #include "llvm/CodeGen/ExpandIRInsts.h"

diff  --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
index c51d5b6103c5d..bad3ce59bd4a1 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
@@ -930,7 +930,7 @@ void AArch64PassConfig::addPreEmitPass() {
     // Identify valid longjmp targets for Windows Control Flow Guard.
     addPass(createCFGuardLongjmpPass());
     // Identify valid eh continuation targets for Windows EHCont Guard.
-    addPass(createEHContGuardTargetsPass());
+    addPass(createEHContGuardTargetsLegacy());
   }
 
   if (TM->getOptLevel() != CodeGenOptLevel::None && EnableCollectLOH &&

diff  --git a/llvm/lib/Target/ARM/ARMTargetMachine.cpp b/llvm/lib/Target/ARM/ARMTargetMachine.cpp
index 4c5eda5705ea4..3c32b73a82ed7 100644
--- a/llvm/lib/Target/ARM/ARMTargetMachine.cpp
+++ b/llvm/lib/Target/ARM/ARMTargetMachine.cpp
@@ -618,7 +618,7 @@ void ARMPassConfig::addPreEmitPass2() {
     // Identify valid longjmp targets for Windows Control Flow Guard.
     addPass(createCFGuardLongjmpPass());
     // Identify valid eh continuation targets for Windows EHCont Guard.
-    addPass(createEHContGuardTargetsPass());
+    addPass(createEHContGuardTargetsLegacy());
   }
 }
 

diff  --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
index ca8a324ae590b..c05bd2ca7f3be 100644
--- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
@@ -17,6 +17,7 @@
 #include "llvm/CodeGen/AtomicExpand.h"
 #include "llvm/CodeGen/BreakFalseDeps.h"
 #include "llvm/CodeGen/CFIInstrInserter.h"
+#include "llvm/CodeGen/EHContGuardTargets.h"
 #include "llvm/CodeGen/EarlyIfConversion.h"
 #include "llvm/CodeGen/IndirectBrExpand.h"
 #include "llvm/CodeGen/InterleavedAccess.h"
@@ -239,8 +240,7 @@ void X86CodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) {
     // TODO(boomanaiden154): Add CFGuardLongjmpPass here when it has been
     // ported.
     // Identify valid eh continuation targets for Windows EHCont Guard.
-    // TODO(boomanaiden154): Add EHContGuardTargetsPass when it has been
-    // ported.
+    addMachineFunctionPass(EHContGuardTargetsPass(), PMW);
   }
 
   addMachineFunctionPass(X86LoadValueInjectionRetHardeningPass(), PMW);

diff  --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index 0559c51f3024f..886405a0c7bae 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -609,7 +609,7 @@ void X86PassConfig::addPreEmitPass2() {
     // Identify valid longjmp targets for Windows Control Flow Guard.
     addPass(createCFGuardLongjmpPass());
     // Identify valid eh continuation targets for Windows EHCont Guard.
-    addPass(createEHContGuardTargetsPass());
+    addPass(createEHContGuardTargetsLegacy());
   }
   addPass(createX86LoadValueInjectionRetHardeningLegacyPass());
 

diff  --git a/llvm/test/CodeGen/X86/ehcontguard.ll b/llvm/test/CodeGen/X86/ehcontguard.ll
index e868209babce6..6cd5d2e8935d3 100644
--- a/llvm/test/CodeGen/X86/ehcontguard.ll
+++ b/llvm/test/CodeGen/X86/ehcontguard.ll
@@ -1,4 +1,5 @@
 ; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s
+; RUN: llc -enable-new-pm < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s
 ; EHCont Guard is currently only available on Windows
 
 ; CHECK: @feat.00 = 16384

diff  --git a/llvm/test/CodeGen/X86/llc-pipeline-npm.ll b/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
index d0369d93d1710..52363d9844c00 100644
--- a/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
+++ b/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
@@ -275,6 +275,7 @@
 ; O0-WINDOWS-NEXT:     x86-seses
 ; O0-WINDOWS-NEXT:     x86-return-thunks
 ; O0-WINDOWS-NEXT:     x86-avoid-trailing-call
+; O0-WINDOWS-NEXT:     eh-cont-guard-targets
 ; O0-WINDOWS-NEXT:     x86-lvi-ret
 ; O0-WINDOWS-NEXT:     x86-wineh-unwindv2
 ; O0-WINDOWS-NEXT:     verify
@@ -404,6 +405,7 @@
 ; O3-WINDOWS-NEXT:     x86-seses
 ; O3-WINDOWS-NEXT:     x86-return-thunks
 ; O3-WINDOWS-NEXT:     x86-avoid-trailing-call
+; O3-WINDOWS-NEXT:     eh-cont-guard-targets
 ; O3-WINDOWS-NEXT:     x86-lvi-ret
 ; O3-WINDOWS-NEXT:     x86-wineh-unwindv2
 ; O3-WINDOWS-NEXT:     verify


        


More information about the llvm-commits mailing list