[Mlir-commits] [mlir] e289b2e - [mlir][Utils] Add VerificationUtils (NFC) (#174336)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Mon Jan 12 08:52:48 PST 2026


Author: Nick Kreeger
Date: 2026-01-12T16:52:44Z
New Revision: e289b2e765ed279e57e4643a4f602d2328ac4af4

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

LOG:  [mlir][Utils] Add VerificationUtils (NFC) (#174336)

Introduces `VerificationUtils` to consolidate common operation
verification patterns in MLIR. This initial implementation provides
`verifyDynamicDimensionCount()` to reduce code duplication across
dialect verifiers.

This is an NFC (No Functional Change) refactoring that improves code
maintainability by extracting reusable verification logic into a shared
utility.

Added: 
    mlir/include/mlir/Dialect/Utils/VerificationUtils.h
    mlir/lib/Dialect/Utils/VerificationUtils.cpp

Modified: 
    mlir/lib/Dialect/Bufferization/IR/BufferizationOps.cpp
    mlir/lib/Dialect/GPU/IR/GPUDialect.cpp
    mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp
    mlir/lib/Dialect/Tensor/IR/TensorOps.cpp
    mlir/lib/Dialect/Utils/CMakeLists.txt
    mlir/test/Dialect/Bufferization/invalid.mlir
    mlir/test/Dialect/GPU/invalid.mlir
    mlir/test/Dialect/MemRef/invalid.mlir
    mlir/test/Dialect/Tensor/invalid.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/Utils/VerificationUtils.h b/mlir/include/mlir/Dialect/Utils/VerificationUtils.h
new file mode 100644
index 0000000000000..c1c3cc6231eb6
--- /dev/null
+++ b/mlir/include/mlir/Dialect/Utils/VerificationUtils.h
@@ -0,0 +1,32 @@
+//===- VerificationUtils.h - Common verification utilities ------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file defines common verification utilities that can be shared
+// across multiple MLIR dialects. These utilities help reduce code duplication
+// for common verification patterns.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_UTILS_VERIFICATIONUTILS_H
+#define MLIR_DIALECT_UTILS_VERIFICATIONUTILS_H
+
+#include "mlir/IR/BuiltinTypes.h"
+#include "mlir/IR/Operation.h"
+#include "mlir/Support/LLVM.h"
+
+namespace mlir {
+
+/// Verify that the number of dynamic size operands matches the number of
+/// dynamic dimensions in the shaped type. Returns failure and emits an error
+/// if the counts don't match.
+LogicalResult verifyDynamicDimensionCount(Operation *op, ShapedType type,
+                                          ValueRange dynamicSizes);
+
+} // namespace mlir
+
+#endif // MLIR_DIALECT_UTILS_VERIFICATIONUTILS_H

diff  --git a/mlir/lib/Dialect/Bufferization/IR/BufferizationOps.cpp b/mlir/lib/Dialect/Bufferization/IR/BufferizationOps.cpp
index 56ff2121e4620..eda6bf276be06 100644
--- a/mlir/lib/Dialect/Bufferization/IR/BufferizationOps.cpp
+++ b/mlir/lib/Dialect/Bufferization/IR/BufferizationOps.cpp
@@ -12,6 +12,7 @@
 #include "mlir/Dialect/Func/IR/FuncOps.h"
 #include "mlir/Dialect/MemRef/IR/MemRef.h"
 #include "mlir/Dialect/Tensor/IR/Tensor.h"
+#include "mlir/Dialect/Utils/VerificationUtils.h"
 #include "mlir/IR/Matchers.h"
 #include <optional>
 
@@ -251,9 +252,9 @@ AllocTensorOp::getBufferType(Value value, const BufferizationOptions &options,
 LogicalResult AllocTensorOp::verify() {
   if (getCopy() && !getDynamicSizes().empty())
     return emitError("dynamic sizes not needed when copying a tensor");
-  if (!getCopy() && getType().getNumDynamicDims() != getDynamicSizes().size())
-    return emitError("expected ")
-           << getType().getNumDynamicDims() << " dynamic sizes";
+  if (!getCopy() && failed(verifyDynamicDimensionCount(
+                        getOperation(), getType(), getDynamicSizes())))
+    return failure();
   if (getCopy() && getCopy().getType() != getType())
     return emitError("expected that `copy` and return type match");
   return success();

diff  --git a/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp b/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp
index 552485e748123..ff2d792f9cebd 100644
--- a/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp
+++ b/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp
@@ -16,6 +16,7 @@
 #include "mlir/Dialect/Bufferization/IR/BufferDeallocationOpInterface.h"
 #include "mlir/Dialect/Math/IR/Math.h"
 #include "mlir/Dialect/MemRef/IR/MemRef.h"
+#include "mlir/Dialect/Utils/VerificationUtils.h"
 #include "mlir/IR/Attributes.h"
 #include "mlir/IR/Builders.h"
 #include "mlir/IR/BuiltinAttributes.h"
@@ -2171,9 +2172,9 @@ void WaitOp::getCanonicalizationPatterns(RewritePatternSet &results,
 LogicalResult AllocOp::verify() {
   auto memRefType = llvm::cast<MemRefType>(getMemref().getType());
 
-  if (getDynamicSizes().size() != memRefType.getNumDynamicDims())
-    return emitOpError("dimension operand count does not equal memref "
-                       "dynamic dimension count");
+  if (failed(verifyDynamicDimensionCount(getOperation(), memRefType,
+                                         getDynamicSizes())))
+    return failure();
 
   unsigned numSymbols = 0;
   if (!memRefType.getLayout().isIdentity())

diff  --git a/mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp b/mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp
index fe93b3e296400..a612475edf3b9 100644
--- a/mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp
+++ b/mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp
@@ -10,6 +10,7 @@
 #include "mlir/Dialect/Arith/Utils/Utils.h"
 #include "mlir/Dialect/MemRef/IR/MemRef.h"
 #include "mlir/Dialect/Utils/StaticValueUtils.h"
+#include "mlir/Dialect/Utils/VerificationUtils.h"
 #include "mlir/IR/AffineMap.h"
 #include "mlir/IR/Builders.h"
 #include "mlir/IR/BuiltinTypes.h"
@@ -192,9 +193,8 @@ static LogicalResult verifyAllocLikeOp(AllocLikeOp op) {
   if (!memRefType)
     return op.emitOpError("result must be a memref");
 
-  if (op.getDynamicSizes().size() != memRefType.getNumDynamicDims())
-    return op.emitOpError("dimension operand count does not equal memref "
-                          "dynamic dimension count");
+  if (failed(verifyDynamicDimensionCount(op, memRefType, op.getDynamicSizes())))
+    return failure();
 
   unsigned numSymbols = 0;
   if (!memRefType.getLayout().isIdentity())
@@ -3735,9 +3735,8 @@ LogicalResult ViewOp::verify() {
            << baseType << " and view memref type " << viewType;
 
   // Verify that we have the correct number of sizes for the result type.
-  unsigned numDynamicDims = viewType.getNumDynamicDims();
-  if (getSizes().size() != numDynamicDims)
-    return emitError("incorrect number of size operands for type ") << viewType;
+  if (failed(verifyDynamicDimensionCount(getOperation(), viewType, getSizes())))
+    return failure();
 
   return success();
 }

diff  --git a/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp b/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp
index a0c7e40c20a46..11824a0ac6f05 100644
--- a/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp
+++ b/mlir/lib/Dialect/Tensor/IR/TensorOps.cpp
@@ -15,6 +15,7 @@
 #include "mlir/Dialect/Utils/IndexingUtils.h"
 #include "mlir/Dialect/Utils/ReshapeOpsUtils.h"
 #include "mlir/Dialect/Utils/StaticValueUtils.h"
+#include "mlir/Dialect/Utils/VerificationUtils.h"
 #include "mlir/IR/Builders.h"
 #include "mlir/IR/BuiltinAttributeInterfaces.h"
 #include "mlir/IR/BuiltinTypeInterfaces.h"
@@ -1075,11 +1076,8 @@ void EmptyOp::build(OpBuilder &builder, OperationState &result,
 }
 
 LogicalResult EmptyOp::verify() {
-  if (getType().getNumDynamicDims() != getDynamicSizes().size())
-    return emitOpError("incorrect number of dynamic sizes, has ")
-           << getDynamicSizes().size() << ", expected "
-           << getType().getNumDynamicDims();
-  return success();
+  return verifyDynamicDimensionCount(getOperation(), getType(),
+                                     getDynamicSizes());
 }
 
 LogicalResult
@@ -1666,9 +1664,9 @@ LogicalResult GenerateOp::verify() {
   // Ensure that the tensor type has as many dynamic dimensions as are
   // specified by the operands.
   RankedTensorType resultType = llvm::cast<RankedTensorType>(getType());
-  if (getNumOperands() != resultType.getNumDynamicDims())
-    return emitError("must have as many index operands as dynamic extents "
-                     "in the result type");
+  if (failed(verifyDynamicDimensionCount(getOperation(), resultType,
+                                         getOperands())))
+    return failure();
   return success();
 }
 
@@ -4039,11 +4037,8 @@ void SplatOp::getAsmResultNames(
 }
 
 LogicalResult SplatOp::verify() {
-  if (getType().getNumDynamicDims() != getDynamicSizes().size())
-    return emitOpError("incorrect number of dynamic sizes, has ")
-           << getDynamicSizes().size() << ", expected "
-           << getType().getNumDynamicDims();
-  return success();
+  return verifyDynamicDimensionCount(getOperation(), getType(),
+                                     getDynamicSizes());
 }
 
 LogicalResult

diff  --git a/mlir/lib/Dialect/Utils/CMakeLists.txt b/mlir/lib/Dialect/Utils/CMakeLists.txt
index f5bb687ae071a..7673da5932304 100644
--- a/mlir/lib/Dialect/Utils/CMakeLists.txt
+++ b/mlir/lib/Dialect/Utils/CMakeLists.txt
@@ -3,6 +3,7 @@ add_mlir_library(MLIRDialectUtils
   ReshapeOpsUtils.cpp
   StructuredOpsUtils.cpp
   StaticValueUtils.cpp
+  VerificationUtils.cpp
 
   DEPENDS
   MLIRDialectUtilsIncGen

diff  --git a/mlir/lib/Dialect/Utils/VerificationUtils.cpp b/mlir/lib/Dialect/Utils/VerificationUtils.cpp
new file mode 100644
index 0000000000000..22b224713a6a3
--- /dev/null
+++ b/mlir/lib/Dialect/Utils/VerificationUtils.cpp
@@ -0,0 +1,22 @@
+//===- VerificationUtils.cpp - Common verification utilities --------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/Utils/VerificationUtils.h"
+
+using namespace mlir;
+
+LogicalResult mlir::verifyDynamicDimensionCount(Operation *op, ShapedType type,
+                                                ValueRange dynamicSizes) {
+  int64_t expectedCount = type.getNumDynamicDims();
+  int64_t actualCount = dynamicSizes.size();
+  if (expectedCount != actualCount) {
+    return op->emitOpError("incorrect number of dynamic sizes, has ")
+           << actualCount << ", expected " << expectedCount;
+  }
+  return success();
+}

diff  --git a/mlir/test/Dialect/Bufferization/invalid.mlir b/mlir/test/Dialect/Bufferization/invalid.mlir
index 9884b040119d0..76aba14bc50f2 100644
--- a/mlir/test/Dialect/Bufferization/invalid.mlir
+++ b/mlir/test/Dialect/Bufferization/invalid.mlir
@@ -2,7 +2,7 @@
 
 func.func @alloc_tensor_missing_dims(%arg0: index)
 {
-  // expected-error @+1 {{expected 2 dynamic sizes}}
+  // expected-error @+1 {{incorrect number of dynamic sizes, has 1, expected 2}}
   %0 = bufferization.alloc_tensor(%arg0) : tensor<4x?x?x5xf32>
   return
 }

diff  --git a/mlir/test/Dialect/GPU/invalid.mlir b/mlir/test/Dialect/GPU/invalid.mlir
index 26bcf948bc85d..5e9c25c36aa79 100644
--- a/mlir/test/Dialect/GPU/invalid.mlir
+++ b/mlir/test/Dialect/GPU/invalid.mlir
@@ -777,7 +777,7 @@ func.func @alloc() {
 // Number of dynamic dimension operand count greater than memref dynamic dimension count.
 func.func @alloc() {
    %0 = arith.constant 7 : index
-   // expected-error at +1 {{dimension operand count does not equal memref dynamic dimension count}}
+   // expected-error at +1 {{incorrect number of dynamic sizes, has 2, expected 1}}
    %1 = gpu.alloc(%0, %0) : memref<2x?xf32, 1>
    return
 }
@@ -787,7 +787,7 @@ func.func @alloc() {
 // Number of dynamic dimension operand count less than memref dynamic dimension count.
 func.func @alloc() {
    %0 = arith.constant 7 : index
-   // expected-error at +1 {{dimension operand count does not equal memref dynamic dimension count}}
+   // expected-error at +1 {{incorrect number of dynamic sizes, has 1, expected 2}}
    %1 = gpu.alloc(%0) : memref<2x?x?xf32, 1>
    return
 }

diff  --git a/mlir/test/Dialect/MemRef/invalid.mlir b/mlir/test/Dialect/MemRef/invalid.mlir
index d10651f363711..2dfe733c13768 100644
--- a/mlir/test/Dialect/MemRef/invalid.mlir
+++ b/mlir/test/Dialect/MemRef/invalid.mlir
@@ -624,7 +624,7 @@ func.func @invalid_view(%arg0 : index, %arg1 : index, %arg2 : index) {
 
 func.func @invalid_view(%arg0 : index, %arg1 : index, %arg2 : index) {
   %0 = memref.alloc() : memref<2048xi8>
-  // expected-error at +1 {{incorrect number of size operands for type}}
+  // expected-error at +1 {{incorrect number of dynamic sizes, has 1, expected 2}}
   %1 = memref.view %0[%arg2][%arg0]
     : memref<2048xi8> to memref<?x?xf32>
   return
@@ -927,7 +927,7 @@ func.func @bad_alloc_wrong_dynamic_dim_count() {
 ^bb0:
   %0 = arith.constant 7 : index
   // Test alloc with wrong number of dynamic dimensions.
-  // expected-error at +1 {{dimension operand count does not equal memref dynamic dimension count}}
+  // expected-error at +1 {{incorrect number of dynamic sizes, has 1, expected 0}}
   %1 = memref.alloc(%0)[%0] : memref<2x4xf32, affine_map<(d0, d1)[s0] -> ((d0 + s0), d1)>, 1>
   return
 }

diff  --git a/mlir/test/Dialect/Tensor/invalid.mlir b/mlir/test/Dialect/Tensor/invalid.mlir
index f36678c3d7589..63be5493e8935 100644
--- a/mlir/test/Dialect/Tensor/invalid.mlir
+++ b/mlir/test/Dialect/Tensor/invalid.mlir
@@ -100,7 +100,7 @@ func.func @tensor.from_elements_wrong_elements_count() {
 
 func.func @tensor.generate(%m : index)
     -> tensor<?x3x?xf32> {
-  // expected-error @+1 {{must have as many index operands as dynamic extents in the result type}}
+  // expected-error @+1 {{incorrect number of dynamic sizes, has 1, expected 2}}
   %tnsr = tensor.generate %m {
     ^bb0(%i : index, %j : index, %k : index):
       %elem = arith.constant 8.0 : f32


        


More information about the Mlir-commits mailing list