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

Mehdi Amini llvmlistbot at llvm.org
Mon Mar 2 06:20:24 PST 2026


https://github.com/joker-eph created https://github.com/llvm/llvm-project/pull/184130

`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

>From 15a934f31658c5a7ab285dac8dd0915cf3e42357 Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Mon, 2 Mar 2026 06:10:35 -0800
Subject: [PATCH] [mlir][affine] Fix crash in addAffineParallelOpDomain with
 min/max bounds

`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
---
 .../Affine/Analysis/AffineStructures.cpp      |  4 ++--
 .../Affine/memref-dependence-check.mlir       | 20 +++++++++++++++++++
 2 files changed, 22 insertions(+), 2 deletions(-)

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
+}



More information about the Mlir-commits mailing list