[Mlir-commits] [mlir] [mlir][scf] Fix front-peel unsigned loops with at most one iteration (PR #231542)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Oct 13 08:50:36 PDT 2026
https://github.com/StarOne01 updated https://github.com/llvm/llvm-project/pull/231542
>From 6d7565049529425fac754d18f170ab065109301f Mon Sep 17 00:00:00 2001
From: Prashanth <ping at starone01.me>
Date: Tue, 13 Oct 2026 20:38:12 +0530
Subject: [PATCH 1/2] [mlir][scf] Don't front-peel unsigned loops with at most
one iteration
---
.../SCF/Transforms/LoopSpecialization.cpp | 18 +++++++++++++
.../Dialect/SCF/transform-ops-invalid.mlir | 27 +++++++++++++++++++
2 files changed, 45 insertions(+)
diff --git a/mlir/lib/Dialect/SCF/Transforms/LoopSpecialization.cpp b/mlir/lib/Dialect/SCF/Transforms/LoopSpecialization.cpp
index 685c57319a2165..0c6003a95066de 100644
--- a/mlir/lib/Dialect/SCF/Transforms/LoopSpecialization.cpp
+++ b/mlir/lib/Dialect/SCF/Transforms/LoopSpecialization.cpp
@@ -242,6 +242,24 @@ LogicalResult mlir::scf::peelForLoopFirstIteration(RewriterBase &b, ForOp forOp,
if (lbInt && ubInt && stepInt && ceil(float(*ubInt - *lbInt) / *stepInt) <= 1)
return failure();
+ // Check whether we have a unsigned loop
+ if (forOp.getUnsignedCmp()) {
+ IntegerAttr lbAttr, ubAttr, stepAttr;
+ if (matchPattern(forOp.getLowerBound(), m_Constant(&lbAttr)) &&
+ matchPattern(forOp.getUpperBound(), m_Constant(&ubAttr)) &&
+ matchPattern(forOp.getStep(), m_Constant(&stepAttr))) {
+
+ // Get the constants as APInt at the loop’s own bit width
+ APInt lb = lbAttr.getValue();
+ APInt ub = ubAttr.getValue();
+ APInt step = stepAttr.getValue();
+
+ // bail out if ub <= lb or ub - lb <= step (unsigned)
+ if (ub.ule(lb) || (ub - lb).ule(step))
+ return failure();
+ }
+ }
+
// The peeling bound (%lb + %step) is computed with affine.apply, which
// accepts only index operands. %ub does not feed into this bound, so only
// %lb and %step need to be constant to guarantee the affine.apply (see below)
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
+ }
+}
>From 017fa8caeccca5c024686b598bb654a29411bd0d Mon Sep 17 00:00:00 2001
From: Prashanth <ping at starone01.me>
Date: Tue, 13 Oct 2026 20:50:38 +0530
Subject: [PATCH 2/2] [mlir][scf] fix formatting of the comment
---
mlir/lib/Dialect/SCF/Transforms/LoopSpecialization.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/lib/Dialect/SCF/Transforms/LoopSpecialization.cpp b/mlir/lib/Dialect/SCF/Transforms/LoopSpecialization.cpp
index 0c6003a95066de..dcfb6bfd991d57 100644
--- a/mlir/lib/Dialect/SCF/Transforms/LoopSpecialization.cpp
+++ b/mlir/lib/Dialect/SCF/Transforms/LoopSpecialization.cpp
@@ -254,7 +254,7 @@ LogicalResult mlir::scf::peelForLoopFirstIteration(RewriterBase &b, ForOp forOp,
APInt ub = ubAttr.getValue();
APInt step = stepAttr.getValue();
- // bail out if ub <= lb or ub - lb <= step (unsigned)
+ // bail out if ub <= lb or ub - lb <= step (unsigned)
if (ub.ule(lb) || (ub - lb).ule(step))
return failure();
}
More information about the Mlir-commits
mailing list