[Mlir-commits] [mlir] [mlir][affine] Fix crash in addAffineParallelOpDomain with min/max bounds (PR #184130)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Mon Mar 2 06:20:59 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir-affine

Author: Mehdi Amini (joker-eph)

<details>
<summary>Changes</summary>

`addAffineParallelOpDomain` checked `isConstant()` on the per-IV bound maps of `affine.parallel`, then called `getSingleConstantResult()`. However, `isConstant()` returns true for maps with *any* number of constant results, while `getSingleConstantResult()` asserts exactly one.

When an `affine.parallel` has a multi-result bound (e.g., `to (min(128, 122))`), the per-IV upper bound map has two results `{128, 122}`, so `isConstant()` is true but the subsequent `getSingleConstantResult()` call aborts.

Fix by using `isSingleConstant()` (which requires exactly one result) instead. Multi-result constant maps (min/max with all-constant alternatives) are then handled by the general `addBound` path, which correctly models the min/max semantics as multiple constraints.

Fixes #<!-- -->61734

---
Full diff: https://github.com/llvm/llvm-project/pull/184130.diff


2 Files Affected:

- (modified) mlir/lib/Dialect/Affine/Analysis/AffineStructures.cpp (+2-2) 
- (modified) mlir/test/Dialect/Affine/memref-dependence-check.mlir (+20) 


``````````diff
diff --git a/mlir/lib/Dialect/Affine/Analysis/AffineStructures.cpp b/mlir/lib/Dialect/Affine/Analysis/AffineStructures.cpp
index edfae7ee96039..8bf773dd817f2 100644
--- a/mlir/lib/Dialect/Affine/Analysis/AffineStructures.cpp
+++ b/mlir/lib/Dialect/Affine/Analysis/AffineStructures.cpp
@@ -133,14 +133,14 @@ LogicalResult FlatAffineValueConstraints::addAffineParallelOpDomain(
     }
 
     AffineMap lowerBound = parallelOp.getLowerBoundMap(ivPos);
-    if (lowerBound.isConstant())
+    if (lowerBound.isSingleConstant())
       addBound(BoundType::LB, pos, lowerBound.getSingleConstantResult());
     else if (failed(addBound(BoundType::LB, pos, lowerBound,
                              parallelOp.getLowerBoundsOperands())))
       return failure();
 
     auto upperBound = parallelOp.getUpperBoundMap(ivPos);
-    if (upperBound.isConstant())
+    if (upperBound.isSingleConstant())
       addBound(BoundType::UB, pos, upperBound.getSingleConstantResult() - 1);
     else if (failed(addBound(BoundType::UB, pos, upperBound,
                              parallelOp.getUpperBoundsOperands())))
diff --git a/mlir/test/Dialect/Affine/memref-dependence-check.mlir b/mlir/test/Dialect/Affine/memref-dependence-check.mlir
index f272277cc7904..0a96d1ac65e0a 100644
--- a/mlir/test/Dialect/Affine/memref-dependence-check.mlir
+++ b/mlir/test/Dialect/Affine/memref-dependence-check.mlir
@@ -1146,3 +1146,23 @@ func.func @affine_parallel_dep_check_2() {
   // expected-remark at above {{dependence from 1 to 0 at depth 1 = false}}
   return
 }
+
+// -----
+
+// Regression test: affine.parallel with multi-result min/max bound maps
+// (e.g., min(128, 122)) must not crash addAffineParallelOpDomain.
+// https://github.com/llvm/llvm-project/issues/61734
+
+// CHECK-LABEL: func @affine_parallel_min_max_bounds
+func.func @affine_parallel_min_max_bounds(%arg0: memref<4090x2040xf32>, %arg1: f32) {
+  affine.parallel (%arg2, %arg3) = (0, 0) to (min(128, 122), min(64, 2040)) {
+    affine.for %arg4 = 0 to 100 {
+      affine.store %arg1, %arg0[%arg2 + 3968, %arg3] : memref<4090x2040xf32>
+      // expected-remark at above {{dependence from 0 to 0 at depth 1 = false}}
+      // expected-remark at above {{dependence from 0 to 0 at depth 2 = false}}
+      // expected-remark at above {{dependence from 0 to 0 at depth 3 = [0, 0][0, 0][1, 99]}}
+      // expected-remark at above {{dependence from 0 to 0 at depth 4 = false}}
+    }
+  }
+  return
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/184130


More information about the Mlir-commits mailing list