[Mlir-commits] [mlir] [mlir][scf] Clamp normalized loop sizes where they are combined (PR #223256)
Samarth Narang
llvmlistbot at llvm.org
Thu Sep 24 05:08:01 PDT 2026
================
@@ -989,6 +989,21 @@ delinearizeInductionVariable(RewriterBase &rewriter, Location loc,
return {delinearizedIvs, preservedUsers};
}
+/// Clamp a normalized loop size at zero. `emitNormalizedLoopBounds` returns
+/// `ceilDiv(ub - lb, step)`, which is negative for an empty loop: combining two
+/// such sizes cancels the signs into a positive extent, and a negative value is
+/// not a legal `affine.delinearize_index` basis.
+static Value clampSizeToNonNegative(RewriterBase &rewriter, Location loc,
+ Value size) {
+ if (auto cst = getConstantIntValue(size))
+ return *cst >= 0 ? size
+ : getValueOrCreateConstantIntOp(rewriter, loc,
+ rewriter.getIndexAttr(0));
+ Value zero = arith::ConstantOp::create(rewriter, loc,
+ rewriter.getZeroAttr(size.getType()));
+ return arith::MaxSIOp::create(rewriter, loc, size, zero);
----------------
snarang181 wrote:
The clamped value is the loop's upper bound with lb = 0 and step = 1, so a zero would imply zero iterations, not one as `max(0, ceilDiv(ub - lb, step))` is exactly the trip count of the original loop, and the product is the trip count of the nest.
Although, you're right that zero wasn't safe everywhere: the same value also went into the `affine.delinearize_index` basis and the `remsi`/`divsi` divisors, where zero is UB dynamically and a verifier error once it's a constant. Those now clamp at one instead. A statically empty nest now becomes `scf.for %i = %c0 to %c0` with basis `(1, 1)` rather than failing verification (see `@coalesce_empty_static_loops`).
https://github.com/llvm/llvm-project/pull/223256
More information about the Mlir-commits
mailing list