[llvm] llc: Verify MIR outputs by default (PR #228248)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 2 00:23:40 PDT 2026
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/228248
>From 5d811c1771d59f288f2b974aa01ea821119bed7a Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 1 Oct 2026 22:53:53 +0200
Subject: [PATCH 1/3] llc: Verify MIR outputs by default
MIR is validated by the machine verifier on read, but by default wasn't
validated on output. This differs from opt, which runs the verifier on
output unless explicitly disabled. -verify-machineinstrs is frequently used as
a much more expensive way of getting the verifier run, since that runs between
every pass.
Run the machine verifier at the end of the pipeline whenever it stops before code
emission. Add -disable-mir-output-verify to suppress this. It is separate from
-disable-verify, which still only controls verification of the IR input. The
extra verifier is skipped when the verifier already runs after every machine
pass, with -verify-machineinstrs in the legacy pass manager or -verify-each in
the new pass manager.
Some tests had to force disabling the verifier in a few tests which already fail
the verifier.
Unlike opt, the driver can't simply verify after the pass manager finishes.
MachineFunctions are freed as soon as they are printed. The verifier therefore
has to be added per function inside the pipeline, including the pipelines built
by addPassesToEmitFile and CodeGenPassBuilder for -stop-before/-stop-after.
Co-authored-by: Claude Opus 5.5 <noreply at anthropic.com>
---
llvm/include/llvm/CodeGen/TargetPassConfig.h | 5 ++
.../include/llvm/Target/CGPassBuilderOption.h | 1 +
llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp | 3 +
llvm/lib/CodeGen/TargetPassConfig.cpp | 18 +++--
llvm/lib/Passes/CodeGenPassBuilder.cpp | 5 +-
.../callbr-asm-outputs-indirect-isel-m32.ll | 2 +-
.../X86/callbr-asm-outputs-indirect-isel.ll | 2 +-
.../tools/llc/disable-mir-output-verify.mir | 74 +++++++++++++++++++
llvm/test/tools/llc/new-pm/start-stop.ll | 4 +-
llvm/tools/llc/lib/NewPMDriver.cpp | 4 +-
llvm/tools/llc/lib/llcdriver.cpp | 3 +
11 files changed, 108 insertions(+), 13 deletions(-)
create mode 100644 llvm/test/tools/llc/disable-mir-output-verify.mir
diff --git a/llvm/include/llvm/CodeGen/TargetPassConfig.h b/llvm/include/llvm/CodeGen/TargetPassConfig.h
index 92b3d4e04f928..6f3dc6c0aa644 100644
--- a/llvm/include/llvm/CodeGen/TargetPassConfig.h
+++ b/llvm/include/llvm/CodeGen/TargetPassConfig.h
@@ -127,6 +127,8 @@ class LLVM_ABI TargetPassConfig : public ImmutablePass {
// Targets provide a default setting, user flags override.
bool DisableVerify = false;
+ bool VerifyEachMachinePass = false;
+
/// Default setting for -enable-tail-merge on this target.
bool EnableTailMerge = true;
@@ -194,6 +196,9 @@ class LLVM_ABI TargetPassConfig : public ImmutablePass {
void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); }
+ /// Return true if the machine verifier runs after each machine pass.
+ bool verifiesEachMachinePass() const { return VerifyEachMachinePass; }
+
bool getEnableTailMerge() const { return EnableTailMerge; }
void setEnableTailMerge(bool Enable) { setOpt(EnableTailMerge, Enable); }
diff --git a/llvm/include/llvm/Target/CGPassBuilderOption.h b/llvm/include/llvm/Target/CGPassBuilderOption.h
index 62f1054384bb3..9e44412be1ec5 100644
--- a/llvm/include/llvm/Target/CGPassBuilderOption.h
+++ b/llvm/include/llvm/Target/CGPassBuilderOption.h
@@ -52,6 +52,7 @@ struct CGPassBuilderOption {
std::optional<bool> EnableIPRA;
bool DebugPM = false;
bool DisableVerify = false;
+ bool DisableMIROutputVerify = false;
bool EnableImplicitNullChecks = false;
bool EnableBlockPlacementStats = false;
bool EnableGlobalMergeFunc = false;
diff --git a/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp b/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp
index 0f6b627935e3b..ddb6c7f5eef2d 100644
--- a/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp
+++ b/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp
@@ -242,6 +242,9 @@ bool CodeGenTargetMachineImpl::addPassesToEmitFile(
if (addAsmPrinter(PM, Out, DwoOut, FileType, MMIWP->getMMI().getContext()))
return true;
} else {
+ if (!getCGPassBuilderOption().DisableMIROutputVerify &&
+ !PassConfig->verifiesEachMachinePass())
+ PM.add(createMachineVerifierPass("At end of pipeline"));
// MIR printing is redundant with -filetype=null.
if (FileType != CodeGenFileType::Null)
PM.add(createPrintMIRPass(Out));
diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp
index d7bb131c97256..be1276ac6e7e3 100644
--- a/llvm/lib/CodeGen/TargetPassConfig.cpp
+++ b/llvm/lib/CodeGen/TargetPassConfig.cpp
@@ -136,6 +136,10 @@ cl::opt<bool>
static cl::opt<cl::boolOrDefault>
VerifyMachineCode("verify-machineinstrs", cl::Hidden,
cl::desc("Verify generated machine code"));
+static cl::opt<bool> DisableMIROutputVerify(
+ "disable-mir-output-verify", cl::Hidden,
+ cl::desc("Do not verify machine code at the end of a pipeline that stops "
+ "before code emission"));
static cl::opt<cl::boolOrDefault>
DebugifyAndStripAll("debugify-and-strip-all-safe", cl::Hidden,
cl::desc("Debugify MIR before and Strip debug after "
@@ -518,6 +522,7 @@ CGPassBuilderOption llvm::getCGPassBuilderOption() {
SET_OPTION(EnableFastISelOption)
SET_OPTION(EnableGlobalISelOption)
SET_OPTION(VerifyMachineCode)
+ SET_OPTION(DisableMIROutputVerify)
SET_OPTION(DisableAtExitBasedGlobalDtorLowering)
SET_OPTION(DisableExpandReductions)
SET_OPTION(PrintAfterISel)
@@ -636,6 +641,12 @@ TargetPassConfig::TargetPassConfig(TargetMachine &TM, PassManagerBase &PM)
if (EnableGlobalISelAbort.getNumOccurrences())
TM.Options.GlobalISelAbort = EnableGlobalISelAbort;
+ VerifyEachMachinePass = VerifyMachineCode == cl::boolOrDefault::BOU_TRUE;
+#ifdef EXPENSIVE_CHECKS
+ if (VerifyMachineCode == cl::boolOrDefault::BOU_UNSET)
+ VerifyEachMachinePass = TM.isMachineVerifierClean();
+#endif
+
setStartStopPasses();
}
@@ -807,12 +818,7 @@ void TargetPassConfig::addPrintPass(const std::string &Banner) {
}
void TargetPassConfig::addVerifyPass(const std::string &Banner) {
- bool Verify = VerifyMachineCode == cl::boolOrDefault::BOU_TRUE;
-#ifdef EXPENSIVE_CHECKS
- if (VerifyMachineCode == cl::boolOrDefault::BOU_UNSET)
- Verify = TM->isMachineVerifierClean();
-#endif
- if (Verify)
+ if (VerifyEachMachinePass)
PM->add(createMachineVerifierPass(Banner));
}
diff --git a/llvm/lib/Passes/CodeGenPassBuilder.cpp b/llvm/lib/Passes/CodeGenPassBuilder.cpp
index d5418c54b6ac4..7a8d1dfe8d38e 100644
--- a/llvm/lib/Passes/CodeGenPassBuilder.cpp
+++ b/llvm/lib/Passes/CodeGenPassBuilder.cpp
@@ -270,8 +270,9 @@ Error CodeGenPassBuilder::buildPipeline(
if (auto Err = addMachinePasses(PMW))
return Err;
- if (!Opt.DisableVerify && TM.Options.EnableDefaultMachineVerifier)
- addMachineFunctionPass(MachineVerifierPass(), PMW);
+ if (!PrintAsm ? !Opt.DisableMIROutputVerify
+ : !Opt.DisableVerify && TM.Options.EnableDefaultMachineVerifier)
+ addMachineFunctionPass(MachineVerifierPass(), PMW, /*Force=*/!PrintAsm);
// We add AsmPrinter regardless if we are emitting MIR or Assembly as the
// final output so that -stop-before=<target>-asm-printer works. When printing
diff --git a/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel-m32.ll b/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel-m32.ll
index 2a57f046927e9..125661a314d85 100644
--- a/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel-m32.ll
+++ b/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel-m32.ll
@@ -2,7 +2,7 @@
; FIXME(ndesaulniers): get this test to pass with -verify-machineinstrs
; enabled. https://github.com/llvm/llvm-project/issues/60827
; RUN: llc -mtriple=i386-linux-gnu %s -o - -stop-after=finalize-isel \
-; RUN: -verify-machineinstrs=0 -start-before=x86-isel | FileCheck %s
+; RUN: -verify-machineinstrs=0 -disable-mir-output-verify -start-before=x86-isel | FileCheck %s
define i8 @emulator_cmpxchg_emulated() {
; CHECK-LABEL: name: emulator_cmpxchg_emulated
diff --git a/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel.ll b/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel.ll
index 25e44cb0d9b5f..833f7a9c62f1e 100644
--- a/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel.ll
+++ b/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel.ll
@@ -2,7 +2,7 @@
; FIXME(ndesaulniers): get this test to pass with -verify-machineinstrs
; enabled. https://github.com/llvm/llvm-project/issues/60827
; RUN: llc -mtriple=x86_64-linux-gnu %s -o - -stop-after=finalize-isel \
-; RUN: -verify-machineinstrs=0 -start-before=x86-isel | FileCheck %s
+; RUN: -verify-machineinstrs=0 -disable-mir-output-verify -start-before=x86-isel | FileCheck %s
; One virtual register, w/o phi
define i32 @test0() {
diff --git a/llvm/test/tools/llc/disable-mir-output-verify.mir b/llvm/test/tools/llc/disable-mir-output-verify.mir
new file mode 100644
index 0000000000000..51daddcad3295
--- /dev/null
+++ b/llvm/test/tools/llc/disable-mir-output-verify.mir
@@ -0,0 +1,74 @@
+# Check that the machine verifier runs at the end of a pipeline that stops
+# before code emission, and that -disable-mir-output-verify suppresses it.
+
+# RUN: llc -mtriple=x86_64-pc-linux-gnu -run-pass=none -debug-pass=Structure -filetype=null %s 2>&1 | FileCheck --check-prefix=RUN-PASS %s
+# RUN: llc -mtriple=x86_64-pc-linux-gnu -run-pass=none -debug-pass=Structure -filetype=null -disable-mir-output-verify %s 2>&1 | FileCheck --check-prefix=RUN-PASS-NOVERIFY %s
+# RUN: llc -mtriple=x86_64-pc-linux-gnu -run-pass=none -debug-pass=Structure -filetype=null -disable-verify %s 2>&1 | FileCheck --check-prefix=RUN-PASS %s
+
+# RUN: llc -mtriple=x86_64-pc-linux-gnu -start-before=machine-cp -stop-after=machine-cp -enable-new-pm=false -debug-pass=Structure -filetype=null %s 2>&1 | FileCheck --check-prefix=LEGACY-STOP %s
+# RUN: llc -mtriple=x86_64-pc-linux-gnu -start-before=machine-cp -stop-after=machine-cp -enable-new-pm=false -debug-pass=Structure -filetype=null -disable-mir-output-verify %s 2>&1 | FileCheck --check-prefix=LEGACY-STOP-NOVERIFY %s
+
+# RUN: llc -mtriple=x86_64-pc-linux-gnu -passes=no-op-machine-function -print-pipeline-passes %s | FileCheck --check-prefix=NPM-PASSES %s
+# RUN: llc -mtriple=x86_64-pc-linux-gnu -passes=no-op-machine-function -print-pipeline-passes -disable-mir-output-verify %s | FileCheck --check-prefix=NPM-PASSES-NOVERIFY %s
+
+# RUN: llc -mtriple=x86_64-pc-linux-gnu -start-before=machine-cp -stop-after=machine-cp -enable-new-pm -print-pipeline-passes -filetype=null %s | FileCheck --check-prefix=NPM-STOP %s
+# RUN: llc -mtriple=x86_64-pc-linux-gnu -start-before=machine-cp -stop-after=machine-cp -enable-new-pm -print-pipeline-passes -filetype=null -disable-mir-output-verify %s | FileCheck --check-prefix=NPM-STOP-NOVERIFY %s
+
+# No extra verifier when one already runs after each pass.
+# RUN: llc -mtriple=x86_64-pc-linux-gnu -run-pass=machine-cp -debug-pass=Structure -filetype=null -verify-machineinstrs %s 2>&1 | FileCheck --check-prefix=RUN-PASS-VERIFY-EACH %s
+# RUN: llc -mtriple=x86_64-pc-linux-gnu -start-before=machine-cp -stop-after=machine-cp -enable-new-pm=false -debug-pass=Structure -filetype=null -verify-machineinstrs %s 2>&1 | FileCheck --check-prefix=LEGACY-STOP-VERIFY-EACH %s
+# RUN: llc -mtriple=x86_64-pc-linux-gnu -passes=no-op-machine-function -print-pipeline-passes -verify-each %s | FileCheck --check-prefix=NPM-PASSES-NOVERIFY %s
+# RUN: llc -mtriple=x86_64-pc-linux-gnu -start-before=machine-cp -stop-after=machine-cp -enable-new-pm -print-pipeline-passes -filetype=null -verify-each %s | FileCheck --check-prefix=NPM-STOP-NOVERIFY %s
+
+# RUN-PASS: FunctionPass Manager
+# RUN-PASS-NEXT: Verify generated machine code
+# RUN-PASS-NEXT: MIR Printing Pass
+# RUN-PASS-NEXT: Free MachineFunction
+
+# RUN-PASS-NOVERIFY: FunctionPass Manager
+# RUN-PASS-NOVERIFY-NEXT: MIR Printing Pass
+# RUN-PASS-NOVERIFY-NEXT: Free MachineFunction
+
+# RUN-PASS-VERIFY-EACH: FunctionPass Manager
+# RUN-PASS-VERIFY-EACH-NEXT: Verify generated machine code
+# RUN-PASS-VERIFY-EACH-NEXT: Machine Copy Propagation Pass
+# RUN-PASS-VERIFY-EACH-NEXT: Verify generated machine code
+# RUN-PASS-VERIFY-EACH-NEXT: MIR Printing Pass
+# RUN-PASS-VERIFY-EACH-NEXT: Free MachineFunction
+
+# LEGACY-STOP: FunctionPass Manager
+# LEGACY-STOP-NEXT: Machine Copy Propagation Pass
+# LEGACY-STOP-NEXT: Lazy Machine Block Frequency Analysis
+# LEGACY-STOP-NEXT: Machine Optimization Remark Emitter
+# LEGACY-STOP-NEXT: Stack Frame Layout Analysis
+# LEGACY-STOP-NEXT: Verify generated machine code
+# LEGACY-STOP-NEXT: Free MachineFunction
+
+# LEGACY-STOP-NOVERIFY: FunctionPass Manager
+# LEGACY-STOP-NOVERIFY-NEXT: Machine Copy Propagation Pass
+# LEGACY-STOP-NOVERIFY-NEXT: Lazy Machine Block Frequency Analysis
+# LEGACY-STOP-NOVERIFY-NEXT: Machine Optimization Remark Emitter
+# LEGACY-STOP-NOVERIFY-NEXT: Stack Frame Layout Analysis
+# LEGACY-STOP-NOVERIFY-NEXT: Free MachineFunction
+
+# LEGACY-STOP-VERIFY-EACH: FunctionPass Manager
+# LEGACY-STOP-VERIFY-EACH-NEXT: Verify generated machine code
+# LEGACY-STOP-VERIFY-EACH-NEXT: Machine Copy Propagation Pass
+# LEGACY-STOP-VERIFY-EACH-NEXT: Verify generated machine code
+# LEGACY-STOP-VERIFY-EACH-NEXT: Lazy Machine Block Frequency Analysis
+# LEGACY-STOP-VERIFY-EACH-NEXT: Machine Optimization Remark Emitter
+# LEGACY-STOP-VERIFY-EACH-NEXT: Stack Frame Layout Analysis
+# LEGACY-STOP-VERIFY-EACH-NEXT: Free MachineFunction
+
+# NPM-PASSES: PrintMIRPreparePass,function(machine-function(verify,print))
+# NPM-PASSES-NOVERIFY: PrintMIRPreparePass,function(machine-function(print))
+
+# NPM-STOP: function(machine-function(machine-cp,verify),free-machine-function)
+# NPM-STOP-NOVERIFY: function(machine-function(machine-cp),free-machine-function)
+
+---
+name: f
+body: |
+ bb.0:
+ RET 0
+...
diff --git a/llvm/test/tools/llc/new-pm/start-stop.ll b/llvm/test/tools/llc/new-pm/start-stop.ll
index 829432238d626..f7dd9fe164066 100644
--- a/llvm/test/tools/llc/new-pm/start-stop.ll
+++ b/llvm/test/tools/llc/new-pm/start-stop.ll
@@ -1,5 +1,5 @@
; RUN: llc -mtriple=x86_64-pc-linux-gnu -enable-new-pm -print-pipeline-passes -start-before=gc-lowering -stop-after=gc-lowering -filetype=null %s | FileCheck --match-full-lines %s --check-prefix=NULL
; RUN: llc -mtriple=x86_64-pc-linux-gnu -enable-new-pm -print-pipeline-passes -start-before=gc-lowering -stop-after=gc-lowering -o /dev/null %s | FileCheck --match-full-lines %s --check-prefix=OBJ
-; NULL: require<MachineModuleAnalysis>,require<profile-summary>,require<collector-metadata>,require<runtime-libcall-info>,require<libcall-lowering-info>,function(verify,gc-lowering,verify)
-; OBJ: require<MachineModuleAnalysis>,require<profile-summary>,require<collector-metadata>,require<runtime-libcall-info>,require<libcall-lowering-info>,function(verify,gc-lowering,verify),PrintMIRPreparePass,function(machine-function(print),free-machine-function)
+; NULL: require<MachineModuleAnalysis>,require<profile-summary>,require<collector-metadata>,require<runtime-libcall-info>,require<libcall-lowering-info>,function(verify,gc-lowering,verify),function(machine-function(verify),free-machine-function)
+; OBJ: require<MachineModuleAnalysis>,require<profile-summary>,require<collector-metadata>,require<runtime-libcall-info>,require<libcall-lowering-info>,function(verify,gc-lowering,verify),PrintMIRPreparePass,function(machine-function(verify,print),free-machine-function)
diff --git a/llvm/tools/llc/lib/NewPMDriver.cpp b/llvm/tools/llc/lib/NewPMDriver.cpp
index 3eac9bd15355e..410e13255da3e 100644
--- a/llvm/tools/llc/lib/NewPMDriver.cpp
+++ b/llvm/tools/llc/lib/NewPMDriver.cpp
@@ -115,6 +115,8 @@ int llvm::compileModuleWithNewPM(
// Fetch options from TargetPassConfig
CGPassBuilderOption Opt = getCGPassBuilderOption();
Opt.DisableVerify = VK != VerifierKind::InputOutput;
+ if (VK == VerifierKind::EachPass)
+ Opt.DisableMIROutputVerify = true;
Opt.DebugPM = DebugPM;
Opt.RegAlloc = RegAlloc;
@@ -169,7 +171,7 @@ int llvm::compileModuleWithNewPM(
ExitOnErr(PB.parsePassPipeline(MPM, PassPipeline));
MPM.addPass(PrintMIRPreparePass(*OS));
MachineFunctionPassManager MFPM;
- if (VK == VerifierKind::InputOutput)
+ if (!Opt.DisableMIROutputVerify)
MFPM.addPass(MachineVerifierPass());
MFPM.addPass(PrintMIRPass(*OS));
FPM.addPass(createFunctionToMachineFunctionPassAdaptor(std::move(MFPM)));
diff --git a/llvm/tools/llc/lib/llcdriver.cpp b/llvm/tools/llc/lib/llcdriver.cpp
index 68dab490712e3..fa300db81c50e 100644
--- a/llvm/tools/llc/lib/llcdriver.cpp
+++ b/llvm/tools/llc/lib/llcdriver.cpp
@@ -826,6 +826,9 @@ static int compileModule(char **argv, SmallVectorImpl<PassPlugin> &PluginList,
return 1;
}
TPC.setInitialized();
+ if (!getCGPassBuilderOption().DisableMIROutputVerify &&
+ !TPC.verifiesEachMachinePass())
+ PM.add(createMachineVerifierPass("At end of pipeline"));
PM.add(createPrintMIRPass(*OS));
// Add MIR2Vec vocabulary printer if requested
>From c69706d1378531368e7b30040975bfe7a0538dca Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Fri, 2 Oct 2026 00:17:13 +0200
Subject: [PATCH 2/3] Use unnegated PrintAsm for the verifier condition
---
llvm/lib/Passes/CodeGenPassBuilder.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Passes/CodeGenPassBuilder.cpp b/llvm/lib/Passes/CodeGenPassBuilder.cpp
index 7a8d1dfe8d38e..82642c802dd48 100644
--- a/llvm/lib/Passes/CodeGenPassBuilder.cpp
+++ b/llvm/lib/Passes/CodeGenPassBuilder.cpp
@@ -270,8 +270,8 @@ Error CodeGenPassBuilder::buildPipeline(
if (auto Err = addMachinePasses(PMW))
return Err;
- if (!PrintAsm ? !Opt.DisableMIROutputVerify
- : !Opt.DisableVerify && TM.Options.EnableDefaultMachineVerifier)
+ if (PrintAsm ? !Opt.DisableVerify && TM.Options.EnableDefaultMachineVerifier
+ : !Opt.DisableMIROutputVerify)
addMachineFunctionPass(MachineVerifierPass(), PMW, /*Force=*/!PrintAsm);
// We add AsmPrinter regardless if we are emitting MIR or Assembly as the
>From 1d034aa3cb8379bf72f11bfa9bc2c41bcabb1900 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Fri, 2 Oct 2026 09:18:55 +0200
Subject: [PATCH 3/3] Replace the machine verify bools with a
MachineVerifierMode enum
---
llvm/include/llvm/CodeGen/TargetPassConfig.h | 6 +++---
llvm/include/llvm/Support/CodeGen.h | 10 ++++++++++
.../include/llvm/Target/CGPassBuilderOption.h | 4 ++--
llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp | 3 +--
llvm/lib/CodeGen/TargetPassConfig.cpp | 20 ++++++++++++++-----
llvm/lib/Passes/CodeGenPassBuilder.cpp | 2 +-
llvm/tools/llc/lib/NewPMDriver.cpp | 4 ++--
llvm/tools/llc/lib/llcdriver.cpp | 3 +--
8 files changed, 35 insertions(+), 17 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/TargetPassConfig.h b/llvm/include/llvm/CodeGen/TargetPassConfig.h
index 6f3dc6c0aa644..8f1e4eb899284 100644
--- a/llvm/include/llvm/CodeGen/TargetPassConfig.h
+++ b/llvm/include/llvm/CodeGen/TargetPassConfig.h
@@ -127,7 +127,7 @@ class LLVM_ABI TargetPassConfig : public ImmutablePass {
// Targets provide a default setting, user flags override.
bool DisableVerify = false;
- bool VerifyEachMachinePass = false;
+ MachineVerifierMode VerifyMode = MachineVerifierMode::End;
/// Default setting for -enable-tail-merge on this target.
bool EnableTailMerge = true;
@@ -196,8 +196,8 @@ class LLVM_ABI TargetPassConfig : public ImmutablePass {
void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); }
- /// Return true if the machine verifier runs after each machine pass.
- bool verifiesEachMachinePass() const { return VerifyEachMachinePass; }
+ /// Return where the machine verifier runs in the pipeline.
+ MachineVerifierMode getMachineVerifierMode() const { return VerifyMode; }
bool getEnableTailMerge() const { return EnableTailMerge; }
void setEnableTailMerge(bool Enable) { setOpt(EnableTailMerge, Enable); }
diff --git a/llvm/include/llvm/Support/CodeGen.h b/llvm/include/llvm/Support/CodeGen.h
index 210c2a023b30c..08af0864eec4f 100644
--- a/llvm/include/llvm/Support/CodeGen.h
+++ b/llvm/include/llvm/Support/CodeGen.h
@@ -259,6 +259,16 @@ namespace llvm {
Null // Do not emit any output.
};
+ /// Specify where the machine verifier runs in the codegen pipeline.
+ enum class MachineVerifierMode {
+ /// Never run the machine verifier.
+ None,
+ /// Run the machine verifier once, at the end of the pipeline.
+ End,
+ /// Run the machine verifier before and after every machine pass.
+ Each
+ };
+
// Specify what functions should keep the frame pointer.
enum class FramePointerKind {
None,
diff --git a/llvm/include/llvm/Target/CGPassBuilderOption.h b/llvm/include/llvm/Target/CGPassBuilderOption.h
index 9e44412be1ec5..85bc434eea0e7 100644
--- a/llvm/include/llvm/Target/CGPassBuilderOption.h
+++ b/llvm/include/llvm/Target/CGPassBuilderOption.h
@@ -52,7 +52,6 @@ struct CGPassBuilderOption {
std::optional<bool> EnableIPRA;
bool DebugPM = false;
bool DisableVerify = false;
- bool DisableMIROutputVerify = false;
bool EnableImplicitNullChecks = false;
bool EnableBlockPlacementStats = false;
bool EnableGlobalMergeFunc = false;
@@ -84,7 +83,8 @@ struct CGPassBuilderOption {
std::string FSProfileFile;
std::string FSRemappingFile;
- cl::boolOrDefault VerifyMachineCode = cl::boolOrDefault::BOU_UNSET;
+ MachineVerifierMode VerifyMachineCode = MachineVerifierMode::End;
+
cl::boolOrDefault EnableFastISelOption = cl::boolOrDefault::BOU_UNSET;
cl::boolOrDefault EnableGlobalISelOption = cl::boolOrDefault::BOU_UNSET;
cl::boolOrDefault DebugifyAndStripAll = cl::boolOrDefault::BOU_UNSET;
diff --git a/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp b/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp
index ddb6c7f5eef2d..d121d5235f9d8 100644
--- a/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp
+++ b/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp
@@ -242,8 +242,7 @@ bool CodeGenTargetMachineImpl::addPassesToEmitFile(
if (addAsmPrinter(PM, Out, DwoOut, FileType, MMIWP->getMMI().getContext()))
return true;
} else {
- if (!getCGPassBuilderOption().DisableMIROutputVerify &&
- !PassConfig->verifiesEachMachinePass())
+ if (PassConfig->getMachineVerifierMode() == MachineVerifierMode::End)
PM.add(createMachineVerifierPass("At end of pipeline"));
// MIR printing is redundant with -filetype=null.
if (FileType != CodeGenFileType::Null)
diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp
index be1276ac6e7e3..b9e2ef4b3cc1b 100644
--- a/llvm/lib/CodeGen/TargetPassConfig.cpp
+++ b/llvm/lib/CodeGen/TargetPassConfig.cpp
@@ -140,6 +140,14 @@ static cl::opt<bool> DisableMIROutputVerify(
"disable-mir-output-verify", cl::Hidden,
cl::desc("Do not verify machine code at the end of a pipeline that stops "
"before code emission"));
+
+static MachineVerifierMode computeMachineVerifierMode(bool VerifyEach) {
+ if (VerifyEach)
+ return MachineVerifierMode::Each;
+ return DisableMIROutputVerify ? MachineVerifierMode::None
+ : MachineVerifierMode::End;
+}
+
static cl::opt<cl::boolOrDefault>
DebugifyAndStripAll("debugify-and-strip-all-safe", cl::Hidden,
cl::desc("Debugify MIR before and Strip debug after "
@@ -521,8 +529,6 @@ CGPassBuilderOption llvm::getCGPassBuilderOption() {
SET_OPTION(EnableFastISelOption)
SET_OPTION(EnableGlobalISelOption)
- SET_OPTION(VerifyMachineCode)
- SET_OPTION(DisableMIROutputVerify)
SET_OPTION(DisableAtExitBasedGlobalDtorLowering)
SET_OPTION(DisableExpandReductions)
SET_OPTION(PrintAfterISel)
@@ -546,6 +552,9 @@ CGPassBuilderOption llvm::getCGPassBuilderOption() {
SET_OPTION(DisableCFIFixup)
SET_OPTION(EnableMachineFunctionSplitter)
+ Opt.VerifyMachineCode = computeMachineVerifierMode(
+ VerifyMachineCode == cl::boolOrDefault::BOU_TRUE);
+
return Opt;
}
@@ -641,11 +650,12 @@ TargetPassConfig::TargetPassConfig(TargetMachine &TM, PassManagerBase &PM)
if (EnableGlobalISelAbort.getNumOccurrences())
TM.Options.GlobalISelAbort = EnableGlobalISelAbort;
- VerifyEachMachinePass = VerifyMachineCode == cl::boolOrDefault::BOU_TRUE;
+ bool VerifyEach = VerifyMachineCode == cl::boolOrDefault::BOU_TRUE;
#ifdef EXPENSIVE_CHECKS
if (VerifyMachineCode == cl::boolOrDefault::BOU_UNSET)
- VerifyEachMachinePass = TM.isMachineVerifierClean();
+ VerifyEach = TM.isMachineVerifierClean();
#endif
+ VerifyMode = computeMachineVerifierMode(VerifyEach);
setStartStopPasses();
}
@@ -818,7 +828,7 @@ void TargetPassConfig::addPrintPass(const std::string &Banner) {
}
void TargetPassConfig::addVerifyPass(const std::string &Banner) {
- if (VerifyEachMachinePass)
+ if (VerifyMode == MachineVerifierMode::Each)
PM->add(createMachineVerifierPass(Banner));
}
diff --git a/llvm/lib/Passes/CodeGenPassBuilder.cpp b/llvm/lib/Passes/CodeGenPassBuilder.cpp
index 82642c802dd48..0e37c17c07294 100644
--- a/llvm/lib/Passes/CodeGenPassBuilder.cpp
+++ b/llvm/lib/Passes/CodeGenPassBuilder.cpp
@@ -271,7 +271,7 @@ Error CodeGenPassBuilder::buildPipeline(
return Err;
if (PrintAsm ? !Opt.DisableVerify && TM.Options.EnableDefaultMachineVerifier
- : !Opt.DisableMIROutputVerify)
+ : Opt.VerifyMachineCode == MachineVerifierMode::End)
addMachineFunctionPass(MachineVerifierPass(), PMW, /*Force=*/!PrintAsm);
// We add AsmPrinter regardless if we are emitting MIR or Assembly as the
diff --git a/llvm/tools/llc/lib/NewPMDriver.cpp b/llvm/tools/llc/lib/NewPMDriver.cpp
index 410e13255da3e..0bf67c9f80f1c 100644
--- a/llvm/tools/llc/lib/NewPMDriver.cpp
+++ b/llvm/tools/llc/lib/NewPMDriver.cpp
@@ -116,7 +116,7 @@ int llvm::compileModuleWithNewPM(
CGPassBuilderOption Opt = getCGPassBuilderOption();
Opt.DisableVerify = VK != VerifierKind::InputOutput;
if (VK == VerifierKind::EachPass)
- Opt.DisableMIROutputVerify = true;
+ Opt.VerifyMachineCode = MachineVerifierMode::Each;
Opt.DebugPM = DebugPM;
Opt.RegAlloc = RegAlloc;
@@ -171,7 +171,7 @@ int llvm::compileModuleWithNewPM(
ExitOnErr(PB.parsePassPipeline(MPM, PassPipeline));
MPM.addPass(PrintMIRPreparePass(*OS));
MachineFunctionPassManager MFPM;
- if (!Opt.DisableMIROutputVerify)
+ if (Opt.VerifyMachineCode == MachineVerifierMode::End)
MFPM.addPass(MachineVerifierPass());
MFPM.addPass(PrintMIRPass(*OS));
FPM.addPass(createFunctionToMachineFunctionPassAdaptor(std::move(MFPM)));
diff --git a/llvm/tools/llc/lib/llcdriver.cpp b/llvm/tools/llc/lib/llcdriver.cpp
index fa300db81c50e..3391f55025076 100644
--- a/llvm/tools/llc/lib/llcdriver.cpp
+++ b/llvm/tools/llc/lib/llcdriver.cpp
@@ -826,8 +826,7 @@ static int compileModule(char **argv, SmallVectorImpl<PassPlugin> &PluginList,
return 1;
}
TPC.setInitialized();
- if (!getCGPassBuilderOption().DisableMIROutputVerify &&
- !TPC.verifiesEachMachinePass())
+ if (TPC.getMachineVerifierMode() == MachineVerifierMode::End)
PM.add(createMachineVerifierPass("At end of pipeline"));
PM.add(createPrintMIRPass(*OS));
More information about the llvm-commits
mailing list