[Mlir-commits] [mlir] [mlir] Add comment for failed verification in print. (PR #161789)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Thu Oct 2 23:21:24 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir

Author: Jacques Pienaar (jpienaar)

<details>
<summary>Changes</summary>

While we have debug output explaining verification failure, many users are confused when they first encounter this/most folks don't run with --debug. Move the checking such that we can emit a comment explaining why/make it more discoverable and so avoid confusion in new users.

---
Full diff: https://github.com/llvm/llvm-project/pull/161789.diff


2 Files Affected:

- (modified) mlir/lib/IR/AsmPrinter.cpp (+50-35) 
- (added) mlir/test/IR/invalid-warning-comment.mlir (+4) 


``````````diff
diff --git a/mlir/lib/IR/AsmPrinter.cpp b/mlir/lib/IR/AsmPrinter.cpp
index 3d19c5ad8fbca..7e49bfc9da64d 100644
--- a/mlir/lib/IR/AsmPrinter.cpp
+++ b/mlir/lib/IR/AsmPrinter.cpp
@@ -1941,12 +1941,43 @@ void FallbackAsmResourceMap::ResourceCollection::buildResources(
 
 namespace mlir {
 namespace detail {
+
+/// Verifies the operation and switches to generic op printing if verification
+/// fails. We need to do this because custom print functions may fail/crash for
+/// invalid ops.
+static void verifyOpAndAdjustFlags(Operation *op, OpPrintingFlags &printerFlags,
+                                   bool &failedVerification) {
+  if (printerFlags.shouldPrintGenericOpForm() ||
+      printerFlags.shouldAssumeVerified())
+    return;
+
+  // Ignore errors emitted by the verifier. We check the thread id to avoid
+  // consuming other threads' errors.
+  auto parentThreadId = llvm::get_threadid();
+  ScopedDiagnosticHandler diagHandler(op->getContext(), [&](Diagnostic &diag) {
+    if (parentThreadId == llvm::get_threadid()) {
+      LLVM_DEBUG({
+        diag.print(llvm::dbgs());
+        llvm::dbgs() << "\n";
+      });
+      return success();
+    }
+    return failure();
+  });
+  if (failed(verify(op))) {
+    printerFlags.printGenericOpForm();
+    failedVerification = true;
+  }
+}
+
 class AsmStateImpl {
 public:
   explicit AsmStateImpl(Operation *op, const OpPrintingFlags &printerFlags,
                         AsmState::LocationMap *locationMap)
       : interfaces(op->getContext()), nameState(op, printerFlags),
-        printerFlags(printerFlags), locationMap(locationMap) {}
+        printerFlags(printerFlags), locationMap(locationMap) {
+    verifyOpAndAdjustFlags(op, this->printerFlags, failedVerification);
+  }
   explicit AsmStateImpl(MLIRContext *ctx, const OpPrintingFlags &printerFlags,
                         AsmState::LocationMap *locationMap)
       : interfaces(ctx), printerFlags(printerFlags), locationMap(locationMap) {}
@@ -1998,6 +2029,8 @@ class AsmStateImpl {
 
   void popCyclicPrinting() { cyclicPrintingStack.pop_back(); }
 
+  bool verificationFailed() const { return failedVerification; }
+
 private:
   /// Collection of OpAsm interfaces implemented in the context.
   DialectInterfaceCollection<OpAsmDialectInterface> interfaces;
@@ -2020,6 +2053,10 @@ class AsmStateImpl {
   /// Flags that control op output.
   OpPrintingFlags printerFlags;
 
+  /// Whether the operation from which the AsmState was created, failed
+  /// verification.
+  bool failedVerification = false;
+
   /// An optional location map to be populated.
   AsmState::LocationMap *locationMap;
 
@@ -2047,41 +2084,9 @@ void printDimensionList(raw_ostream &stream, Range &&shape) {
 } // namespace detail
 } // namespace mlir
 
-/// Verifies the operation and switches to generic op printing if verification
-/// fails. We need to do this because custom print functions may fail for
-/// invalid ops.
-static OpPrintingFlags verifyOpAndAdjustFlags(Operation *op,
-                                              OpPrintingFlags printerFlags) {
-  if (printerFlags.shouldPrintGenericOpForm() ||
-      printerFlags.shouldAssumeVerified())
-    return printerFlags;
-
-  // Ignore errors emitted by the verifier. We check the thread id to avoid
-  // consuming other threads' errors.
-  auto parentThreadId = llvm::get_threadid();
-  ScopedDiagnosticHandler diagHandler(op->getContext(), [&](Diagnostic &diag) {
-    if (parentThreadId == llvm::get_threadid()) {
-      LLVM_DEBUG({
-        diag.print(llvm::dbgs());
-        llvm::dbgs() << "\n";
-      });
-      return success();
-    }
-    return failure();
-  });
-  if (failed(verify(op))) {
-    LDBG() << op->getName()
-           << "' failed to verify and will be printed in generic form";
-    printerFlags.printGenericOpForm();
-  }
-
-  return printerFlags;
-}
-
 AsmState::AsmState(Operation *op, const OpPrintingFlags &printerFlags,
                    LocationMap *locationMap, FallbackAsmResourceMap *map)
-    : impl(std::make_unique<AsmStateImpl>(
-          op, verifyOpAndAdjustFlags(op, printerFlags), locationMap)) {
+    : impl(std::make_unique<AsmStateImpl>(op, printerFlags, locationMap)) {
   if (map)
     attachFallbackResourcePrinter(*map);
 }
@@ -3245,7 +3250,8 @@ class OperationPrinter : public AsmPrinter::Impl, private OpAsmPrinter {
   using Impl::printType;
 
   explicit OperationPrinter(raw_ostream &os, AsmStateImpl &state)
-      : Impl(os, state), OpAsmPrinter(static_cast<Impl &>(*this)) {}
+      : Impl(os, state), OpAsmPrinter(static_cast<Impl &>(*this)),
+        verificationFailed(state.verificationFailed()) {}
 
   /// Print the given top-level operation.
   void printTopLevelOperation(Operation *op);
@@ -3433,10 +3439,19 @@ class OperationPrinter : public AsmPrinter::Impl, private OpAsmPrinter {
 
   // This is the current indentation level for nested structures.
   unsigned currentIndent = 0;
+
+  /// Whether the operation from which the AsmState was created, failed
+  /// verification.
+  bool verificationFailed = false;
 };
 } // namespace
 
 void OperationPrinter::printTopLevelOperation(Operation *op) {
+  if (verificationFailed) {
+    os << "// '" << op->getName()
+       << "' failed to verify and will be printed in generic form\n";
+  }
+
   // Output the aliases at the top level that can't be deferred.
   state.getAliasState().printNonDeferredAliases(*this, newLine);
 
diff --git a/mlir/test/IR/invalid-warning-comment.mlir b/mlir/test/IR/invalid-warning-comment.mlir
new file mode 100644
index 0000000000000..08ace2f8139e4
--- /dev/null
+++ b/mlir/test/IR/invalid-warning-comment.mlir
@@ -0,0 +1,4 @@
+// RUN: mlir-opt --mlir-very-unsafe-disable-verifier-on-parsing %s | FileCheck %s
+
+// CHECK: // 'builtin.module' failed to verify and will be printed in generic form
+func.func @foo() -> tensor<10xi32> { return }

``````````

</details>


https://github.com/llvm/llvm-project/pull/161789


More information about the Mlir-commits mailing list