[Mlir-commits] [mlir] b045729 - [mlir][presburger] add functionality to compute local mod in IntegerRelation (#153614)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Fri Aug 15 09:55:16 PDT 2025
Author: asraa
Date: 2025-08-15T09:55:13-07:00
New Revision: b045729eb4d66ff76df469e1a995cea4e4f383ba
URL: https://github.com/llvm/llvm-project/commit/b045729eb4d66ff76df469e1a995cea4e4f383ba
DIFF: https://github.com/llvm/llvm-project/commit/b045729eb4d66ff76df469e1a995cea4e4f383ba.diff
LOG: [mlir][presburger] add functionality to compute local mod in IntegerRelation (#153614)
Similar to `IntegerRelation::addLocalFloorDiv`, this adds a utility
`IntegerRelation::addLocalModulo` that adds and returns a local variable
that is the modulus of an affine function of the variables modulo some
constant modulus. The function returns the absolute index of the new var
in the relation.
This is computed by first finding the floordiv of `exprs // modulus = q`
and then computing the remainder `result = exprs - q * modulus`.
Signed-off-by: Asra Ali <asraa at google.com>
Added:
Modified:
mlir/include/mlir/Analysis/Presburger/IntegerRelation.h
mlir/lib/Analysis/Presburger/IntegerRelation.cpp
mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
Removed:
################################################################################
diff --git a/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h b/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h
index 4b1802413f75f..335a2dddc7561 100644
--- a/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h
+++ b/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h
@@ -485,6 +485,22 @@ class IntegerRelation {
addLocalFloorDiv(getDynamicAPIntVec(dividend), DynamicAPInt(divisor));
}
+ /// Adds a new local variable as the modulus of an affine function of other
+ /// variables, the coefficients of which are provided in `exprs`. The modulus
+ /// is with respect to a positive constant `modulus`. The function returns the
+ /// absolute index of the new local variable representing the result of the
+ /// modulus operation. Two new local variables are added to the system, one
+ /// representing the floor div with respect to the modulus and one
+ /// representing the mod. Three constraints are added to the system to capture
+ /// the equivalance. The first two are required to compute the result of the
+ /// floor division `q`, and the third computes the equality relation:
+ /// result = exprs - modulus * q.
+ unsigned addLocalModulo(ArrayRef<DynamicAPInt> exprs,
+ const DynamicAPInt &modulus);
+ unsigned addLocalModulo(ArrayRef<int64_t> exprs, int64_t modulus) {
+ return addLocalModulo(getDynamicAPIntVec(exprs), DynamicAPInt(modulus));
+ }
+
/// Projects out (aka eliminates) `num` variables starting at position
/// `pos`. The resulting constraint system is the shadow along the dimensions
/// that still exist. This method may not always be integer exact.
diff --git a/mlir/lib/Analysis/Presburger/IntegerRelation.cpp b/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
index 5c4d4d13580a0..1d1e4ded19db1 100644
--- a/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
+++ b/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
@@ -1515,6 +1515,27 @@ void IntegerRelation::addLocalFloorDiv(ArrayRef<DynamicAPInt> dividend,
getDivUpperBound(dividendCopy, divisor, dividendCopy.size() - 2));
}
+unsigned IntegerRelation::addLocalModulo(ArrayRef<DynamicAPInt> exprs,
+ const DynamicAPInt &modulus) {
+ assert(exprs.size() == getNumCols() && "incorrect exprs size");
+ assert(modulus > 0 && "positive modulus expected");
+
+ /// Add a local variable for q = expr floordiv modulus
+ addLocalFloorDiv(exprs, modulus);
+
+ /// Add a local var to represent the result
+ auto resultIndex = appendVar(VarKind::Local);
+
+ SmallVector<DynamicAPInt, 8> exprsCopy(exprs);
+ /// Insert the two new locals before the constant
+ /// Add locals that correspond to `q` and `result` to compute
+ /// 0 = (expr - modulus * q) - result
+ exprsCopy.insert(exprsCopy.end() - 1,
+ {DynamicAPInt(-modulus), DynamicAPInt(-1)});
+ addEquality(exprsCopy);
+ return resultIndex;
+}
+
int IntegerRelation::findEqualityToConstant(unsigned pos, bool symbolic) const {
assert(pos < getNumVars() && "invalid position");
for (unsigned r = 0, e = getNumEqualities(); r < e; r++) {
diff --git a/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp b/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
index a6ed5c5b21e79..9ae90a4841f3c 100644
--- a/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
+++ b/mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp
@@ -714,3 +714,14 @@ TEST(IntegerRelationTest, getVarKindRange) {
}
EXPECT_THAT(actual, ElementsAre(2, 3, 4));
}
+
+TEST(IntegerRelationTest, addLocalModulo) {
+ IntegerRelation rel = parseRelationFromSet("(x) : (x >= 0, 100 - x >= 0)", 1);
+ unsigned result = rel.addLocalModulo({1, 0}, 32); // x % 32
+ rel.convertVarKind(VarKind::Local,
+ result - rel.getVarKindOffset(VarKind::Local),
+ rel.getNumVarKind(VarKind::Local), VarKind::Range);
+ for (unsigned x = 0; x <= 100; ++x) {
+ EXPECT_TRUE(rel.containsPointNoLocal({x, x % 32}));
+ }
+}
More information about the Mlir-commits
mailing list