[Mlir-commits] [mlir] [MLIR][Transform] Fix crash in transform.structured.split with zero-result operations (PR #204363)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed Jun 17 07:57:11 PDT 2026


https://github.com/JasonHonKL created https://github.com/llvm/llvm-project/pull/204363

### Problem:
transform.structured.split crashes when the dynamic chunk size handle points to an operation with no results (e.g., a void function call).

### Root Cause:
In SplitOp::apply(), the code unconditionally accesses op->getResult(0) after detecting an error condition, causing an assertion failure when the operation has 0 results:

```c++
if (op->getNumResults() != 1 || !op->getResult(0).getType().isIndex()) {
  diag = emitSilenceableError()...  // Sets error
}
return OpFoldResult(op->getResult(0));  // Always executes → CRASH
```

Solution:

Split the validation into two separate checks with early returns to prevent accessing invalid result indices:

1. First check if operation has exactly 1 result
2. If not, return empty OpFoldResult()
3. Then safely check if result type is index
4. If not, return empty OpFoldResult()
5. Only access getResult(0) when safe


Testing:
Before fix:

```
Aborted (core dumped)
Assertion `resultNumber < getNumResults()' failed
```

After fix:

```
error: expected dynamic split point handle to point to a single-result index-typed op
  --> test.mlir:7:12
   |
 7 |   %2 = transform.structured.split %0 after %1  {dimension = 0 : i64}
   |                                   ^^
note: dynamic split point
  --> test.mlir:16:5
    |
 16 |   call @m0() : () -> ()
    |   ^
```
Changes:

- Modified mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp
- Split error validation into two separate checks
- Added early returns to prevent invalid result access
- Now provides clear error message instead of crashing

>From da2c7186b0ae506ff3d5a00b47b002a069af3d28 Mon Sep 17 00:00:00 2001
From: JasonHonKL <j2004nol at gmail.com>
Date: Wed, 17 Jun 2026 22:53:36 +0800
Subject: [PATCH] Fix crash in transform.structured.split when operation has 0
 results

The split operation would crash when trying to access getResult(0) on
an operation with no results (like a void function call). This fix
splits the validation into two separate checks with early returns to
prevent accessing invalid result indices.

Fixes crash where:
- transform.structured.split receives operation with 0 results
- Code unconditionally accesses op->getResult(0)
- Assertion failure: resultNumber out of range

Now returns proper error message instead of crashing.
---
 .../Linalg/TransformOps/LinalgTransformOps.cpp    | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp b/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp
index f44693096b26b..aa55d39e1af23 100644
--- a/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp
+++ b/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp
@@ -2882,13 +2882,22 @@ SplitOp::apply(transform::TransformRewriter &rewriter,
     if (isa<TransformHandleTypeInterface>(getDynamicChunkSizes().getType())) {
       chunkSizes = llvm::map_to_vector(
           state.getPayloadOps(getDynamicChunkSizes()), [&](Operation *op) {
-            if (op->getNumResults() != 1 ||
-                !op->getResult(0).getType().isIndex()) {
+            if (op -> getNumResults() != 1){
               diag = emitSilenceableError()
-                     << "expected dynamic split point handle to point to a "
+                    << "expected dynamic split point handle to point to a "
                         "single-result index-typed op";
               diag.attachNote(op->getLoc()) << "dynamic split point";
+              return OpFoldResult();  
             }
+
+            if (!op->getResult(0).getType().isIndex()){
+              diag = emitSilenceableError()
+                    << "expected dynamic split point handle to point to a "
+                        "single-result index-typed op";
+              diag.attachNote(op->getLoc()) << "dynamic split point";
+              return OpFoldResult(); 
+            }
+
             return OpFoldResult(op->getResult(0));
           });
     } else {



More information about the Mlir-commits mailing list