[Mlir-commits] [mlir] Add options to generate-runtime-verification to enable faster pass running (PR #160331)
Hanchenng Wu
llvmlistbot at llvm.org
Tue Sep 30 06:41:39 PDT 2025
https://github.com/HanchengWu updated https://github.com/llvm/llvm-project/pull/160331
>From 3b8f7dd45b115d9648d3580eb96c94dbbdd41359 Mon Sep 17 00:00:00 2001
From: Henry Wu <henrywu at mathworks.com>
Date: Tue, 23 Sep 2025 10:51:30 -0400
Subject: [PATCH] Add options to generate-runtime-verification to enable a
faster pass
---
.../RuntimeVerifiableOpInterface.td | 8 +---
mlir/include/mlir/Transforms/Passes.h | 1 +
mlir/include/mlir/Transforms/Passes.td | 8 ++++
.../Transforms/RuntimeOpVerification.cpp | 6 +--
.../Transforms/RuntimeOpVerification.cpp | 40 ++++++++--------
.../Transforms/RuntimeOpVerification.cpp | 23 ++++------
.../RuntimeVerifiableOpInterface.cpp | 26 -----------
.../GenerateRuntimeVerification.cpp | 46 ++++++++++++++++++-
.../Dialect/Linalg/runtime-verification.mlir | 14 ++++++
9 files changed, 101 insertions(+), 71 deletions(-)
diff --git a/mlir/include/mlir/Interfaces/RuntimeVerifiableOpInterface.td b/mlir/include/mlir/Interfaces/RuntimeVerifiableOpInterface.td
index 6fd0df59d9d2e..21104834a9dc3 100644
--- a/mlir/include/mlir/Interfaces/RuntimeVerifiableOpInterface.td
+++ b/mlir/include/mlir/Interfaces/RuntimeVerifiableOpInterface.td
@@ -32,15 +32,11 @@ def RuntimeVerifiableOpInterface : OpInterface<"RuntimeVerifiableOpInterface"> {
/*retTy=*/"void",
/*methodName=*/"generateRuntimeVerification",
/*args=*/(ins "::mlir::OpBuilder &":$builder,
- "::mlir::Location":$loc)
+ "::mlir::Location":$loc,
+ "function_ref<std::string(Operation *, StringRef)>":$generateErrorMessage)
>,
];
- let extraClassDeclaration = [{
- /// Generate the error message that will be printed to the user when
- /// verification fails.
- static std::string generateErrorMessage(Operation *op, const std::string &msg);
- }];
}
#endif // MLIR_INTERFACES_RUNTIMEVERIFIABLEOPINTERFACE
diff --git a/mlir/include/mlir/Transforms/Passes.h b/mlir/include/mlir/Transforms/Passes.h
index 1c035f2a843ff..17c323a042ec2 100644
--- a/mlir/include/mlir/Transforms/Passes.h
+++ b/mlir/include/mlir/Transforms/Passes.h
@@ -47,6 +47,7 @@ class GreedyRewriteConfig;
#define GEN_PASS_DECL_TOPOLOGICALSORT
#define GEN_PASS_DECL_COMPOSITEFIXEDPOINTPASS
#define GEN_PASS_DECL_BUBBLEDOWNMEMORYSPACECASTS
+#define GEN_PASS_DECL_GENERATERUNTIMEVERIFICATION
#include "mlir/Transforms/Passes.h.inc"
/// Creates an instance of the Canonicalizer pass, configured with default
diff --git a/mlir/include/mlir/Transforms/Passes.td b/mlir/include/mlir/Transforms/Passes.td
index b2b7f20a497e3..0cb1eab6ee641 100644
--- a/mlir/include/mlir/Transforms/Passes.td
+++ b/mlir/include/mlir/Transforms/Passes.td
@@ -270,8 +270,16 @@ def GenerateRuntimeVerification : Pass<"generate-runtime-verification"> {
passes that are suspected to introduce faulty IR.
}];
let constructor = "mlir::createGenerateRuntimeVerificationPass()";
+ let options = [
+ Option<"verboseLevel", "verbose-level", "unsigned", /*default=*/"2",
+ "Verbosity level for runtime verification messages: "
+ "0 = Minimum (only source location), "
+ "1 = Basic (include operation type and operand type), "
+ "2 = Detailed (include full operation details, names, types, shapes, etc.)">
+ ];
}
+
def Inliner : Pass<"inline"> {
let summary = "Inline function calls";
let constructor = "mlir::createInlinerPass()";
diff --git a/mlir/lib/Dialect/Linalg/Transforms/RuntimeOpVerification.cpp b/mlir/lib/Dialect/Linalg/Transforms/RuntimeOpVerification.cpp
index eac0e47b18a7d..6c45bccb2b4d4 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/RuntimeOpVerification.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/RuntimeOpVerification.cpp
@@ -32,7 +32,7 @@ struct StructuredOpInterface
: public RuntimeVerifiableOpInterface::ExternalModel<
StructuredOpInterface<T>, T> {
void generateRuntimeVerification(Operation *op, OpBuilder &builder,
- Location loc) const {
+ Location loc, function_ref<std::string(Operation *, StringRef)> generateErrorMessage) const {
auto linalgOp = llvm::cast<LinalgOp>(op);
SmallVector<Range> loopRanges = linalgOp.createLoopRanges(builder, loc);
@@ -70,7 +70,7 @@ struct StructuredOpInterface
builder.createOrFold<index::MinSOp>(loc, startIndex, endIndex);
auto cmpOp = builder.createOrFold<index::CmpOp>(
loc, index::IndexCmpPredicate::SGE, min, zero);
- auto msg = RuntimeVerifiableOpInterface::generateErrorMessage(
+ auto msg = generateErrorMessage(
linalgOp, "unexpected negative result on dimension #" +
std::to_string(dim) + " of input/output operand #" +
std::to_string(opOperand.getOperandNumber()));
@@ -100,7 +100,7 @@ struct StructuredOpInterface
cmpOp = builder.createOrFold<index::CmpOp>(
loc, predicate, inferredDimSize, actualDimSize);
- msg = RuntimeVerifiableOpInterface::generateErrorMessage(
+ msg = generateErrorMessage(
linalgOp, "dimension #" + std::to_string(dim) +
" of input/output operand #" +
std::to_string(opOperand.getOperandNumber()) +
diff --git a/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp b/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp
index d3a77c026379e..66d4df2304e13 100644
--- a/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp
+++ b/mlir/lib/Dialect/MemRef/Transforms/RuntimeOpVerification.cpp
@@ -38,7 +38,7 @@ struct AssumeAlignmentOpInterface
: public RuntimeVerifiableOpInterface::ExternalModel<
AssumeAlignmentOpInterface, AssumeAlignmentOp> {
void generateRuntimeVerification(Operation *op, OpBuilder &builder,
- Location loc) const {
+ Location loc, function_ref<std::string(Operation *, StringRef)> generateErrorMessage) const {
auto assumeOp = cast<AssumeAlignmentOp>(op);
Value ptr = ExtractAlignedPointerAsIndexOp::create(builder, loc,
assumeOp.getMemref());
@@ -49,7 +49,7 @@ struct AssumeAlignmentOpInterface
arith::CmpIOp::create(builder, loc, arith::CmpIPredicate::eq, rest,
arith::ConstantIndexOp::create(builder, loc, 0));
cf::AssertOp::create(builder, loc, isAligned,
- RuntimeVerifiableOpInterface::generateErrorMessage(
+ generateErrorMessage(
op, "memref is not aligned to " +
std::to_string(assumeOp.getAlignment())));
}
@@ -59,7 +59,7 @@ struct CastOpInterface
: public RuntimeVerifiableOpInterface::ExternalModel<CastOpInterface,
CastOp> {
void generateRuntimeVerification(Operation *op, OpBuilder &builder,
- Location loc) const {
+ Location loc, function_ref<std::string(Operation *, StringRef)> generateErrorMessage) const {
auto castOp = cast<CastOp>(op);
auto srcType = cast<BaseMemRefType>(castOp.getSource().getType());
@@ -76,8 +76,7 @@ struct CastOpInterface
Value isSameRank = arith::CmpIOp::create(
builder, loc, arith::CmpIPredicate::eq, srcRank, resultRank);
cf::AssertOp::create(builder, loc, isSameRank,
- RuntimeVerifiableOpInterface::generateErrorMessage(
- op, "rank mismatch"));
+ generateErrorMessage(op, "rank mismatch"));
}
// Get source offset and strides. We do not have an op to get offsets and
@@ -116,7 +115,7 @@ struct CastOpInterface
builder, loc, arith::CmpIPredicate::eq, srcDimSz, resultDimSz);
cf::AssertOp::create(
builder, loc, isSameSz,
- RuntimeVerifiableOpInterface::generateErrorMessage(
+ generateErrorMessage(
op, "size mismatch of dim " + std::to_string(it.index())));
}
@@ -135,8 +134,7 @@ struct CastOpInterface
Value isSameOffset = arith::CmpIOp::create(
builder, loc, arith::CmpIPredicate::eq, srcOffset, resultOffsetVal);
cf::AssertOp::create(builder, loc, isSameOffset,
- RuntimeVerifiableOpInterface::generateErrorMessage(
- op, "offset mismatch"));
+ generateErrorMessage(op, "offset mismatch"));
}
// Check strides.
@@ -153,7 +151,7 @@ struct CastOpInterface
builder, loc, arith::CmpIPredicate::eq, srcStride, resultStrideVal);
cf::AssertOp::create(
builder, loc, isSameStride,
- RuntimeVerifiableOpInterface::generateErrorMessage(
+ generateErrorMessage(
op, "stride mismatch of dim " + std::to_string(it.index())));
}
}
@@ -163,7 +161,7 @@ struct CopyOpInterface
: public RuntimeVerifiableOpInterface::ExternalModel<CopyOpInterface,
CopyOp> {
void generateRuntimeVerification(Operation *op, OpBuilder &builder,
- Location loc) const {
+ Location loc, function_ref<std::string(Operation *, StringRef)> generateErrorMessage) const {
auto copyOp = cast<CopyOp>(op);
BaseMemRefType sourceType = copyOp.getSource().getType();
BaseMemRefType targetType = copyOp.getTarget().getType();
@@ -194,7 +192,7 @@ struct CopyOpInterface
Value sameDimSize = arith::CmpIOp::create(
builder, loc, arith::CmpIPredicate::eq, sourceDim, targetDim);
cf::AssertOp::create(builder, loc, sameDimSize,
- RuntimeVerifiableOpInterface::generateErrorMessage(
+ generateErrorMessage(
op, "size of " + std::to_string(i) +
"-th source/target dim does not match"));
}
@@ -205,15 +203,14 @@ struct DimOpInterface
: public RuntimeVerifiableOpInterface::ExternalModel<DimOpInterface,
DimOp> {
void generateRuntimeVerification(Operation *op, OpBuilder &builder,
- Location loc) const {
+ Location loc, function_ref<std::string(Operation *, StringRef)> generateErrorMessage) const {
auto dimOp = cast<DimOp>(op);
Value rank = RankOp::create(builder, loc, dimOp.getSource());
Value zero = arith::ConstantIndexOp::create(builder, loc, 0);
cf::AssertOp::create(
builder, loc,
generateInBoundsCheck(builder, loc, dimOp.getIndex(), zero, rank),
- RuntimeVerifiableOpInterface::generateErrorMessage(
- op, "index is out of bounds"));
+ generateErrorMessage(op, "index is out of bounds"));
}
};
@@ -224,7 +221,7 @@ struct LoadStoreOpInterface
: public RuntimeVerifiableOpInterface::ExternalModel<
LoadStoreOpInterface<LoadStoreOp>, LoadStoreOp> {
void generateRuntimeVerification(Operation *op, OpBuilder &builder,
- Location loc) const {
+ Location loc, function_ref<std::string(Operation *, StringRef)> generateErrorMessage) const {
auto loadStoreOp = cast<LoadStoreOp>(op);
auto memref = loadStoreOp.getMemref();
@@ -245,8 +242,7 @@ struct LoadStoreOpInterface
: inBounds;
}
cf::AssertOp::create(builder, loc, assertCond,
- RuntimeVerifiableOpInterface::generateErrorMessage(
- op, "out-of-bounds access"));
+ generateErrorMessage(op, "out-of-bounds access"));
}
};
@@ -254,7 +250,7 @@ struct SubViewOpInterface
: public RuntimeVerifiableOpInterface::ExternalModel<SubViewOpInterface,
SubViewOp> {
void generateRuntimeVerification(Operation *op, OpBuilder &builder,
- Location loc) const {
+ Location loc, function_ref<std::string(Operation *, StringRef)> generateErrorMessage) const {
auto subView = cast<SubViewOp>(op);
MemRefType sourceType = subView.getSource().getType();
@@ -279,7 +275,7 @@ struct SubViewOpInterface
generateInBoundsCheck(builder, loc, offset, zero, dimSize);
cf::AssertOp::create(
builder, loc, offsetInBounds,
- RuntimeVerifiableOpInterface::generateErrorMessage(
+ generateErrorMessage(
op, "offset " + std::to_string(i) + " is out-of-bounds"));
// Verify that slice does not run out-of-bounds.
@@ -292,7 +288,7 @@ struct SubViewOpInterface
generateInBoundsCheck(builder, loc, lastPos, zero, dimSize);
cf::AssertOp::create(
builder, loc, lastPosInBounds,
- RuntimeVerifiableOpInterface::generateErrorMessage(
+ generateErrorMessage(
op, "subview runs out-of-bounds along dimension " +
std::to_string(i)));
}
@@ -303,7 +299,7 @@ struct ExpandShapeOpInterface
: public RuntimeVerifiableOpInterface::ExternalModel<ExpandShapeOpInterface,
ExpandShapeOp> {
void generateRuntimeVerification(Operation *op, OpBuilder &builder,
- Location loc) const {
+ Location loc, function_ref<std::string(Operation *, StringRef)> generateErrorMessage) const {
auto expandShapeOp = cast<ExpandShapeOp>(op);
// Verify that the expanded dim sizes are a product of the collapsed dim
@@ -334,7 +330,7 @@ struct ExpandShapeOpInterface
builder, loc, arith::CmpIPredicate::eq, mod,
arith::ConstantIndexOp::create(builder, loc, 0));
cf::AssertOp::create(builder, loc, isModZero,
- RuntimeVerifiableOpInterface::generateErrorMessage(
+ generateErrorMessage(
op, "static result dims in reassoc group do not "
"divide src dim evenly"));
}
diff --git a/mlir/lib/Dialect/Tensor/Transforms/RuntimeOpVerification.cpp b/mlir/lib/Dialect/Tensor/Transforms/RuntimeOpVerification.cpp
index 838ff1f987c63..fd51f50101c2e 100644
--- a/mlir/lib/Dialect/Tensor/Transforms/RuntimeOpVerification.cpp
+++ b/mlir/lib/Dialect/Tensor/Transforms/RuntimeOpVerification.cpp
@@ -36,7 +36,7 @@ struct CastOpInterface
: public RuntimeVerifiableOpInterface::ExternalModel<CastOpInterface,
CastOp> {
void generateRuntimeVerification(Operation *op, OpBuilder &builder,
- Location loc) const {
+ Location loc, function_ref<std::string(Operation *, StringRef)> generateErrorMessage) const {
auto castOp = cast<CastOp>(op);
auto srcType = cast<TensorType>(castOp.getSource().getType());
@@ -53,8 +53,7 @@ struct CastOpInterface
Value isSameRank = arith::CmpIOp::create(
builder, loc, arith::CmpIPredicate::eq, srcRank, resultRank);
cf::AssertOp::create(builder, loc, isSameRank,
- RuntimeVerifiableOpInterface::generateErrorMessage(
- op, "rank mismatch"));
+ generateErrorMessage(op, "rank mismatch"));
}
// Check dimension sizes.
@@ -76,7 +75,7 @@ struct CastOpInterface
builder, loc, arith::CmpIPredicate::eq, srcDimSz, resultDimSz);
cf::AssertOp::create(
builder, loc, isSameSz,
- RuntimeVerifiableOpInterface::generateErrorMessage(
+ generateErrorMessage(
op, "size mismatch of dim " + std::to_string(it.index())));
}
}
@@ -86,15 +85,14 @@ struct DimOpInterface
: public RuntimeVerifiableOpInterface::ExternalModel<DimOpInterface,
DimOp> {
void generateRuntimeVerification(Operation *op, OpBuilder &builder,
- Location loc) const {
+ Location loc, function_ref<std::string(Operation *, StringRef)> generateErrorMessage) const {
auto dimOp = cast<DimOp>(op);
Value rank = RankOp::create(builder, loc, dimOp.getSource());
Value zero = arith::ConstantIndexOp::create(builder, loc, 0);
cf::AssertOp::create(
builder, loc,
generateInBoundsCheck(builder, loc, dimOp.getIndex(), zero, rank),
- RuntimeVerifiableOpInterface::generateErrorMessage(
- op, "index is out of bounds"));
+ generateErrorMessage(op, "index is out of bounds"));
}
};
@@ -105,7 +103,7 @@ struct ExtractInsertOpInterface
: public RuntimeVerifiableOpInterface::ExternalModel<
ExtractInsertOpInterface<OpTy>, OpTy> {
void generateRuntimeVerification(Operation *op, OpBuilder &builder,
- Location loc) const {
+ Location loc, function_ref<std::string(Operation *, StringRef)> generateErrorMessage) const {
auto extractInsertOp = cast<OpTy>(op);
Value tensor;
@@ -135,8 +133,7 @@ struct ExtractInsertOpInterface
: inBounds;
}
cf::AssertOp::create(builder, loc, assertCond,
- RuntimeVerifiableOpInterface::generateErrorMessage(
- op, "out-of-bounds access"));
+ generateErrorMessage(op, "out-of-bounds access"));
}
};
@@ -144,7 +141,7 @@ struct ExtractSliceOpInterface
: public RuntimeVerifiableOpInterface::ExternalModel<
ExtractSliceOpInterface, ExtractSliceOp> {
void generateRuntimeVerification(Operation *op, OpBuilder &builder,
- Location loc) const {
+ Location loc, function_ref<std::string(Operation *, StringRef)> generateErrorMessage) const {
auto extractSliceOp = cast<ExtractSliceOp>(op);
RankedTensorType sourceType = extractSliceOp.getSource().getType();
@@ -168,7 +165,7 @@ struct ExtractSliceOpInterface
generateInBoundsCheck(builder, loc, offset, zero, dimSize);
cf::AssertOp::create(
builder, loc, offsetInBounds,
- RuntimeVerifiableOpInterface::generateErrorMessage(
+ generateErrorMessage(
op, "offset " + std::to_string(i) + " is out-of-bounds"));
// Verify that slice does not run out-of-bounds.
@@ -181,7 +178,7 @@ struct ExtractSliceOpInterface
generateInBoundsCheck(builder, loc, lastPos, zero, dimSize);
cf::AssertOp::create(
builder, loc, lastPosInBounds,
- RuntimeVerifiableOpInterface::generateErrorMessage(
+ generateErrorMessage(
op, "extract_slice runs out-of-bounds along dimension " +
std::to_string(i)));
}
diff --git a/mlir/lib/Interfaces/RuntimeVerifiableOpInterface.cpp b/mlir/lib/Interfaces/RuntimeVerifiableOpInterface.cpp
index 8aa194befb420..f9a54f950d7ff 100644
--- a/mlir/lib/Interfaces/RuntimeVerifiableOpInterface.cpp
+++ b/mlir/lib/Interfaces/RuntimeVerifiableOpInterface.cpp
@@ -8,31 +8,5 @@
#include "mlir/Interfaces/RuntimeVerifiableOpInterface.h"
-namespace mlir {
-class Location;
-class OpBuilder;
-
-/// Generate an error message string for the given op and the specified error.
-std::string
-RuntimeVerifiableOpInterface::generateErrorMessage(Operation *op,
- const std::string &msg) {
- std::string buffer;
- llvm::raw_string_ostream stream(buffer);
- OpPrintingFlags flags;
- // We may generate a lot of error messages and so we need to ensure the
- // printing is fast.
- flags.elideLargeElementsAttrs();
- flags.printGenericOpForm();
- flags.skipRegions();
- flags.useLocalScope();
- stream << "ERROR: Runtime op verification failed\n";
- op->print(stream, flags);
- stream << "\n^ " << msg;
- stream << "\nLocation: ";
- op->getLoc().print(stream);
- return buffer;
-}
-} // namespace mlir
-
/// Include the definitions of the interface.
#include "mlir/Interfaces/RuntimeVerifiableOpInterface.cpp.inc"
diff --git a/mlir/lib/Transforms/GenerateRuntimeVerification.cpp b/mlir/lib/Transforms/GenerateRuntimeVerification.cpp
index a40bc2b3272fc..e3098a4c6e7f9 100644
--- a/mlir/lib/Transforms/GenerateRuntimeVerification.cpp
+++ b/mlir/lib/Transforms/GenerateRuntimeVerification.cpp
@@ -28,6 +28,14 @@ struct GenerateRuntimeVerificationPass
} // namespace
void GenerateRuntimeVerificationPass::runOnOperation() {
+ // Check verboseLevel is in range [0, 2].
+ if (verboseLevel > 2) {
+ getOperation()->emitError(
+ "generate-runtime-verification pass: set verboseLevel to 0, 1 or 2");
+ signalPassFailure();
+ return;
+ }
+
// The implementation of the RuntimeVerifiableOpInterface may create ops that
// can be verified. We don't want to generate verification for IR that
// performs verification, so gather all runtime-verifiable ops first.
@@ -36,10 +44,46 @@ void GenerateRuntimeVerificationPass::runOnOperation() {
ops.push_back(verifiableOp);
});
+ // Create error message generator based on verboseLevel
+ auto errorMsgGenerator = [vLevel = verboseLevel.getValue()](Operation *op, StringRef msg) -> std::string {
+ std::string buffer;
+ llvm::raw_string_ostream stream(buffer);
+ OpPrintingFlags flags;
+ // We may generate a lot of error messages and so we need to ensure the
+ // printing is fast.
+ flags.elideLargeElementsAttrs();
+ flags.printGenericOpForm();
+ flags.skipRegions();
+ flags.useLocalScope();
+ stream << "ERROR: Runtime op verification failed\n";
+ if (vLevel == 2) {
+ // print full op including operand names, very expensive
+ op->print(stream, flags);
+ stream << "\n " << msg;
+ } else if (vLevel == 1) {
+ // print op name and operand types
+ stream << "Op: " << op->getName().getStringRef() << "\n";
+ stream << "Operand Types:";
+ for (const auto &operand : op->getOpOperands()) {
+ stream << " " << operand.get().getType();
+ }
+ stream << "\n" << msg;
+ stream << "Result Types:";
+ for (const auto &result : op->getResults()) {
+ stream << " " << result.getType();
+ }
+ }
+ // all verbose levels include location
+ stream << "^\nLocation: ";
+ op->getLoc().print(stream);
+ return buffer;
+ };
+
OpBuilder builder(getOperation()->getContext());
for (RuntimeVerifiableOpInterface verifiableOp : ops) {
builder.setInsertionPoint(verifiableOp);
- verifiableOp.generateRuntimeVerification(builder, verifiableOp.getLoc());
+ verifiableOp.generateRuntimeVerification(builder, verifiableOp.getLoc(),
+ errorMsgGenerator);
};
}
diff --git a/mlir/test/Dialect/Linalg/runtime-verification.mlir b/mlir/test/Dialect/Linalg/runtime-verification.mlir
index a4f29d8457e58..238169adf496e 100644
--- a/mlir/test/Dialect/Linalg/runtime-verification.mlir
+++ b/mlir/test/Dialect/Linalg/runtime-verification.mlir
@@ -1,13 +1,25 @@
// RUN: mlir-opt %s -generate-runtime-verification | FileCheck %s
+// RUN: mlir-opt %s --generate-runtime-verification="verbose-level=1" | FileCheck %s --check-prefix=VERBOSE1
+// RUN: mlir-opt %s --generate-runtime-verification="verbose-level=0" | FileCheck %s --check-prefix=VERBOSE0
// Most of the tests for linalg runtime-verification are implemented as integration tests.
#identity = affine_map<(d0) -> (d0)>
// CHECK-LABEL: @static_dims
+// VERBOSE1-LABEL: @static_dims
+// VERBOSE0-LABEL: @static_dims
func.func @static_dims(%arg0: tensor<5xf32>, %arg1: tensor<5xf32>) -> (tensor<5xf32>) {
// CHECK: %[[TRUE:.*]] = index.bool.constant true
// CHECK: cf.assert %[[TRUE]]
+ // VERBOSE1: %[[TRUE:.*]] = index.bool.constant true
+ // VERBOSE1: cf.assert %[[TRUE]]
+ // VERBOSE1: Operand Types: tensor<5xf32> tensor<5xf32> tensor<5xf32>
+ // VERBOSE1: Result Types
+ // VERBOSE1: Location: loc
+ // VERBOSE0-NOT: Operand Types: tensor<5xf32> tensor<5xf32> tensor<5xf32>
+ // VERBOSE0-NOT: Result Types
+ // VERBOSE0: Location: loc
%result = tensor.empty() : tensor<5xf32>
%0 = linalg.generic {
indexing_maps = [#identity, #identity, #identity],
@@ -26,9 +38,11 @@ func.func @static_dims(%arg0: tensor<5xf32>, %arg1: tensor<5xf32>) -> (tensor<5x
#map = affine_map<() -> ()>
// CHECK-LABEL: @scalars
+// VERBOSE1-LABEL: @scalars
func.func @scalars(%arg0: tensor<f32>, %arg1: tensor<f32>) -> (tensor<f32>) {
// No runtime checks are required if the operands are all scalars
// CHECK-NOT: cf.assert
+ // VERBOSE1-NOT: cf.assert
%result = tensor.empty() : tensor<f32>
%0 = linalg.generic {
indexing_maps = [#map, #map, #map],
More information about the Mlir-commits
mailing list