[Mlir-commits] [mlir] [mlir] implement `-verify-diagnostics=only-expected` (PR #135131)

Maksim Levental llvmlistbot at llvm.org
Thu Apr 10 11:34:36 PDT 2025


https://github.com/makslevental updated https://github.com/llvm/llvm-project/pull/135131

>From 09671dccdf6221164c843c7f736c7815f9fadec1 Mon Sep 17 00:00:00 2001
From: Maksim Levental <maksim.levental at gmail.com>
Date: Thu, 10 Apr 2025 01:27:16 -0400
Subject: [PATCH 1/5] [mlir] implement verify-only-specified-diagnostics

---
 .../transform-opt/mlir-transform-opt.cpp      | 27 ++++++++++++++-----
 mlir/include/mlir/IR/Diagnostics.h            | 13 ++++++---
 .../include/mlir/Tools/mlir-opt/MlirOptMain.h | 13 +++++++++
 mlir/lib/IR/Diagnostics.cpp                   | 15 ++++++++---
 mlir/lib/Tools/mlir-opt/MlirOptMain.cpp       | 11 +++++++-
 .../mlir-translate/MlirTranslateMain.cpp      | 14 +++++++---
 6 files changed, 76 insertions(+), 17 deletions(-)

diff --git a/mlir/examples/transform-opt/mlir-transform-opt.cpp b/mlir/examples/transform-opt/mlir-transform-opt.cpp
index 10e16096211ad..c7fe30b7963b6 100644
--- a/mlir/examples/transform-opt/mlir-transform-opt.cpp
+++ b/mlir/examples/transform-opt/mlir-transform-opt.cpp
@@ -43,6 +43,12 @@ struct MlirTransformOptCLOptions {
       cl::desc("Check that emitted diagnostics match expected-* lines "
                "on the corresponding line"),
       cl::init(false)};
+  cl::opt<bool> verifyOnlyExpectedDiagnostics{
+      "verify-only-expected-diagnostics",
+      cl::desc("Check that emitted diagnostics match only specified expected-* "
+               "lines "
+               "on the corresponding line"),
+      cl::init(false)};
 
   cl::opt<std::string> payloadFilename{cl::Positional, cl::desc("<input file>"),
                                        cl::init("-")};
@@ -103,11 +109,13 @@ class DiagnosticHandlerWrapper {
   /// Constructs the diagnostic handler of the specified kind of the given
   /// source manager and context.
   DiagnosticHandlerWrapper(Kind kind, llvm::SourceMgr &mgr,
-                           mlir::MLIRContext *context) {
+                           mlir::MLIRContext *context,
+                           bool verifyOnlyExpectedDiagnostics = false) {
     if (kind == Kind::EmitDiagnostics)
       handler = new mlir::SourceMgrDiagnosticHandler(mgr, context);
     else
-      handler = new mlir::SourceMgrDiagnosticVerifierHandler(mgr, context);
+      handler = new mlir::SourceMgrDiagnosticVerifierHandler(
+          mgr, context, verifyOnlyExpectedDiagnostics);
   }
 
   /// This object is non-copyable but movable.
@@ -150,8 +158,10 @@ class TransformSourceMgr {
 public:
   /// Constructs the source manager indicating whether diagnostic messages will
   /// be verified later on.
-  explicit TransformSourceMgr(bool verifyDiagnostics)
-      : verifyDiagnostics(verifyDiagnostics) {}
+  explicit TransformSourceMgr(bool verifyDiagnostics,
+                              bool verifyOnlyExpectedDiagnostics)
+      : verifyDiagnostics(verifyDiagnostics),
+        verifyOnlyExpectedDiagnostics(verifyOnlyExpectedDiagnostics) {}
 
   /// Deconstructs the source manager. Note that `checkResults` must have been
   /// called on this instance before deconstructing it.
@@ -179,7 +189,8 @@ class TransformSourceMgr {
     // verification needs to happen and store it.
     if (verifyDiagnostics) {
       diagHandlers.emplace_back(
-          DiagnosticHandlerWrapper::Kind::VerifyDiagnostics, mgr, &context);
+          DiagnosticHandlerWrapper::Kind::VerifyDiagnostics, mgr, &context,
+          verifyOnlyExpectedDiagnostics);
     } else {
       diagHandlers.emplace_back(DiagnosticHandlerWrapper::Kind::EmitDiagnostics,
                                 mgr, &context);
@@ -205,6 +216,9 @@ class TransformSourceMgr {
 private:
   /// Indicates whether diagnostic message verification is requested.
   const bool verifyDiagnostics;
+  /// Indicates whether *only specified* diagnostic message verification is
+  /// requested.
+  const bool verifyOnlyExpectedDiagnostics;
 
   /// Indicates that diagnostic message verification has taken place, and the
   /// deconstruction is therefore safe.
@@ -248,7 +262,8 @@ static llvm::LogicalResult processPayloadBuffer(
   context.allowUnregisteredDialects(clOptions->allowUnregisteredDialects);
   mlir::ParserConfig config(&context);
   TransformSourceMgr sourceMgr(
-      /*verifyDiagnostics=*/clOptions->verifyDiagnostics);
+      /*verifyDiagnostics=*/clOptions->verifyDiagnostics,
+      clOptions->verifyOnlyExpectedDiagnostics);
 
   // Parse the input buffer that will be used as transform payload.
   mlir::OwningOpRef<mlir::Operation *> payloadRoot =
diff --git a/mlir/include/mlir/IR/Diagnostics.h b/mlir/include/mlir/IR/Diagnostics.h
index 59bed71e4db88..76ed2342bfb29 100644
--- a/mlir/include/mlir/IR/Diagnostics.h
+++ b/mlir/include/mlir/IR/Diagnostics.h
@@ -626,9 +626,12 @@ struct SourceMgrDiagnosticVerifierHandlerImpl;
 /// corresponding line of the source file.
 class SourceMgrDiagnosticVerifierHandler : public SourceMgrDiagnosticHandler {
 public:
-  SourceMgrDiagnosticVerifierHandler(llvm::SourceMgr &srcMgr, MLIRContext *ctx,
-                                     raw_ostream &out);
-  SourceMgrDiagnosticVerifierHandler(llvm::SourceMgr &srcMgr, MLIRContext *ctx);
+  SourceMgrDiagnosticVerifierHandler(
+      llvm::SourceMgr &srcMgr, MLIRContext *ctx, raw_ostream &out,
+      bool verifyOnlyExpectedDiagnostics = false);
+  SourceMgrDiagnosticVerifierHandler(
+      llvm::SourceMgr &srcMgr, MLIRContext *ctx,
+      bool verifyOnlyExpectedDiagnostics = false);
   ~SourceMgrDiagnosticVerifierHandler();
 
   /// Returns the status of the handler and verifies that all expected
@@ -644,6 +647,10 @@ class SourceMgrDiagnosticVerifierHandler : public SourceMgrDiagnosticHandler {
   void process(LocationAttr loc, StringRef msg, DiagnosticSeverity kind);
 
   std::unique_ptr<detail::SourceMgrDiagnosticVerifierHandlerImpl> impl;
+
+  /// Set whether to check that emitted diagnostics match *only specified*
+  /// `expected-*` lines on the corresponding line.
+  bool verifyOnlyExpectedDiagnostics = false;
 };
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h b/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
index af379797fe865..5a4ebcbd84fa9 100644
--- a/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
+++ b/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
@@ -191,6 +191,16 @@ class MlirOptMainConfig {
   }
   bool shouldVerifyDiagnostics() const { return verifyDiagnosticsFlag; }
 
+  /// Set whether to check that emitted diagnostics match *only specified*
+  /// `expected-*` lines on the corresponding line.
+  MlirOptMainConfig &verifyOnlyExpectedDiagnostics(bool verify) {
+    verifyOnlyExpectedDiagnosticsFlag = verify;
+    return *this;
+  }
+  bool shouldVerifyOnlyExpectedDiagnostics() const {
+    return verifyOnlyExpectedDiagnosticsFlag;
+  }
+
   /// Set whether to run the verifier after each transformation pass.
   MlirOptMainConfig &verifyPasses(bool verify) {
     verifyPassesFlag = verify;
@@ -277,6 +287,9 @@ class MlirOptMainConfig {
   /// Set whether to check that emitted diagnostics match `expected-*` lines on
   /// the corresponding line. This is meant for implementing diagnostic tests.
   bool verifyDiagnosticsFlag = false;
+  /// Set whether to check that emitted diagnostics match *only specified*
+  /// `expected-*` lines on the corresponding line.
+  bool verifyOnlyExpectedDiagnosticsFlag = false;
 
   /// Run the verifier after each transformation pass.
   bool verifyPassesFlag = true;
diff --git a/mlir/lib/IR/Diagnostics.cpp b/mlir/lib/IR/Diagnostics.cpp
index b699e396f6577..d2dfad74c56de 100644
--- a/mlir/lib/IR/Diagnostics.cpp
+++ b/mlir/lib/IR/Diagnostics.cpp
@@ -803,9 +803,11 @@ SourceMgrDiagnosticVerifierHandlerImpl::computeExpectedDiags(
 }
 
 SourceMgrDiagnosticVerifierHandler::SourceMgrDiagnosticVerifierHandler(
-    llvm::SourceMgr &srcMgr, MLIRContext *ctx, raw_ostream &out)
+    llvm::SourceMgr &srcMgr, MLIRContext *ctx, raw_ostream &out,
+    bool verifyOnlyExpectedDiagnostics)
     : SourceMgrDiagnosticHandler(srcMgr, ctx, out),
-      impl(new SourceMgrDiagnosticVerifierHandlerImpl()) {
+      impl(new SourceMgrDiagnosticVerifierHandlerImpl()),
+      verifyOnlyExpectedDiagnostics(verifyOnlyExpectedDiagnostics) {
   // Compute the expected diagnostics for each of the current files in the
   // source manager.
   for (unsigned i = 0, e = mgr.getNumBuffers(); i != e; ++i)
@@ -823,8 +825,10 @@ SourceMgrDiagnosticVerifierHandler::SourceMgrDiagnosticVerifierHandler(
 }
 
 SourceMgrDiagnosticVerifierHandler::SourceMgrDiagnosticVerifierHandler(
-    llvm::SourceMgr &srcMgr, MLIRContext *ctx)
-    : SourceMgrDiagnosticVerifierHandler(srcMgr, ctx, llvm::errs()) {}
+    llvm::SourceMgr &srcMgr, MLIRContext *ctx,
+    bool verifyOnlyExpectedDiagnostics)
+    : SourceMgrDiagnosticVerifierHandler(srcMgr, ctx, llvm::errs(),
+                                         verifyOnlyExpectedDiagnostics) {}
 
 SourceMgrDiagnosticVerifierHandler::~SourceMgrDiagnosticVerifierHandler() {
   // Ensure that all expected diagnostics were handled.
@@ -898,6 +902,9 @@ void SourceMgrDiagnosticVerifierHandler::process(LocationAttr loc,
     }
   }
 
+  if (verifyOnlyExpectedDiagnostics)
+    return;
+
   // Otherwise, emit an error for the near miss.
   if (nearMiss)
     mgr.PrintMessage(os, nearMiss->fileLoc, llvm::SourceMgr::DK_Error,
diff --git a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
index 2924a1205f574..6a97ac3c9742f 100644
--- a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
+++ b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
@@ -168,6 +168,14 @@ struct MlirOptMainConfigCLOptions : public MlirOptMainConfig {
         cl::desc("Check that emitted diagnostics match "
                  "expected-* lines on the corresponding line"),
         cl::location(verifyDiagnosticsFlag), cl::init(false));
+    static cl::opt<bool, /*ExternalStorage=*/true>
+        verifyOnlyExpectedDiagnostics{
+            "verify-only-expected-diagnostics",
+            cl::desc("Check that emitted diagnostics match only specified "
+                     "expected-* "
+                     "lines "
+                     "on the corresponding line"),
+            cl::location(verifyOnlyExpectedDiagnosticsFlag), cl::init(false)};
 
     static cl::opt<bool, /*ExternalStorage=*/true> verifyPasses(
         "verify-each",
@@ -537,7 +545,8 @@ static LogicalResult processBuffer(raw_ostream &os,
     return performActions(os, sourceMgr, &context, config);
   }
 
-  SourceMgrDiagnosticVerifierHandler sourceMgrHandler(*sourceMgr, &context);
+  SourceMgrDiagnosticVerifierHandler sourceMgrHandler(
+      *sourceMgr, &context, config.shouldVerifyOnlyExpectedDiagnostics());
 
   // Do any processing requested by command line flags.  We don't care whether
   // these actions succeed or fail, we only care what diagnostics they produce
diff --git a/mlir/lib/Tools/mlir-translate/MlirTranslateMain.cpp b/mlir/lib/Tools/mlir-translate/MlirTranslateMain.cpp
index 56773f599d5ce..012c8969e7abb 100644
--- a/mlir/lib/Tools/mlir-translate/MlirTranslateMain.cpp
+++ b/mlir/lib/Tools/mlir-translate/MlirTranslateMain.cpp
@@ -58,7 +58,8 @@ LogicalResult mlir::mlirTranslateMain(int argc, char **argv,
 
   static llvm::cl::opt<bool> allowUnregisteredDialects(
       "allow-unregistered-dialect",
-      llvm::cl::desc("Allow operation with no registered dialects (discouraged: testing only!)"),
+      llvm::cl::desc("Allow operation with no registered dialects "
+                     "(discouraged: testing only!)"),
       llvm::cl::init(false));
 
   static llvm::cl::opt<std::string> inputSplitMarker{
@@ -77,6 +78,13 @@ LogicalResult mlir::mlirTranslateMain(int argc, char **argv,
       llvm::cl::desc("Check that emitted diagnostics match "
                      "expected-* lines on the corresponding line"),
       llvm::cl::init(false));
+  static llvm::cl::opt<bool> verifyOnlyExpectedDiagnostics{
+      "verify-only-expected-diagnostics",
+      llvm::cl::desc(
+          "Check that emitted diagnostics match only specified expected-* "
+          "lines "
+          "on the corresponding line"),
+      llvm::cl::init(false)};
 
   static llvm::cl::opt<bool> errorDiagnosticsOnly(
       "error-diagnostics-only",
@@ -158,8 +166,8 @@ LogicalResult mlir::mlirTranslateMain(int argc, char **argv,
         // translation failed (in most cases, it is expected to fail) and we do
         // not filter non-error diagnostics even if `errorDiagnosticsOnly` is
         // set. Instead, we check if the diagnostics were produced as expected.
-        SourceMgrDiagnosticVerifierHandler sourceMgrHandler(*sourceMgr,
-                                                            &context);
+        SourceMgrDiagnosticVerifierHandler sourceMgrHandler(
+            *sourceMgr, &context, verifyOnlyExpectedDiagnostics);
         (void)(*translationRequested)(sourceMgr, os, &context);
         result = sourceMgrHandler.verify();
       } else if (errorDiagnosticsOnly) {

>From 2846d1c8fa4f0c6408a87f2f9a109b6516bdedb6 Mon Sep 17 00:00:00 2001
From: Maksim Levental <maksim.levental at gmail.com>
Date: Thu, 10 Apr 2025 13:46:10 -0400
Subject: [PATCH 2/5] use enum for verifyDiagnostics

---
 .../transform-opt/mlir-transform-opt.cpp      | 61 ++++++++++---------
 mlir/include/mlir/IR/Diagnostics.h            | 16 +++--
 .../include/mlir/Tools/mlir-opt/MlirOptMain.h | 23 +++----
 mlir/lib/IR/Diagnostics.cpp                   | 14 ++---
 mlir/lib/Tools/mlir-opt/MlirOptMain.cpp       | 35 ++++++-----
 .../mlir-translate/MlirTranslateMain.cpp      | 33 +++++-----
 mlir/test/Pass/full_diagnostics.mlir          |  1 +
 .../Pass/full_diagnostics_only_expected.mlir  | 17 ++++++
 .../mlir-translate/verify-only-expected.mlir  | 49 +++++++++++++++
 9 files changed, 160 insertions(+), 89 deletions(-)
 create mode 100644 mlir/test/Pass/full_diagnostics_only_expected.mlir
 create mode 100644 mlir/test/mlir-translate/verify-only-expected.mlir

diff --git a/mlir/examples/transform-opt/mlir-transform-opt.cpp b/mlir/examples/transform-opt/mlir-transform-opt.cpp
index c7fe30b7963b6..ce23e2d67101c 100644
--- a/mlir/examples/transform-opt/mlir-transform-opt.cpp
+++ b/mlir/examples/transform-opt/mlir-transform-opt.cpp
@@ -38,17 +38,20 @@ struct MlirTransformOptCLOptions {
       cl::desc("Allow operations coming from an unregistered dialect"),
       cl::init(false)};
 
-  cl::opt<bool> verifyDiagnostics{
-      "verify-diagnostics",
-      cl::desc("Check that emitted diagnostics match expected-* lines "
-               "on the corresponding line"),
-      cl::init(false)};
-  cl::opt<bool> verifyOnlyExpectedDiagnostics{
-      "verify-only-expected-diagnostics",
-      cl::desc("Check that emitted diagnostics match only specified expected-* "
-               "lines "
-               "on the corresponding line"),
-      cl::init(false)};
+  cl::opt<mlir::SourceMgrDiagnosticVerifierHandler::Level> verifyDiagnostics{
+      "verify-diagnostics", llvm::cl::ValueOptional,
+      cl::desc("Check that emitted diagnostics match "
+               "expected-* lines on the corresponding line"),
+      cl::values(
+          clEnumValN(
+              mlir::SourceMgrDiagnosticVerifierHandler::Level::All, "all",
+              "Check all diagnostics (expected, unexpected, near-misses)"),
+          clEnumValN(
+              mlir::SourceMgrDiagnosticVerifierHandler::Level::All, "",
+              "Check all diagnostics (expected, unexpected, near-misses)"),
+          clEnumValN(
+              mlir::SourceMgrDiagnosticVerifierHandler::Level::OnlyExpected,
+              "only-expected", "Check only expected diagnostics"))};
 
   cl::opt<std::string> payloadFilename{cl::Positional, cl::desc("<input file>"),
                                        cl::init("-")};
@@ -108,14 +111,17 @@ class DiagnosticHandlerWrapper {
 
   /// Constructs the diagnostic handler of the specified kind of the given
   /// source manager and context.
-  DiagnosticHandlerWrapper(Kind kind, llvm::SourceMgr &mgr,
-                           mlir::MLIRContext *context,
-                           bool verifyOnlyExpectedDiagnostics = false) {
-    if (kind == Kind::EmitDiagnostics)
+  DiagnosticHandlerWrapper(
+      Kind kind, llvm::SourceMgr &mgr, mlir::MLIRContext *context,
+      std::optional<mlir::SourceMgrDiagnosticVerifierHandler::Level> level =
+          {}) {
+    if (kind == Kind::EmitDiagnostics) {
       handler = new mlir::SourceMgrDiagnosticHandler(mgr, context);
-    else
-      handler = new mlir::SourceMgrDiagnosticVerifierHandler(
-          mgr, context, verifyOnlyExpectedDiagnostics);
+    } else {
+      assert(level.has_value() && "expected level");
+      handler =
+          new mlir::SourceMgrDiagnosticVerifierHandler(mgr, context, *level);
+    }
   }
 
   /// This object is non-copyable but movable.
@@ -158,10 +164,10 @@ class TransformSourceMgr {
 public:
   /// Constructs the source manager indicating whether diagnostic messages will
   /// be verified later on.
-  explicit TransformSourceMgr(bool verifyDiagnostics,
-                              bool verifyOnlyExpectedDiagnostics)
-      : verifyDiagnostics(verifyDiagnostics),
-        verifyOnlyExpectedDiagnostics(verifyOnlyExpectedDiagnostics) {}
+  explicit TransformSourceMgr(
+      std::optional<mlir::SourceMgrDiagnosticVerifierHandler::Level>
+          verifyDiagnostics)
+      : verifyDiagnostics(verifyDiagnostics) {}
 
   /// Deconstructs the source manager. Note that `checkResults` must have been
   /// called on this instance before deconstructing it.
@@ -190,7 +196,7 @@ class TransformSourceMgr {
     if (verifyDiagnostics) {
       diagHandlers.emplace_back(
           DiagnosticHandlerWrapper::Kind::VerifyDiagnostics, mgr, &context,
-          verifyOnlyExpectedDiagnostics);
+          verifyDiagnostics);
     } else {
       diagHandlers.emplace_back(DiagnosticHandlerWrapper::Kind::EmitDiagnostics,
                                 mgr, &context);
@@ -215,10 +221,8 @@ class TransformSourceMgr {
 
 private:
   /// Indicates whether diagnostic message verification is requested.
-  const bool verifyDiagnostics;
-  /// Indicates whether *only specified* diagnostic message verification is
-  /// requested.
-  const bool verifyOnlyExpectedDiagnostics;
+  const std::optional<mlir::SourceMgrDiagnosticVerifierHandler::Level>
+      verifyDiagnostics;
 
   /// Indicates that diagnostic message verification has taken place, and the
   /// deconstruction is therefore safe.
@@ -262,8 +266,7 @@ static llvm::LogicalResult processPayloadBuffer(
   context.allowUnregisteredDialects(clOptions->allowUnregisteredDialects);
   mlir::ParserConfig config(&context);
   TransformSourceMgr sourceMgr(
-      /*verifyDiagnostics=*/clOptions->verifyDiagnostics,
-      clOptions->verifyOnlyExpectedDiagnostics);
+      /*verifyDiagnostics=*/clOptions->verifyDiagnostics);
 
   // Parse the input buffer that will be used as transform payload.
   mlir::OwningOpRef<mlir::Operation *> payloadRoot =
diff --git a/mlir/include/mlir/IR/Diagnostics.h b/mlir/include/mlir/IR/Diagnostics.h
index 76ed2342bfb29..9359884f2d737 100644
--- a/mlir/include/mlir/IR/Diagnostics.h
+++ b/mlir/include/mlir/IR/Diagnostics.h
@@ -626,12 +626,12 @@ struct SourceMgrDiagnosticVerifierHandlerImpl;
 /// corresponding line of the source file.
 class SourceMgrDiagnosticVerifierHandler : public SourceMgrDiagnosticHandler {
 public:
-  SourceMgrDiagnosticVerifierHandler(
-      llvm::SourceMgr &srcMgr, MLIRContext *ctx, raw_ostream &out,
-      bool verifyOnlyExpectedDiagnostics = false);
-  SourceMgrDiagnosticVerifierHandler(
-      llvm::SourceMgr &srcMgr, MLIRContext *ctx,
-      bool verifyOnlyExpectedDiagnostics = false);
+  enum class Level { None = 0, All, OnlyExpected };
+  SourceMgrDiagnosticVerifierHandler(llvm::SourceMgr &srcMgr, MLIRContext *ctx,
+                                     raw_ostream &out,
+                                     Level level = Level::All);
+  SourceMgrDiagnosticVerifierHandler(llvm::SourceMgr &srcMgr, MLIRContext *ctx,
+                                     Level level = Level::All);
   ~SourceMgrDiagnosticVerifierHandler();
 
   /// Returns the status of the handler and verifies that all expected
@@ -648,9 +648,7 @@ class SourceMgrDiagnosticVerifierHandler : public SourceMgrDiagnosticHandler {
 
   std::unique_ptr<detail::SourceMgrDiagnosticVerifierHandlerImpl> impl;
 
-  /// Set whether to check that emitted diagnostics match *only specified*
-  /// `expected-*` lines on the corresponding line.
-  bool verifyOnlyExpectedDiagnostics = false;
+  Level level = Level::All;
 };
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h b/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
index 5a4ebcbd84fa9..94231227599c9 100644
--- a/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
+++ b/mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
@@ -185,20 +185,19 @@ class MlirOptMainConfig {
 
   /// Set whether to check that emitted diagnostics match `expected-*` lines on
   /// the corresponding line. This is meant for implementing diagnostic tests.
-  MlirOptMainConfig &verifyDiagnostics(bool verify) {
+  MlirOptMainConfig &
+  verifyDiagnostics(SourceMgrDiagnosticVerifierHandler::Level verify) {
     verifyDiagnosticsFlag = verify;
     return *this;
   }
-  bool shouldVerifyDiagnostics() const { return verifyDiagnosticsFlag; }
 
-  /// Set whether to check that emitted diagnostics match *only specified*
-  /// `expected-*` lines on the corresponding line.
-  MlirOptMainConfig &verifyOnlyExpectedDiagnostics(bool verify) {
-    verifyOnlyExpectedDiagnosticsFlag = verify;
-    return *this;
+  bool shouldVerifyDiagnostics() const {
+    return verifyDiagnosticsFlag !=
+           SourceMgrDiagnosticVerifierHandler::Level::None;
   }
-  bool shouldVerifyOnlyExpectedDiagnostics() const {
-    return verifyOnlyExpectedDiagnosticsFlag;
+
+  SourceMgrDiagnosticVerifierHandler::Level verifyDiagnosticsLevel() const {
+    return verifyDiagnosticsFlag;
   }
 
   /// Set whether to run the verifier after each transformation pass.
@@ -286,10 +285,8 @@ class MlirOptMainConfig {
 
   /// Set whether to check that emitted diagnostics match `expected-*` lines on
   /// the corresponding line. This is meant for implementing diagnostic tests.
-  bool verifyDiagnosticsFlag = false;
-  /// Set whether to check that emitted diagnostics match *only specified*
-  /// `expected-*` lines on the corresponding line.
-  bool verifyOnlyExpectedDiagnosticsFlag = false;
+  SourceMgrDiagnosticVerifierHandler::Level verifyDiagnosticsFlag =
+      SourceMgrDiagnosticVerifierHandler::Level::None;
 
   /// Run the verifier after each transformation pass.
   bool verifyPassesFlag = true;
diff --git a/mlir/lib/IR/Diagnostics.cpp b/mlir/lib/IR/Diagnostics.cpp
index d2dfad74c56de..890234b7d78d7 100644
--- a/mlir/lib/IR/Diagnostics.cpp
+++ b/mlir/lib/IR/Diagnostics.cpp
@@ -803,11 +803,9 @@ SourceMgrDiagnosticVerifierHandlerImpl::computeExpectedDiags(
 }
 
 SourceMgrDiagnosticVerifierHandler::SourceMgrDiagnosticVerifierHandler(
-    llvm::SourceMgr &srcMgr, MLIRContext *ctx, raw_ostream &out,
-    bool verifyOnlyExpectedDiagnostics)
+    llvm::SourceMgr &srcMgr, MLIRContext *ctx, raw_ostream &out, Level level)
     : SourceMgrDiagnosticHandler(srcMgr, ctx, out),
-      impl(new SourceMgrDiagnosticVerifierHandlerImpl()),
-      verifyOnlyExpectedDiagnostics(verifyOnlyExpectedDiagnostics) {
+      impl(new SourceMgrDiagnosticVerifierHandlerImpl()), level(level) {
   // Compute the expected diagnostics for each of the current files in the
   // source manager.
   for (unsigned i = 0, e = mgr.getNumBuffers(); i != e; ++i)
@@ -825,10 +823,8 @@ SourceMgrDiagnosticVerifierHandler::SourceMgrDiagnosticVerifierHandler(
 }
 
 SourceMgrDiagnosticVerifierHandler::SourceMgrDiagnosticVerifierHandler(
-    llvm::SourceMgr &srcMgr, MLIRContext *ctx,
-    bool verifyOnlyExpectedDiagnostics)
-    : SourceMgrDiagnosticVerifierHandler(srcMgr, ctx, llvm::errs(),
-                                         verifyOnlyExpectedDiagnostics) {}
+    llvm::SourceMgr &srcMgr, MLIRContext *ctx, Level level)
+    : SourceMgrDiagnosticVerifierHandler(srcMgr, ctx, llvm::errs(), level) {}
 
 SourceMgrDiagnosticVerifierHandler::~SourceMgrDiagnosticVerifierHandler() {
   // Ensure that all expected diagnostics were handled.
@@ -902,7 +898,7 @@ void SourceMgrDiagnosticVerifierHandler::process(LocationAttr loc,
     }
   }
 
-  if (verifyOnlyExpectedDiagnostics)
+  if (level == Level::OnlyExpected)
     return;
 
   // Otherwise, emit an error for the near miss.
diff --git a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
index 6a97ac3c9742f..9f5cb377da566 100644
--- a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
+++ b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
@@ -163,19 +163,26 @@ struct MlirOptMainConfigCLOptions : public MlirOptMainConfig {
         cl::desc("Split marker to use for merging the ouput"),
         cl::location(outputSplitMarkerFlag), cl::init(kDefaultSplitMarker));
 
-    static cl::opt<bool, /*ExternalStorage=*/true> verifyDiagnostics(
-        "verify-diagnostics",
-        cl::desc("Check that emitted diagnostics match "
-                 "expected-* lines on the corresponding line"),
-        cl::location(verifyDiagnosticsFlag), cl::init(false));
-    static cl::opt<bool, /*ExternalStorage=*/true>
-        verifyOnlyExpectedDiagnostics{
-            "verify-only-expected-diagnostics",
-            cl::desc("Check that emitted diagnostics match only specified "
-                     "expected-* "
-                     "lines "
-                     "on the corresponding line"),
-            cl::location(verifyOnlyExpectedDiagnosticsFlag), cl::init(false)};
+    static cl::opt<SourceMgrDiagnosticVerifierHandler::Level,
+                   /*ExternalStorage=*/true>
+        verifyDiagnostics{
+            "verify-diagnostics", llvm::cl::ValueOptional,
+            cl::desc("Check that emitted diagnostics match "
+                     "expected-* lines on the corresponding line"),
+            cl::location(verifyDiagnosticsFlag),
+            cl::values(
+                clEnumValN(SourceMgrDiagnosticVerifierHandler::Level::All,
+                           "all",
+                           "Check all diagnostics (expected, unexpected, "
+                           "near-misses)"),
+                // Implicit value: when passed with no arguments, e.g.
+                // `--verify-diagnostics` or `--verify-diagnostics=`.
+                clEnumValN(SourceMgrDiagnosticVerifierHandler::Level::All, "",
+                           "Check all diagnostics (expected, unexpected, "
+                           "near-misses)"),
+                clEnumValN(
+                    SourceMgrDiagnosticVerifierHandler::Level::OnlyExpected,
+                    "only-expected", "Check only expected diagnostics"))};
 
     static cl::opt<bool, /*ExternalStorage=*/true> verifyPasses(
         "verify-each",
@@ -546,7 +553,7 @@ static LogicalResult processBuffer(raw_ostream &os,
   }
 
   SourceMgrDiagnosticVerifierHandler sourceMgrHandler(
-      *sourceMgr, &context, config.shouldVerifyOnlyExpectedDiagnostics());
+      *sourceMgr, &context, config.verifyDiagnosticsLevel());
 
   // Do any processing requested by command line flags.  We don't care whether
   // these actions succeed or fail, we only care what diagnostics they produce
diff --git a/mlir/lib/Tools/mlir-translate/MlirTranslateMain.cpp b/mlir/lib/Tools/mlir-translate/MlirTranslateMain.cpp
index 012c8969e7abb..ceccd1ea69e96 100644
--- a/mlir/lib/Tools/mlir-translate/MlirTranslateMain.cpp
+++ b/mlir/lib/Tools/mlir-translate/MlirTranslateMain.cpp
@@ -73,18 +73,21 @@ LogicalResult mlir::mlirTranslateMain(int argc, char **argv,
                      "default marker and process each chunk independently"),
       llvm::cl::init("")};
 
-  static llvm::cl::opt<bool> verifyDiagnostics(
-      "verify-diagnostics",
-      llvm::cl::desc("Check that emitted diagnostics match "
-                     "expected-* lines on the corresponding line"),
-      llvm::cl::init(false));
-  static llvm::cl::opt<bool> verifyOnlyExpectedDiagnostics{
-      "verify-only-expected-diagnostics",
-      llvm::cl::desc(
-          "Check that emitted diagnostics match only specified expected-* "
-          "lines "
-          "on the corresponding line"),
-      llvm::cl::init(false)};
+  static llvm::cl::opt<SourceMgrDiagnosticVerifierHandler::Level>
+      verifyDiagnostics{
+          "verify-diagnostics", llvm::cl::ValueOptional,
+          llvm::cl::desc("Check that emitted diagnostics match "
+                         "expected-* lines on the corresponding line"),
+          llvm::cl::values(
+              clEnumValN(
+                  SourceMgrDiagnosticVerifierHandler::Level::All, "all",
+                  "Check all diagnostics (expected, unexpected, near-misses)"),
+              clEnumValN(
+                  SourceMgrDiagnosticVerifierHandler::Level::All, "",
+                  "Check all diagnostics (expected, unexpected, near-misses)"),
+              clEnumValN(
+                  SourceMgrDiagnosticVerifierHandler::Level::OnlyExpected,
+                  "only-expected", "Check only expected diagnostics"))};
 
   static llvm::cl::opt<bool> errorDiagnosticsOnly(
       "error-diagnostics-only",
@@ -157,17 +160,17 @@ LogicalResult mlir::mlirTranslateMain(int argc, char **argv,
 
       MLIRContext context;
       context.allowUnregisteredDialects(allowUnregisteredDialects);
-      context.printOpOnDiagnostic(!verifyDiagnostics);
+      context.printOpOnDiagnostic(!bool(verifyDiagnostics.getNumOccurrences()));
       auto sourceMgr = std::make_shared<llvm::SourceMgr>();
       sourceMgr->AddNewSourceBuffer(std::move(ownedBuffer), SMLoc());
 
-      if (verifyDiagnostics) {
+      if (verifyDiagnostics.getNumOccurrences()) {
         // In the diagnostic verification flow, we ignore whether the
         // translation failed (in most cases, it is expected to fail) and we do
         // not filter non-error diagnostics even if `errorDiagnosticsOnly` is
         // set. Instead, we check if the diagnostics were produced as expected.
         SourceMgrDiagnosticVerifierHandler sourceMgrHandler(
-            *sourceMgr, &context, verifyOnlyExpectedDiagnostics);
+            *sourceMgr, &context, verifyDiagnostics);
         (void)(*translationRequested)(sourceMgr, os, &context);
         result = sourceMgrHandler.verify();
       } else if (errorDiagnosticsOnly) {
diff --git a/mlir/test/Pass/full_diagnostics.mlir b/mlir/test/Pass/full_diagnostics.mlir
index 881260ce60d32..c355fd071bdb6 100644
--- a/mlir/test/Pass/full_diagnostics.mlir
+++ b/mlir/test/Pass/full_diagnostics.mlir
@@ -1,4 +1,5 @@
 // RUN: mlir-opt %s -pass-pipeline='builtin.module(func.func(test-pass-failure{gen-diagnostics}))' -verify-diagnostics
+// RUN: mlir-opt %s -pass-pipeline='builtin.module(func.func(test-pass-failure{gen-diagnostics}))' -verify-diagnostics=all
 
 // Test that all errors are reported.
 // expected-error at below {{illegal operation}}
diff --git a/mlir/test/Pass/full_diagnostics_only_expected.mlir b/mlir/test/Pass/full_diagnostics_only_expected.mlir
new file mode 100644
index 0000000000000..de29693604b4f
--- /dev/null
+++ b/mlir/test/Pass/full_diagnostics_only_expected.mlir
@@ -0,0 +1,17 @@
+// RUN: mlir-opt %s -pass-pipeline='builtin.module(func.func(test-pass-failure{gen-diagnostics}))' -verify-diagnostics=only-expected
+
+// Test that only expected errors are reported.
+// reports {{illegal operation}} but unchecked
+func.func @TestAlwaysIllegalOperationPass1() {
+  return
+}
+
+// expected-error at +1 {{illegal operation}}
+func.func @TestAlwaysIllegalOperationPass2() {
+  return
+}
+
+// reports {{illegal operation}} but unchecked
+func.func @TestAlwaysIllegalOperationPass3() {
+  return
+}
diff --git a/mlir/test/mlir-translate/verify-only-expected.mlir b/mlir/test/mlir-translate/verify-only-expected.mlir
new file mode 100644
index 0000000000000..543a6954c840f
--- /dev/null
+++ b/mlir/test/mlir-translate/verify-only-expected.mlir
@@ -0,0 +1,49 @@
+// Note: borrowed/copied from mlir/test/Target/LLVMIR/arm-sme-invalid.mlir
+
+// Check that verify-diagnostics=only-expected passes with only one actual `expected-error`
+// RUN: mlir-translate %s -verify-diagnostics=only-expected -split-input-file -mlir-to-llvmir
+
+// Check that verify-diagnostics=all fails because we're missing three `expected-error`
+// RUN: not mlir-translate %s -verify-diagnostics=all -split-input-file -mlir-to-llvmir 2>&1 | FileCheck %s --check-prefix=CHECK-VERIFY-ALL
+// CHECK-VERIFY-ALL:      error: unexpected error: 'arm_sme.intr.write.horiz' op failed to verify that all of {predicate, vector} have same shape
+// CHECK-VERIFY-ALL-NEXT: "arm_sme.intr.write.horiz"
+// CHECK-VERIFY-ALL:      error: unexpected error: 'arm_sme.intr.read.horiz' op failed to verify that all of {vector, res} have same element type
+// CHECK-VERIFY-ALL-NEXT: %res = "arm_sme.intr.read.horiz"
+// CHECK-VERIFY-ALL:      error: unexpected error: 'arm_sme.intr.cntsb' op failed to verify that `res` is i64
+// CHECK-VERIFY-ALL-NEXT: %res = "arm_sme.intr.cntsb"
+
+llvm.func @arm_sme_vector_to_tile_invalid_types(%tileslice : i32,
+                                                %nxv4i1 : vector<[4]xi1>,
+                                                %nxv16i8 : vector<[16]xi8>) {
+  "arm_sme.intr.write.horiz"(%tileslice, %nxv4i1, %nxv16i8) <{tile_id = 0 : i32}> :
+      (i32, vector<[4]xi1>, vector<[16]xi8>) -> ()
+  llvm.return
+}
+
+// -----
+
+llvm.func @arm_sme_tile_slice_to_vector_invalid_shapes(
+  %tileslice : i32, %nxv4i1 : vector<[4]xi1>, %nxv16i8 : vector<[16]xi8>
+) -> vector<[3]xf32> {
+  // expected-error @+1 {{failed to verify that all of {vector, predicate, res} have same shape}}
+  %res = "arm_sme.intr.read.horiz"(%nxv16i8, %nxv4i1, %tileslice) <{tile_id = 0 : i32}> :
+      (vector<[16]xi8>, vector<[4]xi1>, i32) -> vector<[3]xf32>
+  llvm.return %res : vector<[3]xf32>
+}
+
+// -----
+
+llvm.func @arm_sme_tile_slice_to_vector_invalid_element_types(
+  %tileslice : i32, %nxv4i1 : vector<[4]xi1>, %nxv4f32 : vector<[4]xf32>
+) -> vector<[3]xi32> {
+  %res = "arm_sme.intr.read.horiz"(%nxv4f32, %nxv4i1, %tileslice) <{tile_id = 0 : i32}> :
+      (vector<[4]xf32>, vector<[4]xi1>, i32) -> vector<[4]xi32>
+  llvm.return %res : vector<[4]xi32>
+}
+
+// -----
+
+llvm.func @arm_sme_streaming_vl_invalid_return_type() -> i32 {
+  %res = "arm_sme.intr.cntsb"() : () -> i32
+  llvm.return %res : i32
+}

>From 67df3396bcf57533f251cd647d76169050e0acbd Mon Sep 17 00:00:00 2001
From: Maksim Levental <maksim.levental at gmail.com>
Date: Thu, 10 Apr 2025 14:14:18 -0400
Subject: [PATCH 3/5] address comments

---
 mlir/examples/transform-opt/mlir-transform-opt.cpp  |  6 ++++--
 mlir/lib/Tools/mlir-opt/MlirOptMain.cpp             |  4 ++--
 mlir/lib/Tools/mlir-translate/MlirTranslateMain.cpp | 11 ++++++-----
 3 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/mlir/examples/transform-opt/mlir-transform-opt.cpp b/mlir/examples/transform-opt/mlir-transform-opt.cpp
index ce23e2d67101c..405008526f675 100644
--- a/mlir/examples/transform-opt/mlir-transform-opt.cpp
+++ b/mlir/examples/transform-opt/mlir-transform-opt.cpp
@@ -40,12 +40,14 @@ struct MlirTransformOptCLOptions {
 
   cl::opt<mlir::SourceMgrDiagnosticVerifierHandler::Level> verifyDiagnostics{
       "verify-diagnostics", llvm::cl::ValueOptional,
-      cl::desc("Check that emitted diagnostics match "
-               "expected-* lines on the corresponding line"),
+      cl::desc("Check that emitted diagnostics match expected-* lines on the "
+               "corresponding line"),
       cl::values(
           clEnumValN(
               mlir::SourceMgrDiagnosticVerifierHandler::Level::All, "all",
               "Check all diagnostics (expected, unexpected, near-misses)"),
+          // Implicit value: when passed with no arguments, e.g.
+          // `--verify-diagnostics` or `--verify-diagnostics=`.
           clEnumValN(
               mlir::SourceMgrDiagnosticVerifierHandler::Level::All, "",
               "Check all diagnostics (expected, unexpected, near-misses)"),
diff --git a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
index 9f5cb377da566..31e0caa768113 100644
--- a/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
+++ b/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
@@ -167,8 +167,8 @@ struct MlirOptMainConfigCLOptions : public MlirOptMainConfig {
                    /*ExternalStorage=*/true>
         verifyDiagnostics{
             "verify-diagnostics", llvm::cl::ValueOptional,
-            cl::desc("Check that emitted diagnostics match "
-                     "expected-* lines on the corresponding line"),
+            cl::desc("Check that emitted diagnostics match expected-* lines on "
+                     "the corresponding line"),
             cl::location(verifyDiagnosticsFlag),
             cl::values(
                 clEnumValN(SourceMgrDiagnosticVerifierHandler::Level::All,
diff --git a/mlir/lib/Tools/mlir-translate/MlirTranslateMain.cpp b/mlir/lib/Tools/mlir-translate/MlirTranslateMain.cpp
index ceccd1ea69e96..f2a81cca2abe5 100644
--- a/mlir/lib/Tools/mlir-translate/MlirTranslateMain.cpp
+++ b/mlir/lib/Tools/mlir-translate/MlirTranslateMain.cpp
@@ -58,8 +58,7 @@ LogicalResult mlir::mlirTranslateMain(int argc, char **argv,
 
   static llvm::cl::opt<bool> allowUnregisteredDialects(
       "allow-unregistered-dialect",
-      llvm::cl::desc("Allow operation with no registered dialects "
-                     "(discouraged: testing only!)"),
+      llvm::cl::desc("Allow operation with no registered dialects (discouraged: testing only!)"),
       llvm::cl::init(false));
 
   static llvm::cl::opt<std::string> inputSplitMarker{
@@ -76,12 +75,14 @@ LogicalResult mlir::mlirTranslateMain(int argc, char **argv,
   static llvm::cl::opt<SourceMgrDiagnosticVerifierHandler::Level>
       verifyDiagnostics{
           "verify-diagnostics", llvm::cl::ValueOptional,
-          llvm::cl::desc("Check that emitted diagnostics match "
-                         "expected-* lines on the corresponding line"),
+          llvm::cl::desc("Check that emitted diagnostics match expected-* "
+                         "lines on the corresponding line"),
           llvm::cl::values(
               clEnumValN(
                   SourceMgrDiagnosticVerifierHandler::Level::All, "all",
                   "Check all diagnostics (expected, unexpected, near-misses)"),
+              // Implicit value: when passed with no arguments, e.g.
+              // `--verify-diagnostics` or `--verify-diagnostics=`.
               clEnumValN(
                   SourceMgrDiagnosticVerifierHandler::Level::All, "",
                   "Check all diagnostics (expected, unexpected, near-misses)"),
@@ -160,7 +161,7 @@ LogicalResult mlir::mlirTranslateMain(int argc, char **argv,
 
       MLIRContext context;
       context.allowUnregisteredDialects(allowUnregisteredDialects);
-      context.printOpOnDiagnostic(!bool(verifyDiagnostics.getNumOccurrences()));
+      context.printOpOnDiagnostic(verifyDiagnostics.getNumOccurrences() == 0);
       auto sourceMgr = std::make_shared<llvm::SourceMgr>();
       sourceMgr->AddNewSourceBuffer(std::move(ownedBuffer), SMLoc());
 

>From 03c5c6b21abf94db80da6909586210da02146f71 Mon Sep 17 00:00:00 2001
From: Maksim Levental <maksim.levental at gmail.com>
Date: Thu, 10 Apr 2025 14:24:48 -0400
Subject: [PATCH 4/5] more generic test

---
 .../mlir-translate/verify-only-expected.mlir  | 49 +++++--------------
 1 file changed, 12 insertions(+), 37 deletions(-)

diff --git a/mlir/test/mlir-translate/verify-only-expected.mlir b/mlir/test/mlir-translate/verify-only-expected.mlir
index 543a6954c840f..0efeaa84a3f4f 100644
--- a/mlir/test/mlir-translate/verify-only-expected.mlir
+++ b/mlir/test/mlir-translate/verify-only-expected.mlir
@@ -1,49 +1,24 @@
-// Note: borrowed/copied from mlir/test/Target/LLVMIR/arm-sme-invalid.mlir
-
 // Check that verify-diagnostics=only-expected passes with only one actual `expected-error`
-// RUN: mlir-translate %s -verify-diagnostics=only-expected -split-input-file -mlir-to-llvmir
-
-// Check that verify-diagnostics=all fails because we're missing three `expected-error`
-// RUN: not mlir-translate %s -verify-diagnostics=all -split-input-file -mlir-to-llvmir 2>&1 | FileCheck %s --check-prefix=CHECK-VERIFY-ALL
-// CHECK-VERIFY-ALL:      error: unexpected error: 'arm_sme.intr.write.horiz' op failed to verify that all of {predicate, vector} have same shape
-// CHECK-VERIFY-ALL-NEXT: "arm_sme.intr.write.horiz"
-// CHECK-VERIFY-ALL:      error: unexpected error: 'arm_sme.intr.read.horiz' op failed to verify that all of {vector, res} have same element type
-// CHECK-VERIFY-ALL-NEXT: %res = "arm_sme.intr.read.horiz"
-// CHECK-VERIFY-ALL:      error: unexpected error: 'arm_sme.intr.cntsb' op failed to verify that `res` is i64
-// CHECK-VERIFY-ALL-NEXT: %res = "arm_sme.intr.cntsb"
+// RUN: mlir-translate %s --allow-unregistered-dialect -verify-diagnostics=only-expected -split-input-file -mlir-to-llvmir
 
-llvm.func @arm_sme_vector_to_tile_invalid_types(%tileslice : i32,
-                                                %nxv4i1 : vector<[4]xi1>,
-                                                %nxv16i8 : vector<[16]xi8>) {
-  "arm_sme.intr.write.horiz"(%tileslice, %nxv4i1, %nxv16i8) <{tile_id = 0 : i32}> :
-      (i32, vector<[4]xi1>, vector<[16]xi8>) -> ()
-  llvm.return
-}
-
-// -----
+// Check that verify-diagnostics=all fails because we're missing two `expected-error`
+// RUN: not mlir-translate %s --allow-unregistered-dialect -verify-diagnostics=all -split-input-file -mlir-to-llvmir 2>&1 | FileCheck %s --check-prefix=CHECK-VERIFY-ALL
+// CHECK-VERIFY-ALL: unexpected error: cannot be converted to LLVM IR: missing `LLVMTranslationDialectInterface` registration for dialect for op: simple.terminator1
+// CHECK-VERIFY-ALL: unexpected error: cannot be converted to LLVM IR: missing `LLVMTranslationDialectInterface` registration for dialect for op: simple.terminator3
 
-llvm.func @arm_sme_tile_slice_to_vector_invalid_shapes(
-  %tileslice : i32, %nxv4i1 : vector<[4]xi1>, %nxv16i8 : vector<[16]xi8>
-) -> vector<[3]xf32> {
-  // expected-error @+1 {{failed to verify that all of {vector, predicate, res} have same shape}}
-  %res = "arm_sme.intr.read.horiz"(%nxv16i8, %nxv4i1, %tileslice) <{tile_id = 0 : i32}> :
-      (vector<[16]xi8>, vector<[4]xi1>, i32) -> vector<[3]xf32>
-  llvm.return %res : vector<[3]xf32>
+llvm.func @trivial() {
+  "simple.terminator1"() : () -> ()
 }
 
 // -----
 
-llvm.func @arm_sme_tile_slice_to_vector_invalid_element_types(
-  %tileslice : i32, %nxv4i1 : vector<[4]xi1>, %nxv4f32 : vector<[4]xf32>
-) -> vector<[3]xi32> {
-  %res = "arm_sme.intr.read.horiz"(%nxv4f32, %nxv4i1, %tileslice) <{tile_id = 0 : i32}> :
-      (vector<[4]xf32>, vector<[4]xi1>, i32) -> vector<[4]xi32>
-  llvm.return %res : vector<[4]xi32>
+llvm.func @trivial() {
+  // expected-error @+1 {{cannot be converted to LLVM IR: missing `LLVMTranslationDialectInterface` registration for dialect for op: simple.terminator2}}
+  "simple.terminator2"() : () -> ()
 }
 
 // -----
 
-llvm.func @arm_sme_streaming_vl_invalid_return_type() -> i32 {
-  %res = "arm_sme.intr.cntsb"() : () -> i32
-  llvm.return %res : i32
+llvm.func @trivial() {
+  "simple.terminator3"() : () -> ()
 }

>From 2e894352b5612030c5454d79579b9e1697900695 Mon Sep 17 00:00:00 2001
From: Maksim Levental <maksim.levental at gmail.com>
Date: Thu, 10 Apr 2025 14:32:33 -0400
Subject: [PATCH 5/5] move level to impl

---
 mlir/include/mlir/IR/Diagnostics.h |  2 --
 mlir/lib/IR/Diagnostics.cpp        | 16 +++++++++++++---
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/mlir/include/mlir/IR/Diagnostics.h b/mlir/include/mlir/IR/Diagnostics.h
index 9359884f2d737..4ed0423902138 100644
--- a/mlir/include/mlir/IR/Diagnostics.h
+++ b/mlir/include/mlir/IR/Diagnostics.h
@@ -647,8 +647,6 @@ class SourceMgrDiagnosticVerifierHandler : public SourceMgrDiagnosticHandler {
   void process(LocationAttr loc, StringRef msg, DiagnosticSeverity kind);
 
   std::unique_ptr<detail::SourceMgrDiagnosticVerifierHandlerImpl> impl;
-
-  Level level = Level::All;
 };
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/lib/IR/Diagnostics.cpp b/mlir/lib/IR/Diagnostics.cpp
index 890234b7d78d7..59d803035bda0 100644
--- a/mlir/lib/IR/Diagnostics.cpp
+++ b/mlir/lib/IR/Diagnostics.cpp
@@ -661,7 +661,9 @@ struct ExpectedDiag {
 };
 
 struct SourceMgrDiagnosticVerifierHandlerImpl {
-  SourceMgrDiagnosticVerifierHandlerImpl() : status(success()) {}
+  SourceMgrDiagnosticVerifierHandlerImpl(
+      SourceMgrDiagnosticVerifierHandler::Level level)
+      : status(success()), level(level) {}
 
   /// Returns the expected diagnostics for the given source file.
   std::optional<MutableArrayRef<ExpectedDiag>>
@@ -672,6 +674,10 @@ struct SourceMgrDiagnosticVerifierHandlerImpl {
   computeExpectedDiags(raw_ostream &os, llvm::SourceMgr &mgr,
                        const llvm::MemoryBuffer *buf);
 
+  SourceMgrDiagnosticVerifierHandler::Level getVerifyLevel() const {
+    return level;
+  }
+
   /// The current status of the verifier.
   LogicalResult status;
 
@@ -685,6 +691,10 @@ struct SourceMgrDiagnosticVerifierHandlerImpl {
   llvm::Regex expected =
       llvm::Regex("expected-(error|note|remark|warning)(-re)? "
                   "*(@([+-][0-9]+|above|below|unknown))? *{{(.*)}}$");
+
+  /// Verification level.
+  SourceMgrDiagnosticVerifierHandler::Level level =
+      SourceMgrDiagnosticVerifierHandler::Level::All;
 };
 } // namespace detail
 } // namespace mlir
@@ -805,7 +815,7 @@ SourceMgrDiagnosticVerifierHandlerImpl::computeExpectedDiags(
 SourceMgrDiagnosticVerifierHandler::SourceMgrDiagnosticVerifierHandler(
     llvm::SourceMgr &srcMgr, MLIRContext *ctx, raw_ostream &out, Level level)
     : SourceMgrDiagnosticHandler(srcMgr, ctx, out),
-      impl(new SourceMgrDiagnosticVerifierHandlerImpl()), level(level) {
+      impl(new SourceMgrDiagnosticVerifierHandlerImpl(level)) {
   // Compute the expected diagnostics for each of the current files in the
   // source manager.
   for (unsigned i = 0, e = mgr.getNumBuffers(); i != e; ++i)
@@ -898,7 +908,7 @@ void SourceMgrDiagnosticVerifierHandler::process(LocationAttr loc,
     }
   }
 
-  if (level == Level::OnlyExpected)
+  if (impl->getVerifyLevel() == Level::OnlyExpected)
     return;
 
   // Otherwise, emit an error for the near miss.



More information about the Mlir-commits mailing list