[Mlir-commits] [mlir] [mlir][linalg] Diagnose non-tensor/memref operands in structured region build (PR #235746)
Chanj Wons
llvmlistbot at llvm.org
Thu Oct 29 09:04:16 PDT 2026
https://github.com/wonschangge updated https://github.com/llvm/llvm-project/pull/235746
>From 0e8f60e1b41e26910bf8349667ba46f3d641edae Mon Sep 17 00:00:00 2001
From: Chanj Wons <892108131 at qq.com>
Date: Mon, 26 Oct 2026 18:56:10 +0800
Subject: [PATCH] [mlir][linalg] Diagnose non-tensor/memref operands in
structured region build
Passing a vector (or other non-tensor/memref shaped type) into a structured op
such as linalg.elementwise used to reach llvm_unreachable inside the region
builder. Reject those operand types when parsing (via emitError) and thread
emitError through ElementwiseOp::regionBuilder so unsupported numeric cases
also produce diagnostics instead of aborting.
Fixes #178363
---
mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp | 29 ++++++++++++++++++------
mlir/test/Dialect/Linalg/invalid.mlir | 24 ++++++++++++++++++++
2 files changed, 46 insertions(+), 7 deletions(-)
diff --git a/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp b/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
index 3c9797cc6acb5c..195b0f0f2d6239 100644
--- a/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
+++ b/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
@@ -150,6 +150,16 @@ static void fillStructuredOpRegion(OpBuilder &opBuilder, Region ®ion,
SmallVector<Location, 8> argLocs;
for (auto containers : {inputTypes, outputTypes}) {
for (auto t : containers) {
+ // Structured ops operate on tensor/memref containers (or scalars). Other
+ // shaped types such as vectors are not supported and previously hit an
+ // llvm_unreachable inside the region builder.
+ if (isa<ShapedType>(t) && !isa<MemRefType, RankedTensorType>(t)) {
+ if (emitError) {
+ emitError() << "expected tensor or memref operand, got " << t;
+ return;
+ }
+ llvm_unreachable("expected tensor or memref shaped operand");
+ }
argTypes.push_back(
isa<MemRefType, RankedTensorType>(t) ? getElementTypeOrSelf(t) : t);
@@ -5194,11 +5204,10 @@ ParseResult ElementwiseOp::parse(OpAsmParser &parser, OperationState &result) {
auto arityGroupAndKind = getArityGroupAndKind(elemwiseKindVal);
int numRegionArgs =
getArityGroupAsUInt(arityGroupAndKind.arityGroup) + 1 /*output*/;
+ // parseNamedStructuredOp already emits a diagnostic on failure.
if (parseNamedStructuredOp(parser, result, numRegionArgs,
- ElementwiseOp::getRegionBuilder())) {
- return parser.emitError(parser.getCurrentLocation(),
- "unable to parse elemwise op");
- }
+ ElementwiseOp::getRegionBuilder()))
+ return failure();
// Initialize indexingMaps, if not supplied explicitly.
if (indexingMapsAttr.empty()) {
@@ -5286,20 +5295,26 @@ void ElementwiseOp::regionBuilder(
Value result;
if (arityGroup == ElementwiseArityGroup::Unary) {
- result = helper.buildUnaryFn(kind.unaryFn, block.getArgument(0));
+ result = helper.buildUnaryFn(kind.unaryFn, block.getArgument(0), emitError);
} else if (arityGroup == ElementwiseArityGroup::Binary) {
result = helper.buildBinaryFn(kind.binaryFn, block.getArgument(0),
- block.getArgument(1));
+ block.getArgument(1), emitError);
} else if (arityGroup == ElementwiseArityGroup::Ternary) {
result = helper.buildTernaryFn(kind.ternaryFn, block.getArgument(0),
- block.getArgument(1), block.getArgument(2));
+ block.getArgument(1), block.getArgument(2),
+ emitError);
} else {
assert(false && "found unhandled category in elemwise");
}
+ if (!result) {
+ // emitError already reported the problem (if provided).
+ return;
+ }
+
yields.push_back(result);
helper.yieldOutputs(yields);
}
diff --git a/mlir/test/Dialect/Linalg/invalid.mlir b/mlir/test/Dialect/Linalg/invalid.mlir
index 70b375ef24941b..d626d8f4068d5b 100644
--- a/mlir/test/Dialect/Linalg/invalid.mlir
+++ b/mlir/test/Dialect/Linalg/invalid.mlir
@@ -2466,3 +2466,27 @@ func.func @reduce_no_inputs() {
}
func.return
}
+
+
+
+// -----
+
+// Vectors are shaped types but not supported by structured Linalg ops.
+// Previously this hit llvm_unreachable in the elementwise region builder.
+func.func @elementwise_vector_operands(%v: vector<4xf32>, %o: tensor<4xf32>) -> tensor<4xf32> {
+ %r = linalg.elementwise kind=#linalg.elementwise_kind<add>
+ // expected-error at +1 {{expected tensor or memref operand, got 'vector<4xf32>'}}
+ ins(%v, %v : vector<4xf32>, vector<4xf32>)
+ outs(%o : tensor<4xf32>) -> tensor<4xf32>
+ return %r : tensor<4xf32>
+}
+
+// -----
+
+func.func @elementwise_vector_input_tensor_output(%v: vector<4xf32>, %o: tensor<4xf32>) -> tensor<4xf32> {
+ %r = linalg.elementwise kind=#linalg.elementwise_kind<exp>
+ // expected-error at +1 {{expected tensor or memref operand, got 'vector<4xf32>'}}
+ ins(%v : vector<4xf32>)
+ outs(%o : tensor<4xf32>) -> tensor<4xf32>
+ return %r : tensor<4xf32>
+}
More information about the Mlir-commits
mailing list