[Mlir-commits] [mlir] [mlir][test] Allow excess tile sizes in fuse_using_forall (PR #216370)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Fri Aug 14 10:59:20 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
Author: crZhao (cr-zhao)
<details>
<summary>Changes</summary>
## Summary
- stop deriving the generated `scf.forall` rank from the unadjusted tile-size list in the test transform
- keep the structural assertion that forall tiling returns a single `scf.forall`
- add regression coverage for excess tile sizes on a one-dimensional `linalg.generic`
## Root cause
`tileUsingSCF` resizes the requested tile sizes to the target operation's iteration domain. `transform.test.fuse_using_forall` instead computed an expected rank from the original tile-size list. For a one-dimensional target with `[10, 20]`, tiling correctly generated a rank-1 `scf.forall`, but the test transform asserted that its rank must be 2 and crashed.
The transform returns one handle for the generated `scf.forall`, independent of that operation's rank, so the rank assertion was not a valid invariant.
Fixes #<!-- -->206619.
## Testing
- `build/bin/mlir-opt --transform-interpreter --cse --split-input-file mlir/test/Interfaces/TilingInterface/tile-and-fuse-using-scfforall.mlir | build/bin/FileCheck mlir/test/Interfaces/TilingInterface/tile-and-fuse-using-scfforall.mlir`
- original issue reproducer with `build/bin/mlir-opt -transform-interpreter` (exit code 0)
Assisted-by: Codex
---
Full diff: https://github.com/llvm/llvm-project/pull/216370.diff
2 Files Affected:
- (modified) mlir/test/Interfaces/TilingInterface/tile-and-fuse-using-scfforall.mlir (+32)
- (modified) mlir/test/lib/Interfaces/TilingInterface/TestTilingInterfaceTransformOps.cpp (+4-5)
``````````diff
diff --git a/mlir/test/Interfaces/TilingInterface/tile-and-fuse-using-scfforall.mlir b/mlir/test/Interfaces/TilingInterface/tile-and-fuse-using-scfforall.mlir
index 0bd2546e082b5..6682c0de3e133 100644
--- a/mlir/test/Interfaces/TilingInterface/tile-and-fuse-using-scfforall.mlir
+++ b/mlir/test/Interfaces/TilingInterface/tile-and-fuse-using-scfforall.mlir
@@ -174,3 +174,35 @@ module attributes {transform.with_named_sequence} {
// CHECK: tensor.parallel_insert_slice %[[GENERIC2]] into %[[ITERARG0]][%[[IV]], 0]
// CHECK: }
// CHECK: return %[[RESULT]]
+
+// -----
+
+// Tile sizes beyond the iteration domain are ignored.
+func.func @excess_tile_sizes(%arg0: tensor<?xf32>,
+ %arg1: tensor<?xf32>) -> tensor<?xf32> {
+ %0 = linalg.generic {
+ indexing_maps = [affine_map<(d0) -> (d0)>,
+ affine_map<(d0) -> (d0)>],
+ iterator_types = ["parallel"]}
+ ins(%arg0 : tensor<?xf32>) outs(%arg1 : tensor<?xf32>) {
+ ^bb0(%in: f32, %out: f32):
+ %sum = arith.addf %in, %out : f32
+ linalg.yield %sum : f32
+ } -> tensor<?xf32>
+ return %0 : tensor<?xf32>
+}
+
+module attributes {transform.with_named_sequence} {
+ transform.named_sequence @__transform_main(
+ %arg0: !transform.any_op {transform.readonly}) {
+ %generic = transform.structured.match ops{["linalg.generic"]} in %arg0
+ : (!transform.any_op) -> !transform.any_op
+ %tiled, %loop = transform.test.fuse_using_forall %generic [10, 20]
+ : (!transform.any_op) -> (!transform.any_op, !transform.any_op)
+ transform.yield
+ }
+}
+
+// CHECK-LABEL: func.func @excess_tile_sizes
+// CHECK: scf.forall (%[[IV:.+]]) = (0) to
+// CHECK: linalg.generic
diff --git a/mlir/test/lib/Interfaces/TilingInterface/TestTilingInterfaceTransformOps.cpp b/mlir/test/lib/Interfaces/TilingInterface/TestTilingInterfaceTransformOps.cpp
index 9467c925e543c..5902001094f5c 100644
--- a/mlir/test/lib/Interfaces/TilingInterface/TestTilingInterfaceTransformOps.cpp
+++ b/mlir/test/lib/Interfaces/TilingInterface/TestTilingInterfaceTransformOps.cpp
@@ -397,7 +397,7 @@ void transform::TestTileUsingForallOp::getEffects(
template <typename Range>
static LogicalResult applyTilingToAll(
RewriterBase &rewriter, Operation *transformOp, Range &&payloadOps,
- unsigned numLoops, TransformResults &transformResults,
+ TransformResults &transformResults,
function_ref<FailureOr<scf::SCFTileAndFuseResult>(TilingInterface)>
applyFn) {
SmallVector<Operation *> tiledLinalgOps;
@@ -428,9 +428,8 @@ static LogicalResult applyTilingToAll(
// Report back the relevant handles to the transform op.
tiledLinalgOps.push_back(tiledResults->tiledAndFusedOps.front());
assert(tiledResults->loops.size() == 1 &&
- cast<scf::ForallOp>(tiledResults->loops[0]).getRank() == numLoops &&
- "Mismatched number of loops, tile and fuse transform should have "
- "failed");
+ isa<scf::ForallOp>(tiledResults->loops[0]) &&
+ "expected a single scf.forall op");
loopOps[0] = {tiledResults->loops[0]};
}
@@ -460,7 +459,7 @@ transform::TestFuseUsingForallOp::apply(TransformRewriter &rewriter,
tileAndFuseOptions.tilingOptions = tilingOptions;
LogicalResult result = applyTilingToAll(
rewriter, getOperation(), state.getPayloadOps(getRootOp()),
- tileSizes.size() - llvm::count(tileSizes, 0), transformResults,
+ transformResults,
[&](TilingInterface tilingInterfaceOp)
-> FailureOr<scf::SCFTileAndFuseResult> {
return tileConsumerAndFuseProducersUsingSCF(rewriter, tilingInterfaceOp,
``````````
</details>
https://github.com/llvm/llvm-project/pull/216370
More information about the Mlir-commits
mailing list