[Mlir-commits] [mlir] 1510689 - [mlir][scf] Fix front-peel unsigned loops with at most one iteration (#231542)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed Oct 14 17:57:21 PDT 2026


Author: Prashanth
Date: 2026-10-15T09:57:14+09:00
New Revision: 15106899301ea12b5be2ed5c7f104b605c1a1154

URL: https://github.com/llvm/llvm-project/commit/15106899301ea12b5be2ed5c7f104b605c1a1154
DIFF: https://github.com/llvm/llvm-project/commit/15106899301ea12b5be2ed5c7f104b605c1a1154.diff

LOG: [mlir][scf] Fix front-peel unsigned loops with at most one iteration (#231542)

For unsigned loops with constant bounds, read the bounds as `APInt` and
skip peeling when `ub <= lb` or `ub - lb <= step` (compared unsigned),
bail out if failed.

from #231100 and fixes #231541

Added: 
    

Modified: 
    mlir/lib/Dialect/SCF/Transforms/LoopSpecialization.cpp
    mlir/test/Dialect/SCF/transform-ops-invalid.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/lib/Dialect/SCF/Transforms/LoopSpecialization.cpp b/mlir/lib/Dialect/SCF/Transforms/LoopSpecialization.cpp
index 685c57319a2165..62ed21795ab6e2 100644
--- a/mlir/lib/Dialect/SCF/Transforms/LoopSpecialization.cpp
+++ b/mlir/lib/Dialect/SCF/Transforms/LoopSpecialization.cpp
@@ -233,6 +233,12 @@ LogicalResult mlir::scf::peelForLoopAndSimplifyBounds(RewriterBase &rewriter,
 /// original lower bound plus the step (i.e. skips the first iteration).
 LogicalResult mlir::scf::peelForLoopFirstIteration(RewriterBase &b, ForOp forOp,
                                                    ForOp &firstIteration) {
+  // TODO: Add support for unsigned loops. The current logic
+  // uses `affine.min` and `arith.index_cast`, which is incorrect for
+  // unsigned comparisons.
+  if (forOp.getUnsignedCmp())
+    return failure();
+
   RewriterBase::InsertionGuard guard(b);
   auto lbInt = getConstantIntValue(forOp.getLowerBound());
   auto ubInt = getConstantIntValue(forOp.getUpperBound());

diff  --git a/mlir/test/Dialect/SCF/transform-ops-invalid.mlir b/mlir/test/Dialect/SCF/transform-ops-invalid.mlir
index 20549581029ebf..cd0f0eb8cb5554 100644
--- a/mlir/test/Dialect/SCF/transform-ops-invalid.mlir
+++ b/mlir/test/Dialect/SCF/transform-ops-invalid.mlir
@@ -255,3 +255,30 @@ module attributes {transform.with_named_sequence} {
     transform.yield
   }
 }
+
+// -----
+
+// An unsigned loop with lb > ub (as unsigned values) has no iterations and
+// must not be peeled.
+
+func.func @peel_front_unsigned_empty(%out: memref<8xindex>) {
+  %lb = arith.constant -1 : index
+  %ub = arith.constant 5 : index
+  %step = arith.constant 1 : index
+  scf.for unsigned %i = %lb to %ub step %step {
+    %c0 = arith.constant 0 : index
+    memref.store %i, %out[%c0] : memref<8xindex>
+  }
+  return
+}
+
+module attributes {transform.with_named_sequence} {
+  transform.named_sequence @__transform_main(%root: !transform.any_op {transform.readonly}) {
+    %loops = transform.structured.match ops{["scf.for"]} in %root
+        : (!transform.any_op) -> !transform.op<"scf.for">
+    // expected-error @below {{failed to peel the first iteration}}
+    %main, %rest = transform.loop.peel %loops peel_front = true
+        : (!transform.op<"scf.for">) -> (!transform.any_op, !transform.any_op)
+    transform.yield
+  }
+}


        


More information about the Mlir-commits mailing list