[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 02:41:40 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 &region,
   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