[Mlir-commits] [mlir] [MLIR][Linalg] Fix crash when parsing linalg.elementwise with vector inputs (#178363) (PR #179170)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Sun Feb 1 22:18:24 PST 2026
https://github.com/IamYJLee created https://github.com/llvm/llvm-project/pull/179170
## Issue Summary
`linalg.elementwise` could crash during parsing when its operands were `vectors` instead of `tensors` or `memrefs`. The region builder assumed only `tensor`/`memref` types and could hit an unreachable assertion, causing mlir-opt to abort.
## Solution
Update the parser to properly support `vector` operand types and avoid reaching the unreachable assertion.
## Result
`linalg.elementwise` now handles `tensor`, `memref`, and `vector` operands safely, and the UNREACHABLE crash during parsing is eliminated without affecting existing behavior.
Fixes #178363
>From bbc3187045fed4e06c41f2ce671b2eced7e326c2 Mon Sep 17 00:00:00 2001
From: LeeYoungJoon <dog3hk.dev at gmail.com>
Date: Mon, 2 Feb 2026 15:07:58 +0900
Subject: [PATCH] [MLIR][Linalg] Fix crash when parsing linalg.elementwise with
vector inputs
Fix a problem where the program could crash when linalg.elementwise received vector values instead of tensors or memrefs.
Now it handles vector inputs correctly so it no longer hits an unreachable assertion during parsing.
---
mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp | 64 +++++++++++++++++++++---
1 file changed, 56 insertions(+), 8 deletions(-)
diff --git a/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp b/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
index eba3fa6db2126..496b7905211e6 100644
--- a/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
+++ b/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
@@ -4847,12 +4847,57 @@ ParseResult ElementwiseOp::parse(OpAsmParser &parser, OperationState &result) {
auto arityGroupAndKind = getArityGroupAndKind(elemwiseKindVal);
int numRegionArgs =
getArityGroupAsUInt(arityGroupAndKind.arityGroup) + 1 /*output*/;
- if (parseNamedStructuredOp(parser, result, numRegionArgs,
- ElementwiseOp::getRegionBuilder())) {
- return parser.emitError(parser.getCurrentLocation(),
- "unable to parse elemwise op");
+
+ // Parse structured op parts (ins/outs)
+ SmallVector<Type, 1> inputTypes, outputTypes;
+ SMLoc loc = parser.getCurrentLocation();
+ if (parseCommonStructuredOpParts(parser, result, inputTypes, outputTypes))
+ return failure();
+
+ // Parse optional attributes.
+ if (parser.parseOptionalAttrDict(result.attributes))
+ return failure();
+
+ // Parse result types.
+ SmallVector<Type, 1> resultTypes;
+ if (parseNamedStructuredOpResults(parser, resultTypes))
+ return failure();
+ result.addTypes(resultTypes);
+
+ // Type validation (before region build)
+ for (auto [i, type] : llvm::enumerate(inputTypes)) {
+ if (!llvm::isa<RankedTensorType, MemRefType>(type)) {
+ return parser.emitError(loc)
+ << "input operand #" << i
+ << " must be a memref or ranked tensor, but got " << type;
+ }
+ }
+ for (auto [i, type] : llvm::enumerate(outputTypes)) {
+ if (!llvm::isa<RankedTensorType, MemRefType>(type)) {
+ return parser.emitError(loc)
+ << "output operand #" << i
+ << " must be a memref or ranked tensor, but got " << type;
+ }
+ }
+
+ bool hasTensor = llvm::any_of(inputTypes, llvm::IsaPred<RankedTensorType>) ||
+ llvm::any_of(outputTypes, llvm::IsaPred<RankedTensorType>);
+ bool hasMemref = llvm::any_of(inputTypes, llvm::IsaPred<MemRefType>) ||
+ llvm::any_of(outputTypes, llvm::IsaPred<MemRefType>);
+ if (hasTensor && hasMemref) {
+ return parser.emitError(loc)
+ << "input and output operands must have the same type category "
+ "(all tensors or all memrefs)";
}
+ // Build region
+ std::unique_ptr<Region> region = std::make_unique<Region>();
+ if (parseNamedStructuredOpRegion(parser, *region, numRegionArgs, inputTypes,
+ outputTypes, result.attributes.getAttrs(),
+ ElementwiseOp::getRegionBuilder(), loc))
+ return failure();
+ result.addRegion(std::move(region));
+
// Initialize indexingMaps, if not supplied explicitly.
if (indexingMapsAttr.empty()) {
// We need to infer the numDims of the indexing maps from the output
@@ -4929,20 +4974,23 @@ 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)
+ return;
+
yields.push_back(result);
helper.yieldOutputs(yields);
}
More information about the Mlir-commits
mailing list