[Mlir-commits] [mlir] [mlir] [presburger] Add IntegerRelation::rangeProduct (PR #148092)

Jeremy Kun llvmlistbot at llvm.org
Thu Jul 17 06:46:50 PDT 2025


https://github.com/j2kun updated https://github.com/llvm/llvm-project/pull/148092

>From 3c55e16f6dbc266512a24e5af814f5e0e51b62e7 Mon Sep 17 00:00:00 2001
From: Jeremy Kun <j2kun at users.noreply.github.com>
Date: Thu, 10 Jul 2025 17:24:50 -0700
Subject: [PATCH 1/7] Add IntegerRelation::rangeProduct

This is intended to match `isl::map`'s `flat_range_product`.
---
 .../Analysis/Presburger/IntegerRelation.h     | 15 ++++++++
 .../Analysis/Presburger/IntegerRelation.cpp   | 35 +++++++++++++++++++
 .../Presburger/IntegerRelationTest.cpp        | 14 ++++++++
 3 files changed, 64 insertions(+)

diff --git a/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h b/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h
index b68262f09f485..ae213181f2c3b 100644
--- a/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h
+++ b/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h
@@ -707,6 +707,21 @@ class IntegerRelation {
   /// this for uniformity with `applyDomain`.
   void applyRange(const IntegerRelation &rel);
 
+  /// Let the relation `this` be R1, and the relation `rel` be R2. Requires
+  /// R1 and R2 to have the same domain.
+  ///
+  /// This operation computes the relation whose domain is the same as R1 and
+  /// whose range is the product of the ranges of R1 and R2, and whose
+  /// constraints are the conjunction of the constraints of R1 and R2 applied
+  /// to the relevant subspaces of the range.
+  ///
+  /// Example:
+  ///
+  /// R1: (i, j) -> k : f(i, j, k) = 0
+  /// R2: (i, j) -> l : g(i, j, l) = 0
+  /// R1.rangeProduct(R2): (i, j) -> (k, l) : f(i, j, k) = 0 and g(i, j, l) = 0
+  IntegerRelation rangeProduct(const IntegerRelation &rel);
+
   /// Given a relation `other: (A -> B)`, this operation merges the symbol and
   /// local variables and then takes the composition of `other` on `this: (B ->
   /// C)`. The resulting relation represents tuples of the form: `A -> C`.
diff --git a/mlir/lib/Analysis/Presburger/IntegerRelation.cpp b/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
index 17e48e0d069b7..5c767ff7207ba 100644
--- a/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
+++ b/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
@@ -2481,6 +2481,41 @@ void IntegerRelation::applyDomain(const IntegerRelation &rel) {
 
 void IntegerRelation::applyRange(const IntegerRelation &rel) { compose(rel); }
 
+IntegerRelation IntegerRelation::rangeProduct(const IntegerRelation &rel) {
+  /// R1: (i, j) -> k : f(i, j, k) = 0
+  /// R2: (i, j) -> l : g(i, j, l) = 0
+  /// R1.rangeProduct(R2): (i, j) -> (k, l) : f(i, j, k) = 0 and g(i, j, l) = 0
+  assert(getNumDomainVars() == rel.getNumDomainVars() &&
+         "Range product is only defined for relations with equal domains");
+
+  // explicit copy of the context relation
+  IntegerRelation result = *this;
+  unsigned srcOffset = getVarKindOffset(VarKind::Range);
+  unsigned newNumRangeVars = rel.getNumRangeVars();
+
+  result.appendVar(VarKind::Range, newNumRangeVars);
+
+  for (unsigned i = 0; i < rel.getNumEqualities(); ++i) {
+    // Add a new equality that uses the new range variables.
+    // The old equality is a list of coefficients of the variables
+    // from `rel`, and so the range variables need to be shifted
+    // right by the number of range variables added to `result`.
+    SmallVector<DynamicAPInt> copy =
+        SmallVector<DynamicAPInt>(rel.getEquality(i));
+    copy.insert(copy.begin() + srcOffset, newNumRangeVars, DynamicAPInt(0));
+    result.addEquality(copy);
+  }
+
+  for (unsigned i = 0; i < rel.getNumInequalities(); ++i) {
+    SmallVector<DynamicAPInt> copy =
+        SmallVector<DynamicAPInt>(rel.getInequality(i));
+    copy.insert(copy.begin() + srcOffset, newNumRangeVars, DynamicAPInt(0));
+    result.addInequality(copy);
+  }
+
+  return result;
+}
+
 void IntegerRelation::printSpace(raw_ostream &os) const {
   space.print(os);
   os << getNumConstraints() << " constraints\n";
diff --git a/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp b/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
index 7df500bc9568a..dd8b9e3f03330 100644
--- a/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
+++ b/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
@@ -608,3 +608,17 @@ TEST(IntegerRelationTest, convertVarKindToLocal) {
   EXPECT_EQ(space.getId(VarKind::Symbol, 0), Identifier(&identifiers[3]));
   EXPECT_EQ(space.getId(VarKind::Symbol, 1), Identifier(&identifiers[4]));
 }
+
+TEST(IntegerRelationTest, rangeProduct) {
+  IntegerRelation r1 = parseRelationFromSet(
+      "(i, j, k) : (2*i + 3*k == 0, i >= 0, j >= 0, k >= 0)", 2);
+  IntegerRelation r2 = parseRelationFromSet(
+      "(i, j, l) : (4*i + 6*j + 9*l == 0, i >= 0, j >= 0, l >= 0)", 2);
+
+  IntegerRelation rangeProd = r1.rangeProduct(r2);
+  IntegerRelation expected = parseRelationFromSet(
+      "(i, j, k, l) : (2*i + 3*k == 0, 4*i + 6*j + 9*l == 0, i >= 0, j >= 0, k >= 0, l >= 0)", 2);
+
+  EXPECT_TRUE(expected.isEqual(rangeProd));
+}
+

>From 1c8457eb2a555047964f4dc68e1927dbbc8beb47 Mon Sep 17 00:00:00 2001
From: Jeremy Kun <j2kun at users.noreply.github.com>
Date: Tue, 15 Jul 2025 13:43:15 -0700
Subject: [PATCH 2/7] formatting

---
 mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp b/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
index dd8b9e3f03330..db24600111cee 100644
--- a/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
+++ b/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
@@ -616,9 +616,10 @@ TEST(IntegerRelationTest, rangeProduct) {
       "(i, j, l) : (4*i + 6*j + 9*l == 0, i >= 0, j >= 0, l >= 0)", 2);
 
   IntegerRelation rangeProd = r1.rangeProduct(r2);
-  IntegerRelation expected = parseRelationFromSet(
-      "(i, j, k, l) : (2*i + 3*k == 0, 4*i + 6*j + 9*l == 0, i >= 0, j >= 0, k >= 0, l >= 0)", 2);
+  IntegerRelation expected =
+      parseRelationFromSet("(i, j, k, l) : (2*i + 3*k == 0, 4*i + 6*j + 9*l == "
+                           "0, i >= 0, j >= 0, k >= 0, l >= 0)",
+                           2);
 
   EXPECT_TRUE(expected.isEqual(rangeProd));
 }
-

>From 7c20201c8edcbb94ce8afe166bbdf5922869d120 Mon Sep 17 00:00:00 2001
From: Jeremy Kun <j2kun at users.noreply.github.com>
Date: Tue, 15 Jul 2025 13:51:07 -0700
Subject: [PATCH 3/7] address review comments

---
 .../include/mlir/Analysis/Presburger/IntegerRelation.h |  6 ++----
 mlir/lib/Analysis/Presburger/IntegerRelation.cpp       | 10 +++++-----
 2 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h b/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h
index ae213181f2c3b..ee401cca8f552 100644
--- a/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h
+++ b/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h
@@ -710,10 +710,8 @@ class IntegerRelation {
   /// Let the relation `this` be R1, and the relation `rel` be R2. Requires
   /// R1 and R2 to have the same domain.
   ///
-  /// This operation computes the relation whose domain is the same as R1 and
-  /// whose range is the product of the ranges of R1 and R2, and whose
-  /// constraints are the conjunction of the constraints of R1 and R2 applied
-  /// to the relevant subspaces of the range.
+  /// Let R3 be the rangeProduct of R1 and R2. Then x R3 (y, z) iff
+  /// (x R1 y and x R2 z).
   ///
   /// Example:
   ///
diff --git a/mlir/lib/Analysis/Presburger/IntegerRelation.cpp b/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
index 5c767ff7207ba..9e596b16b78b2 100644
--- a/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
+++ b/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
@@ -2488,12 +2488,12 @@ IntegerRelation IntegerRelation::rangeProduct(const IntegerRelation &rel) {
   assert(getNumDomainVars() == rel.getNumDomainVars() &&
          "Range product is only defined for relations with equal domains");
 
-  // explicit copy of the context relation
+  // explicit copy of `this`
   IntegerRelation result = *this;
   unsigned srcOffset = getVarKindOffset(VarKind::Range);
-  unsigned newNumRangeVars = rel.getNumRangeVars();
+  unsigned numRelRangeVars = rel.getNumRangeVars();
 
-  result.appendVar(VarKind::Range, newNumRangeVars);
+  result.appendVar(VarKind::Range, numRelRangeVars);
 
   for (unsigned i = 0; i < rel.getNumEqualities(); ++i) {
     // Add a new equality that uses the new range variables.
@@ -2502,14 +2502,14 @@ IntegerRelation IntegerRelation::rangeProduct(const IntegerRelation &rel) {
     // right by the number of range variables added to `result`.
     SmallVector<DynamicAPInt> copy =
         SmallVector<DynamicAPInt>(rel.getEquality(i));
-    copy.insert(copy.begin() + srcOffset, newNumRangeVars, DynamicAPInt(0));
+    copy.insert(copy.begin() + srcOffset, numRelRangeVars, DynamicAPInt(0));
     result.addEquality(copy);
   }
 
   for (unsigned i = 0; i < rel.getNumInequalities(); ++i) {
     SmallVector<DynamicAPInt> copy =
         SmallVector<DynamicAPInt>(rel.getInequality(i));
-    copy.insert(copy.begin() + srcOffset, newNumRangeVars, DynamicAPInt(0));
+    copy.insert(copy.begin() + srcOffset, numRelRangeVars, DynamicAPInt(0));
     result.addInequality(copy);
   }
 

>From 2d8537c8d45cd8e2c02193884495d5aa8ae1be0f Mon Sep 17 00:00:00 2001
From: Jeremy Kun <j2kun at users.noreply.github.com>
Date: Tue, 15 Jul 2025 14:26:01 -0700
Subject: [PATCH 4/7] fix an indexing bug and add more tests

---
 .../Analysis/Presburger/IntegerRelation.cpp   | 17 ++++++-----
 .../Presburger/IntegerRelationTest.cpp        | 30 +++++++++++++++++++
 2 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/mlir/lib/Analysis/Presburger/IntegerRelation.cpp b/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
index 9e596b16b78b2..adbdb525c00ef 100644
--- a/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
+++ b/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
@@ -2490,26 +2490,29 @@ IntegerRelation IntegerRelation::rangeProduct(const IntegerRelation &rel) {
 
   // explicit copy of `this`
   IntegerRelation result = *this;
-  unsigned srcOffset = getVarKindOffset(VarKind::Range);
+  unsigned relRangeVarStart = rel.getVarKindOffset(VarKind::Range);
   unsigned numRelRangeVars = rel.getNumRangeVars();
+  unsigned numThisRangeVars = getNumRangeVars();
 
   result.appendVar(VarKind::Range, numRelRangeVars);
 
+  // Copy each equality from `rel` and update the copy to account for range
+  // variables from `this`. The `rel` equality is a list of coefficients of the
+  // variables from `rel`, and so the range variables need to be shifted right
+  // by the number of `this` range variables.
   for (unsigned i = 0; i < rel.getNumEqualities(); ++i) {
-    // Add a new equality that uses the new range variables.
-    // The old equality is a list of coefficients of the variables
-    // from `rel`, and so the range variables need to be shifted
-    // right by the number of range variables added to `result`.
     SmallVector<DynamicAPInt> copy =
         SmallVector<DynamicAPInt>(rel.getEquality(i));
-    copy.insert(copy.begin() + srcOffset, numRelRangeVars, DynamicAPInt(0));
+    copy.insert(copy.begin() + relRangeVarStart, numThisRangeVars,
+                DynamicAPInt(0));
     result.addEquality(copy);
   }
 
   for (unsigned i = 0; i < rel.getNumInequalities(); ++i) {
     SmallVector<DynamicAPInt> copy =
         SmallVector<DynamicAPInt>(rel.getInequality(i));
-    copy.insert(copy.begin() + srcOffset, numRelRangeVars, DynamicAPInt(0));
+    copy.insert(copy.begin() + relRangeVarStart, numThisRangeVars,
+                DynamicAPInt(0));
     result.addInequality(copy);
   }
 
diff --git a/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp b/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
index db24600111cee..563e94d0c5e16 100644
--- a/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
+++ b/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
@@ -623,3 +623,33 @@ TEST(IntegerRelationTest, rangeProduct) {
 
   EXPECT_TRUE(expected.isEqual(rangeProd));
 }
+
+TEST(IntegerRelationTest, rangeProductMultdimRange) {
+  IntegerRelation r1 = parseRelationFromSet(
+      "(i, k) : (2*i + 3*k == 0, i >= 0, k >= 0)", 1);
+  IntegerRelation r2 = parseRelationFromSet(
+      "(i, l, m) : (4*i + 6*m + 9*l == 0, i >= 0, l >= 0, m >= 0)", 1);
+
+  IntegerRelation rangeProd = r1.rangeProduct(r2);
+  IntegerRelation expected =
+      parseRelationFromSet("(i, k, l, m) : (2*i + 3*k == 0, 4*i + 6*m + 9*l == "
+                           "0, i >= 0, k >= 0, l >= 0, m >= 0)",
+                           1);
+
+  EXPECT_TRUE(expected.isEqual(rangeProd));
+}
+
+TEST(IntegerRelationTest, rangeProductMultdimRangeSwapped) {
+  IntegerRelation r1 = parseRelationFromSet(
+      "(i, l, m) : (4*i + 6*m + 9*l == 0, i >= 0, l >= 0, m >= 0)", 1);
+  IntegerRelation r2 = parseRelationFromSet(
+      "(i, k) : (2*i + 3*k == 0, i >= 0, k >= 0)", 1);
+
+  IntegerRelation rangeProd = r1.rangeProduct(r2);
+  IntegerRelation expected =
+      parseRelationFromSet("(i, l, m, k) : (2*i + 3*k == 0, 4*i + 6*m + 9*l == "
+                           "0, i >= 0, k >= 0, l >= 0, m >= 0)",
+                           1);
+
+  EXPECT_TRUE(expected.isEqual(rangeProd));
+}

>From f968bbbfcbd6ce508ef1ee9e0591fdbfdd0e8754 Mon Sep 17 00:00:00 2001
From: Jeremy Kun <j2kun at users.noreply.github.com>
Date: Tue, 15 Jul 2025 20:55:40 -0700
Subject: [PATCH 5/7] formatting

---
 .../unittests/Analysis/Presburger/IntegerRelationTest.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp b/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
index 563e94d0c5e16..39a74dbd7b18c 100644
--- a/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
+++ b/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
@@ -625,8 +625,8 @@ TEST(IntegerRelationTest, rangeProduct) {
 }
 
 TEST(IntegerRelationTest, rangeProductMultdimRange) {
-  IntegerRelation r1 = parseRelationFromSet(
-      "(i, k) : (2*i + 3*k == 0, i >= 0, k >= 0)", 1);
+  IntegerRelation r1 =
+      parseRelationFromSet("(i, k) : (2*i + 3*k == 0, i >= 0, k >= 0)", 1);
   IntegerRelation r2 = parseRelationFromSet(
       "(i, l, m) : (4*i + 6*m + 9*l == 0, i >= 0, l >= 0, m >= 0)", 1);
 
@@ -642,8 +642,8 @@ TEST(IntegerRelationTest, rangeProductMultdimRange) {
 TEST(IntegerRelationTest, rangeProductMultdimRangeSwapped) {
   IntegerRelation r1 = parseRelationFromSet(
       "(i, l, m) : (4*i + 6*m + 9*l == 0, i >= 0, l >= 0, m >= 0)", 1);
-  IntegerRelation r2 = parseRelationFromSet(
-      "(i, k) : (2*i + 3*k == 0, i >= 0, k >= 0)", 1);
+  IntegerRelation r2 =
+      parseRelationFromSet("(i, k) : (2*i + 3*k == 0, i >= 0, k >= 0)", 1);
 
   IntegerRelation rangeProd = r1.rangeProduct(r2);
   IntegerRelation expected =

>From bc4c61cf83fe930bf816bcd32ee1e19e47da44f1 Mon Sep 17 00:00:00 2001
From: Jeremy Kun <j2kun at users.noreply.github.com>
Date: Wed, 16 Jul 2025 08:25:06 -0700
Subject: [PATCH 6/7] test for empty domain/range and symbols

---
 .../Analysis/Presburger/IntegerRelation.cpp   | 20 +++++---
 .../Presburger/IntegerRelationTest.cpp        | 49 +++++++++++++++++++
 2 files changed, 62 insertions(+), 7 deletions(-)

diff --git a/mlir/lib/Analysis/Presburger/IntegerRelation.cpp b/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
index adbdb525c00ef..90f0af088757e 100644
--- a/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
+++ b/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
@@ -2490,29 +2490,35 @@ IntegerRelation IntegerRelation::rangeProduct(const IntegerRelation &rel) {
 
   // explicit copy of `this`
   IntegerRelation result = *this;
+
+  // An explicit copy of `rel` is needed to merge and align symbols, since that
+  // function mutates both relations.
+  IntegerRelation relCopy = rel;
+  result.mergeAndAlignSymbols(relCopy);
+
   unsigned relRangeVarStart = rel.getVarKindOffset(VarKind::Range);
-  unsigned numRelRangeVars = rel.getNumRangeVars();
   unsigned numThisRangeVars = getNumRangeVars();
+  unsigned numNewSymbolVars = result.getNumSymbolVars() - getNumSymbolVars();
 
-  result.appendVar(VarKind::Range, numRelRangeVars);
+  result.appendVar(VarKind::Range, rel.getNumRangeVars());
 
   // Copy each equality from `rel` and update the copy to account for range
   // variables from `this`. The `rel` equality is a list of coefficients of the
   // variables from `rel`, and so the range variables need to be shifted right
-  // by the number of `this` range variables.
+  // by the number of `this` range variables and symbols.
   for (unsigned i = 0; i < rel.getNumEqualities(); ++i) {
     SmallVector<DynamicAPInt> copy =
         SmallVector<DynamicAPInt>(rel.getEquality(i));
-    copy.insert(copy.begin() + relRangeVarStart, numThisRangeVars,
-                DynamicAPInt(0));
+    copy.insert(copy.begin() + relRangeVarStart,
+                numThisRangeVars + numNewSymbolVars, DynamicAPInt(0));
     result.addEquality(copy);
   }
 
   for (unsigned i = 0; i < rel.getNumInequalities(); ++i) {
     SmallVector<DynamicAPInt> copy =
         SmallVector<DynamicAPInt>(rel.getInequality(i));
-    copy.insert(copy.begin() + relRangeVarStart, numThisRangeVars,
-                DynamicAPInt(0));
+    copy.insert(copy.begin() + relRangeVarStart,
+                numThisRangeVars + numNewSymbolVars, DynamicAPInt(0));
     result.addInequality(copy);
   }
 
diff --git a/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp b/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
index 39a74dbd7b18c..ab2937d08eb5b 100644
--- a/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
+++ b/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
@@ -653,3 +653,52 @@ TEST(IntegerRelationTest, rangeProductMultdimRangeSwapped) {
 
   EXPECT_TRUE(expected.isEqual(rangeProd));
 }
+
+TEST(IntegerRelationTest, rangeProductEmptyDomain) {
+  IntegerRelation r1 =
+      parseRelationFromSet("(i, j) : (4*i + 9*j == 0, i >= 0, j >= 0)", 0);
+  IntegerRelation r2 =
+      parseRelationFromSet("(k, l) : (2*k + 3*l == 0, k >= 0, l >= 0)", 0);
+  IntegerRelation rangeProd = r1.rangeProduct(r2);
+  IntegerRelation expected =
+      parseRelationFromSet("(i, j, k, l) : (2*k + 3*l == 0, 4*i + 9*j == "
+                           "0, i >= 0, j >= 0, k >= 0, l >= 0)",
+                           0);
+  EXPECT_TRUE(expected.isEqual(rangeProd));
+}
+
+TEST(IntegerRelationTest, rangeProductEmptyRange) {
+  IntegerRelation r1 =
+      parseRelationFromSet("(i, j) : (4*i + 9*j == 0, i >= 0, j >= 0)", 2);
+  IntegerRelation r2 =
+      parseRelationFromSet("(i, j) : (2*i + 3*j == 0, i >= 0, j >= 0)", 2);
+  IntegerRelation rangeProd = r1.rangeProduct(r2);
+  IntegerRelation expected =
+      parseRelationFromSet("(i, j) : (2*i + 3*j == 0, 4*i + 9*j == "
+                           "0, i >= 0, j >= 0)",
+                           2);
+  EXPECT_TRUE(expected.isEqual(rangeProd));
+}
+
+TEST(IntegerRelationTest, rangeProductEmptyDomainAndRange) {
+  IntegerRelation r1 = parseRelationFromSet("() : ()", 0);
+  IntegerRelation r2 = parseRelationFromSet("() : ()", 0);
+  IntegerRelation rangeProd = r1.rangeProduct(r2);
+  IntegerRelation expected = parseRelationFromSet("() : ()", 0);
+  EXPECT_TRUE(expected.isEqual(rangeProd));
+}
+
+TEST(IntegerRelationTest, rangeProductSymbols) {
+  IntegerRelation r1 = parseRelationFromSet(
+      "(i, j)[s] : (2*i + 3*j + s == 0, i >= 0, j >= 0)", 1);
+  IntegerRelation r2 = parseRelationFromSet(
+      "(i, l)[t] : (3*i + 4*l + t == 0, i >= 0, l >= 0)", 1);
+
+  IntegerRelation rangeProd = r1.rangeProduct(r2);
+  IntegerRelation expected = parseRelationFromSet(
+      "(i, j, k, l)[s, t] : (2*i + 3*j + s == 0, 3*i + 4*l + t == "
+      "0, i >= 0, j >= 0, l >= 0)",
+      1);
+
+  EXPECT_TRUE(expected.isEqual(rangeProd));
+}

>From cf868a9e9d0c1102fc9b502181eca2ca103d2803 Mon Sep 17 00:00:00 2001
From: Jeremy Kun <j2kun at users.noreply.github.com>
Date: Thu, 17 Jul 2025 06:40:40 -0700
Subject: [PATCH 7/7] fix symbols issue

---
 mlir/lib/Analysis/Presburger/IntegerRelation.cpp           | 6 ------
 mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp | 4 ++--
 2 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/mlir/lib/Analysis/Presburger/IntegerRelation.cpp b/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
index 90f0af088757e..5c4d4d13580a0 100644
--- a/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
+++ b/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
@@ -2490,12 +2490,6 @@ IntegerRelation IntegerRelation::rangeProduct(const IntegerRelation &rel) {
 
   // explicit copy of `this`
   IntegerRelation result = *this;
-
-  // An explicit copy of `rel` is needed to merge and align symbols, since that
-  // function mutates both relations.
-  IntegerRelation relCopy = rel;
-  result.mergeAndAlignSymbols(relCopy);
-
   unsigned relRangeVarStart = rel.getVarKindOffset(VarKind::Range);
   unsigned numThisRangeVars = getNumRangeVars();
   unsigned numNewSymbolVars = result.getNumSymbolVars() - getNumSymbolVars();
diff --git a/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp b/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
index ab2937d08eb5b..dd0b09f7f05d2 100644
--- a/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
+++ b/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
@@ -692,11 +692,11 @@ TEST(IntegerRelationTest, rangeProductSymbols) {
   IntegerRelation r1 = parseRelationFromSet(
       "(i, j)[s] : (2*i + 3*j + s == 0, i >= 0, j >= 0)", 1);
   IntegerRelation r2 = parseRelationFromSet(
-      "(i, l)[t] : (3*i + 4*l + t == 0, i >= 0, l >= 0)", 1);
+      "(i, l)[s] : (3*i + 4*l + s == 0, i >= 0, l >= 0)", 1);
 
   IntegerRelation rangeProd = r1.rangeProduct(r2);
   IntegerRelation expected = parseRelationFromSet(
-      "(i, j, k, l)[s, t] : (2*i + 3*j + s == 0, 3*i + 4*l + t == "
+      "(i, j, l)[s] : (2*i + 3*j + s == 0, 3*i + 4*l + s == "
       "0, i >= 0, j >= 0, l >= 0)",
       1);
 



More information about the Mlir-commits mailing list