[GlobalOpt] Fix crash in RaiseSpecialOps on buffer-semantics named ops (#24626)
## Problem
Passing a `linalg.matmul` (or any named contraction/convolution op) with
**memref / buffer operands** to `iree-compile` crashes with a hard
assert instead of a clean diagnostic:
```
Assertion failed: (index < size() && "invalid index into type range"),
function operator[], file TypeRange.h, line 156.
...
NamedImplicitCastOpConversion<linalg::ContractionOpInterface>::matchAndRewrite(...)
```
`NamedImplicitCastOpConversion::matchAndRewrite` in
`GlobalOptimization/RaiseSpecialOps.cpp` reasons about the op's results
(`getResultTypes()[0]`) and rewrites its body region, both of which
assume tensor semantics. A buffer-semantics linalg op writes to an
output buffer and has **zero results**, so `getResultTypes()[0]` indexes
an empty `TypeRange` and aborts.
## Fix
Bail out via `hasPureTensorSemantics()` before touching results,
matching the guards already used elsewhere in this file (e.g. lines 48,
231). The op is left untouched and compilation proceeds normally.
## Verification (local, llvm-cpu)
A/B on identical current `main` sources, exact reproducer from the
issue:
| Build | `iree-compile ... memref matmul` |
|---|---|
| unfixed (`main`) | exit **134**, assert in
`NamedImplicitCastOpConversion` |
| fixed (this PR) | exit **0**, compiles cleanly to a valid `.vmfb` |
- Added lit test `@matmul_memref_no_crash` in `raise_special_ops.mlir`.
- Full `raise_special_ops.mlir` lit suite passes.
Fixes #24624
Signed-off-by: Alex-Wengg <hanweng9@gmail.com>
diff --git a/compiler/src/iree/compiler/GlobalOptimization/RaiseSpecialOps.cpp b/compiler/src/iree/compiler/GlobalOptimization/RaiseSpecialOps.cpp
index 4077d76..3ca4d33 100644
--- a/compiler/src/iree/compiler/GlobalOptimization/RaiseSpecialOps.cpp
+++ b/compiler/src/iree/compiler/GlobalOptimization/RaiseSpecialOps.cpp
@@ -284,6 +284,12 @@
return failure();
}
+ auto linalgOp = dyn_cast<linalg::LinalgOp>(namedOp.getOperation());
+ if (!linalgOp || !linalgOp.hasPureTensorSemantics()) {
+ return rewriter.notifyMatchFailure(
+ namedOp, "expected an op with pure tensor semantics");
+ }
+
// Look for a producer of the given operand that does an elementwise extend
// and replace the operand with the source of the elementwise producer.
// Returns true if the operand was updated to inform the pattern rewriter
diff --git a/compiler/src/iree/compiler/GlobalOptimization/test/raise_special_ops.mlir b/compiler/src/iree/compiler/GlobalOptimization/test/raise_special_ops.mlir
index 877b169..6b3e22a 100644
--- a/compiler/src/iree/compiler/GlobalOptimization/test/raise_special_ops.mlir
+++ b/compiler/src/iree/compiler/GlobalOptimization/test/raise_special_ops.mlir
@@ -921,3 +921,15 @@
// CHECK: %[[PAD:.+]] = tensor.pad %[[ARG0]] low[1, 2] high[%[[H0]], %[[H1]]]
// CHECK: tensor.yield %[[C1]]
// CHECK: util.return %[[PAD]]
+
+// -----
+
+util.func public @matmul_memref_no_crash(%arg0: memref<10x20xf32>,
+ %arg1: memref<20x40xf32>, %arg2: memref<10x40xf32>) {
+ linalg.matmul ins(%arg0, %arg1 : memref<10x20xf32>, memref<20x40xf32>)
+ outs(%arg2 : memref<10x40xf32>)
+ util.return
+}
+// CHECK-LABEL: util.func public @matmul_memref_no_crash
+// CHECK: linalg.matmul
+// CHECK: util.return