[Mlir-commits] [mlir] a7bf249 - [mlir][IntRangeAnalysis] Fix assertion in inferAffineExpr for mod with range crossing modulus boundary (#188842)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Fri Apr 3 01:15:57 PDT 2026


Author: Zhewen Yu
Date: 2026-04-03T10:15:52+02:00
New Revision: a7bf24919f879fed809b16bff33623d821b11226

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

LOG: [mlir][IntRangeAnalysis] Fix assertion in inferAffineExpr for mod with range crossing modulus boundary (#188842)

The "small range with constant divisor" optimization in
`inferAffineExpr` for `AffineExprKind::Mod` assumed that if the dividend
range span (`lhsMax - lhsMin`) is less than the divisor, then the mod
results form a contiguous range. This is not always true, as the range
can straddle a modulus boundary.

For example, `[14, 17] mod 8`:
- Span is 3 < 8, so the old condition passed
- But `14%8=6` and `17%8=1` (wraps at 16)
- `umin=6, umax=1` → assertion `umin.ule(umax)` fails

The fix adds a same-quotient check (`lhsMin/rhs == lhsMax/rhs`) to
ensure both endpoints fall within the same modular period. When they
don't, we fall back to the conservative `[0, divisor-1]` range.

Assisted-by: Cursor (Claude)

Signed-off-by: Yu-Zhewen <zhewenyu at amd.com>

Added: 
    

Modified: 
    mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp
    mlir/test/Dialect/Affine/int-range-interface.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp b/mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp
index 21f07ddce4495..c9f49fda726e7 100644
--- a/mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp
+++ b/mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp
@@ -854,12 +854,14 @@ mlir::intrange::inferAffineExpr(AffineExpr expr,
       umax = lhsMax;
     }
     // Special case: sweeping out a contiguous range with constant divisor.
-    // Only applies when dividend is non-negative to ensure result range is
-    // contiguous.
+    // Only applies when dividend is non-negative and the range does not
+    // cross a modulus boundary (same quotient), ensuring contiguity.
     else if (rhsMin == rhsMax && lhsMin.isNonNegative() &&
-             (lhsMax - lhsMin).ult(rhsMax)) {
-      // For non-negative dividends, Euclidean mod is same as unsigned
-      // remainder.
+             (lhsMax - lhsMin).ult(rhsMax) &&
+             lhsMin.udiv(rhsMax) == lhsMax.udiv(rhsMax)) {
+      // For non-negative dividends within the same modular period,
+      // Euclidean mod is same as unsigned remainder and the result is
+      // contiguous.
       umin = lhsMin.urem(rhsMax);
       umax = lhsMax.urem(rhsMax);
       // Result should be contiguous since we're not wrapping around.

diff  --git a/mlir/test/Dialect/Affine/int-range-interface.mlir b/mlir/test/Dialect/Affine/int-range-interface.mlir
index ca8df8a9e5788..ac64ad09ee244 100644
--- a/mlir/test/Dialect/Affine/int-range-interface.mlir
+++ b/mlir/test/Dialect/Affine/int-range-interface.mlir
@@ -147,6 +147,18 @@ func.func @affine_apply_mod_variable_divisor() -> index {
   func.return %1 : index
 }
 
+// CHECK-LABEL: func @affine_apply_mod_cross_boundary
+// CHECK: test.reflect_bounds {smax = 7 : index, smin = 0 : index, umax = 7 : index, umin = 0 : index}
+func.func @affine_apply_mod_cross_boundary() -> index {
+  %d0 = test.with_bounds { umin = 14 : index, umax = 17 : index,
+                           smin = 14 : index, smax = 17 : index } : index
+  // Range [14, 17] spans a mod-8 boundary (at 16): 14%8=6, 17%8=1.
+  // Span 3 < 8 but the range wraps, so we fall back to [0, 7].
+  %0 = affine.apply affine_map<(d0) -> (d0 mod 8)>(%d0)
+  %1 = test.reflect_bounds %0 : index
+  func.return %1 : index
+}
+
 // CHECK-LABEL: func @affine_apply_mod_negative_dividend
 // CHECK: test.reflect_bounds {smax = 3 : index, smin = 0 : index, umax = 3 : index, umin = 0 : index}
 func.func @affine_apply_mod_negative_dividend() -> index {


        


More information about the Mlir-commits mailing list