aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArjun P <arjunpitchanathan@gmail.com>2022-03-22 13:21:20 +0000
committerArjun P <arjunpitchanathan@gmail.com>2022-03-23 10:53:32 +0000
commitff44760427dbaff0cf63dbdf64a7708a73e1d595 (patch)
tree400cbfc0bfc92c1863794c0984057bb24bea00d7
parent47eb4f7dcd845878b16a53dadd765195b9c24b6e (diff)
downloadllvm-ff44760427dbaff0cf63dbdf64a7708a73e1d595.zip
llvm-ff44760427dbaff0cf63dbdf64a7708a73e1d595.tar.gz
llvm-ff44760427dbaff0cf63dbdf64a7708a73e1d595.tar.bz2
[MLIR][Presburger] add Simplex:addDivisionVariable
This is a convenience function for adding new divisions to the Simplex given the numerator and denominator. This will be needed for symbolic integer lexmin support. Reviewed By: Groverkss Differential Revision: https://reviews.llvm.org/D122159
-rw-r--r--mlir/include/mlir/Analysis/Presburger/Simplex.h4
-rw-r--r--mlir/lib/Analysis/Presburger/Simplex.cpp22
-rw-r--r--mlir/unittests/Analysis/Presburger/SimplexTest.cpp10
3 files changed, 36 insertions, 0 deletions
diff --git a/mlir/include/mlir/Analysis/Presburger/Simplex.h b/mlir/include/mlir/Analysis/Presburger/Simplex.h
index 07d7318..8a4ea2a 100644
--- a/mlir/include/mlir/Analysis/Presburger/Simplex.h
+++ b/mlir/include/mlir/Analysis/Presburger/Simplex.h
@@ -185,6 +185,10 @@ public:
/// Add new variables to the end of the list of variables.
void appendVariable(unsigned count = 1);
+ /// Append a new variable to the simplex and constrain it such that its only
+ /// integer value is the floor div of `coeffs` and `denom`.
+ void addDivisionVariable(ArrayRef<int64_t> coeffs, int64_t denom);
+
/// Mark the tableau as being empty.
void markEmpty();
diff --git a/mlir/lib/Analysis/Presburger/Simplex.cpp b/mlir/lib/Analysis/Presburger/Simplex.cpp
index 8c9f017..a79bbb0 100644
--- a/mlir/lib/Analysis/Presburger/Simplex.cpp
+++ b/mlir/lib/Analysis/Presburger/Simplex.cpp
@@ -818,6 +818,28 @@ void SimplexBase::rollback(unsigned snapshot) {
}
}
+/// We add the usual floor division constraints:
+/// `0 <= coeffs - denom*q <= denom - 1`, where `q` is the new division
+/// variable.
+///
+/// This constrains the remainder `coeffs - denom*q` to be in the
+/// range `[0, denom - 1]`, which fixes the integer value of the quotient `q`.
+void SimplexBase::addDivisionVariable(ArrayRef<int64_t> coeffs, int64_t denom) {
+ assert(denom != 0 && "Cannot divide by zero!\n");
+ appendVariable();
+
+ SmallVector<int64_t, 8> ineq(coeffs.begin(), coeffs.end());
+ int64_t constTerm = ineq.back();
+ ineq.back() = -denom;
+ ineq.push_back(constTerm);
+ addInequality(ineq);
+
+ for (int64_t &coeff : ineq)
+ coeff = -coeff;
+ ineq.back() += denom - 1;
+ addInequality(ineq);
+}
+
void SimplexBase::appendVariable(unsigned count) {
if (count == 0)
return;
diff --git a/mlir/unittests/Analysis/Presburger/SimplexTest.cpp b/mlir/unittests/Analysis/Presburger/SimplexTest.cpp
index a66f1fe..e605c89 100644
--- a/mlir/unittests/Analysis/Presburger/SimplexTest.cpp
+++ b/mlir/unittests/Analysis/Presburger/SimplexTest.cpp
@@ -538,3 +538,13 @@ TEST(SimplexTest, IsRationalSubsetOf) {
EXPECT_TRUE(sim2.isRationalSubsetOf(s2));
EXPECT_FALSE(sim2.isRationalSubsetOf(empty));
}
+
+TEST(SimplexTest, addDivisionVariable) {
+ Simplex simplex(/*nVar=*/1);
+ simplex.addDivisionVariable({1, 0}, 2);
+ simplex.addInequality({1, 0, -3}); // x >= 3.
+ simplex.addInequality({-1, 0, 9}); // x <= 9.
+ Optional<SmallVector<int64_t, 8>> sample = simplex.findIntegerSample();
+ ASSERT_TRUE(sample.hasValue());
+ EXPECT_EQ((*sample)[0] / 2, (*sample)[1]);
+}