[Mlir-commits] [mlir] [MLIR][Presburger] Add enum based dispatch for isEmpty (PR #93010)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed May 22 02:32:58 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-affine
Author: Kunwar Grover (Groverkss)
<details>
<summary>Changes</summary>
This patch adds an enum to dispatch to different available solvers for emptiness check. This allows the user to make a more informed choice on what emptiness check they are using.
---
Patch is 26.42 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/93010.diff
12 Files Affected:
- (modified) mlir/include/mlir/Analysis/Presburger/IntegerRelation.h (+41-20)
- (modified) mlir/include/mlir/Analysis/Presburger/PresburgerRelation.h (+3-6)
- (modified) mlir/lib/Analysis/Presburger/IntegerRelation.cpp (+22-3)
- (modified) mlir/lib/Analysis/Presburger/PWMAFunction.cpp (+3-2)
- (modified) mlir/lib/Analysis/Presburger/PresburgerRelation.cpp (+14-19)
- (modified) mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp (+1-1)
- (modified) mlir/lib/Dialect/Affine/Analysis/Utils.cpp (+7-7)
- (modified) mlir/lib/Interfaces/ValueBoundsOpInterface.cpp (+2-2)
- (modified) mlir/unittests/Analysis/Presburger/IntegerPolyhedronTest.cpp (+17-17)
- (modified) mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp (+4-4)
- (modified) mlir/unittests/Analysis/Presburger/PresburgerRelationTest.cpp (+6-6)
- (modified) mlir/unittests/Analysis/Presburger/PresburgerSetTest.cpp (+4-2)
``````````diff
diff --git a/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h b/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h
index 163f365c623d7..f8c45247d58ce 100644
--- a/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h
+++ b/mlir/include/mlir/Analysis/Presburger/IntegerRelation.h
@@ -34,6 +34,20 @@ struct SymbolicLexOpt;
/// The type of bound: equal, lower bound or upper bound.
enum class BoundType { EQ, LB, UB };
+/// The kind of solver to use for emptiness check.
+/// TODO: We should have some docs to explain the user what kind of solver
+/// should fit best for their use case.
+enum class SolverKind {
+ // Integer Exact algorithm.
+ IntegerSimplex,
+ // Rational Exact algorithm.
+ RationalSimplex,
+ // Rationly Exact algorithm.
+ FourierMotzkin,
+ // Fast heuristic based algorithm (no guarantees).
+ FastHeuristics
+};
+
/// An IntegerRelation represents the set of points from a PresburgerSpace that
/// satisfy a list of affine constraints. Affine constraints can be inequalities
/// or equalities in the form:
@@ -366,26 +380,9 @@ class IntegerRelation {
SmallVectorImpl<unsigned> *eqIndices = nullptr,
unsigned offset = 0, unsigned num = 0) const;
- /// Checks for emptiness by performing variable elimination on all
- /// variables, running the GCD test on each equality constraint, and
- /// checking for invalid constraints. Returns true if the GCD test fails for
- /// any equality, or if any invalid constraints are discovered on any row.
- /// Returns false otherwise.
- bool isEmpty() const;
-
- /// Performs GCD checks and invalid constraint checks.
- bool isObviouslyEmpty() const;
-
- /// Runs the GCD test on all equality constraints. Returns true if this test
- /// fails on any equality. Returns false otherwise.
- /// This test can be used to disprove the existence of a solution. If it
- /// returns true, no integer solution to the equality constraints can exist.
- bool isEmptyByGCDTest() const;
-
- /// Returns true if the set of constraints is found to have no solution,
- /// false if a solution exists. Uses the same algorithm as
- /// `findIntegerSample`.
- bool isIntegerEmpty() const;
+ /// Check if the given relation/polyhedron is empty. The emptiness guarantees
+ /// depend on the solver used.
+ bool isEmpty(SolverKind kind) const;
/// Returns a matrix where each row is a vector along which the polytope is
/// bounded. The span of the returned vectors is guaranteed to contain all
@@ -754,6 +751,30 @@ class IntegerRelation {
return computeConstantLowerOrUpperBound<isLower>(pos).map(int64FromMPInt);
}
+ /// Checks for emptiness by performing variable elimination on all
+ /// variables, running the GCD test on each equality constraint, and
+ /// checking for invalid constraints. Returns true if the GCD test fails for
+ /// any equality, or if any invalid constraints are discovered on any row.
+ /// Returns false otherwise.
+ bool isEmptyByFMTest() const;
+
+ /// Performs GCD checks and invalid constraint checks.
+ bool isObviouslyEmpty() const;
+
+ /// Runs the GCD test on all equality constraints. Returns true if this test
+ /// fails on any equality. Returns false otherwise.
+ /// This test can be used to disprove the existence of a solution. If it
+ /// returns true, no integer solution to the equality constraints can exist.
+ bool isEmptyByGCDTest() const;
+
+ /// Returns true if the set of constraints is found to have no integer
+ /// solution, false if a solution exists.
+ bool isIntegerEmpty() const;
+
+ /// Returns true if the set of constraints is found to have no rational
+ /// solution, false if a solution exists.
+ bool isRationalEmpty() const;
+
/// Eliminates a single variable at `position` from equality and inequality
/// constraints. Returns `success` if the variable was eliminated, and
/// `failure` otherwise.
diff --git a/mlir/include/mlir/Analysis/Presburger/PresburgerRelation.h b/mlir/include/mlir/Analysis/Presburger/PresburgerRelation.h
index 9634df6d58a1a..aeb73984bcc99 100644
--- a/mlir/include/mlir/Analysis/Presburger/PresburgerRelation.h
+++ b/mlir/include/mlir/Analysis/Presburger/PresburgerRelation.h
@@ -164,12 +164,9 @@ class PresburgerRelation {
/// All local variables in both sets must correspond to floor divisions.
bool isEqual(const PresburgerRelation &set) const;
- /// Return true if all the sets in the union are known to be integer empty
- /// false otherwise.
- bool isIntegerEmpty() const;
-
- /// Return true if there is no disjunct, false otherwise.
- bool isObviouslyEmpty() const;
+ /// Check if the given relation/polyhedron is empty. The emptiness guarantees
+ /// depend on the solver used.
+ bool isEmpty(SolverKind kind) const;
/// Return true if the set is known to have one unconstrained disjunct, false
/// otherwise.
diff --git a/mlir/lib/Analysis/Presburger/IntegerRelation.cpp b/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
index b5a2ed6ccc369..8697d6d046e89 100644
--- a/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
+++ b/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
@@ -689,7 +689,7 @@ static unsigned getBestVarToEliminate(const IntegerRelation &cst,
// using the GCD test (on all equality constraints) and checking for trivially
// invalid constraints. Returns 'true' if the constraint system is found to be
// empty; false otherwise.
-bool IntegerRelation::isEmpty() const {
+bool IntegerRelation::isEmptyByFMTest() const {
if (isEmptyByGCDTest() || hasInvalidConstraint())
return true;
@@ -817,8 +817,27 @@ IntMatrix IntegerRelation::getBoundedDirections() const {
return dirs;
}
+bool IntegerRelation::isEmpty(SolverKind kind) const {
+ switch (kind) {
+ case SolverKind::IntegerSimplex:
+ return isIntegerEmpty();
+ case SolverKind::RationalSimplex:
+ return isRationalEmpty();
+ case SolverKind::FourierMotzkin:
+ return isEmptyByFMTest();
+ case SolverKind::FastHeuristics:
+ return isObviouslyEmpty();
+ }
+}
+
bool IntegerRelation::isIntegerEmpty() const { return !findIntegerSample(); }
+bool IntegerRelation::isRationalEmpty() const {
+ // TODO: We should cache the simplex at some point.
+ Simplex simplex(*this);
+ return simplex.isEmpty();
+}
+
/// Let this set be S. If S is bounded then we directly call into the GBR
/// sampling algorithm. Otherwise, there are some unbounded directions, i.e.,
/// vectors v such that S extends to infinity along v or -v. In this case we
@@ -1180,7 +1199,7 @@ void IntegerRelation::removeRedundantInequalities() {
// Change the inequality to its complement.
tmpCst.inequalities.negateRow(r);
--tmpCst.atIneq(r, tmpCst.getNumCols() - 1);
- if (tmpCst.isEmpty()) {
+ if (tmpCst.isEmpty(SolverKind::FourierMotzkin)) {
redun[r] = true;
// Zero fill the redundant inequality.
inequalities.fillRow(r, /*value=*/0);
@@ -2506,7 +2525,7 @@ void IntegerRelation::removeTrivialEqualities() {
bool IntegerRelation::isFullDim() {
if (getNumVars() == 0)
return true;
- if (isEmpty())
+ if (isEmpty(SolverKind::FourierMotzkin))
return false;
// If there is a non-trivial equality, the space cannot be full-dimensional.
diff --git a/mlir/lib/Analysis/Presburger/PWMAFunction.cpp b/mlir/lib/Analysis/Presburger/PWMAFunction.cpp
index d55962616de17..4911b237e1425 100644
--- a/mlir/lib/Analysis/Presburger/PWMAFunction.cpp
+++ b/mlir/lib/Analysis/Presburger/PWMAFunction.cpp
@@ -293,8 +293,9 @@ bool PWMAFunction::isEqual(const PWMAFunction &other) const {
void PWMAFunction::addPiece(const Piece &piece) {
assert(piece.isConsistent() && "Piece should be consistent");
- assert(piece.domain.intersect(getDomain()).isIntegerEmpty() &&
- "Piece should be disjoint from the function");
+ assert(
+ piece.domain.intersect(getDomain()).isEmpty(SolverKind::IntegerSimplex) &&
+ "Piece should be disjoint from the function");
pieces.push_back(piece);
}
diff --git a/mlir/lib/Analysis/Presburger/PresburgerRelation.cpp b/mlir/lib/Analysis/Presburger/PresburgerRelation.cpp
index 3af6baae0e700..25a443b6bf818 100644
--- a/mlir/lib/Analysis/Presburger/PresburgerRelation.cpp
+++ b/mlir/lib/Analysis/Presburger/PresburgerRelation.cpp
@@ -94,11 +94,11 @@ void PresburgerRelation::unionInPlace(const PresburgerRelation &set) {
if (isObviouslyEqual(set))
return;
- if (isObviouslyEmpty()) {
+ if (isEmpty(SolverKind::FastHeuristics)) {
disjuncts = set.disjuncts;
return;
}
- if (set.isObviouslyEmpty())
+ if (set.isEmpty(SolverKind::FastHeuristics))
return;
if (isObviouslyUniverse())
@@ -152,17 +152,17 @@ PresburgerRelation::intersect(const PresburgerRelation &set) const {
// If the set is empty or the other set is universe,
// directly return the set
- if (isObviouslyEmpty() || set.isObviouslyUniverse())
+ if (isEmpty(SolverKind::FastHeuristics) || set.isObviouslyUniverse())
return *this;
- if (set.isObviouslyEmpty() || isObviouslyUniverse())
+ if (set.isEmpty(SolverKind::FastHeuristics) || isObviouslyUniverse())
return set;
PresburgerRelation result(getSpace());
for (const IntegerRelation &csA : disjuncts) {
for (const IntegerRelation &csB : set.disjuncts) {
IntegerRelation intersection = csA.intersect(csB);
- if (!intersection.isEmpty())
+ if (!intersection.isEmpty(SolverKind::IntegerSimplex))
result.unionInPlace(intersection);
}
}
@@ -224,7 +224,7 @@ void PresburgerRelation::compose(const PresburgerRelation &rel) {
for (const IntegerRelation &csB : rel.disjuncts) {
IntegerRelation composition = csA;
composition.compose(csB);
- if (!composition.isEmpty())
+ if (!composition.isEmpty(SolverKind::IntegerSimplex))
result.unionInPlace(composition);
}
}
@@ -347,7 +347,7 @@ PresburgerRelation PresburgerRelation::computeReprWithOnlyDivLocals() const {
static PresburgerRelation getSetDifference(IntegerRelation b,
const PresburgerRelation &s) {
assert(b.getSpace().isCompatible(s.getSpace()) && "Spaces should match");
- if (b.isEmptyByGCDTest())
+ if (b.isEmpty(SolverKind::FastHeuristics))
return PresburgerRelation::getEmpty(b.getSpaceWithoutLocals());
if (!s.hasOnlyDivLocals())
@@ -617,7 +617,7 @@ PresburgerRelation::subtract(const PresburgerRelation &set) const {
/// point then this is a point that is contained in T but not S, and
/// if T contains a point that is not in S, this also lies in T \ S.
bool PresburgerRelation::isSubsetOf(const PresburgerRelation &set) const {
- return this->subtract(set).isIntegerEmpty();
+ return this->subtract(set).isEmpty(SolverKind::IntegerSimplex);
}
/// Two sets are equal iff they are subsets of each other.
@@ -658,16 +658,11 @@ bool PresburgerRelation::isConvexNoLocals() const {
return getNumDisjuncts() == 1 && getSpace().getNumLocalVars() == 0;
}
-/// Return true if there is no disjunct, false otherwise.
-bool PresburgerRelation::isObviouslyEmpty() const {
- return getNumDisjuncts() == 0;
-}
-
-/// Return true if all the sets in the union are known to be integer empty,
-/// false otherwise.
-bool PresburgerRelation::isIntegerEmpty() const {
- // The set is empty iff all of the disjuncts are empty.
- return llvm::all_of(disjuncts, std::mem_fn(&IntegerRelation::isIntegerEmpty));
+bool PresburgerRelation::isEmpty(SolverKind kind) const {
+ auto disjunctCheck = [&kind](const IntegerRelation &disjunct) {
+ return disjunct.isEmpty(kind);
+ };
+ return llvm::all_of(disjuncts, disjunctCheck);
}
bool PresburgerRelation::findIntegerSample(SmallVectorImpl<MPInt> &sample) {
@@ -1035,7 +1030,7 @@ PresburgerRelation PresburgerRelation::simplify() const {
PresburgerRelation result = PresburgerRelation(getSpace());
for (IntegerRelation &disjunct : origin.disjuncts) {
disjunct.simplify();
- if (!disjunct.isObviouslyEmpty())
+ if (!disjunct.isEmpty(SolverKind::FastHeuristics))
result.unionInPlace(disjunct);
}
return result;
diff --git a/mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp b/mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp
index 9b776900c379a..7d20473f0b05f 100644
--- a/mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp
+++ b/mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp
@@ -668,7 +668,7 @@ DependenceResult mlir::affine::checkMemrefAccessDependence(
addOrderingConstraints(srcDomain, dstDomain, loopDepth, &dependenceDomain);
// Return 'NoDependence' if the solution space is empty: no dependence.
- if (dependenceDomain.isEmpty())
+ if (dependenceDomain.isEmpty(SolverKind::FourierMotzkin))
return DependenceResult::NoDependence;
// Compute dependence direction vector and return true.
diff --git a/mlir/lib/Dialect/Affine/Analysis/Utils.cpp b/mlir/lib/Dialect/Affine/Analysis/Utils.cpp
index 194ee9115e3d7..4fd3e165f50c0 100644
--- a/mlir/lib/Dialect/Affine/Analysis/Utils.cpp
+++ b/mlir/lib/Dialect/Affine/Analysis/Utils.cpp
@@ -875,7 +875,7 @@ std::optional<bool> ComputationSliceState::isSliceValid() const {
PresburgerSet sliceSet(sliceConstraints);
PresburgerSet diffSet = sliceSet.subtract(srcSet);
- if (!diffSet.isIntegerEmpty()) {
+ if (!diffSet.isEmpty(SolverKind::IntegerSimplex)) {
LLVM_DEBUG(llvm::dbgs() << "Incorrect slice\n");
return false;
}
@@ -932,7 +932,7 @@ std::optional<bool> ComputationSliceState::isMaximal() const {
PresburgerSet srcSet(srcConstraints);
PresburgerSet sliceSet(sliceConstraints);
PresburgerSet diffSet = srcSet.subtract(sliceSet);
- return diffSet.isIntegerEmpty();
+ return diffSet.isEmpty(SolverKind::IntegerSimplex);
}
unsigned MemRefRegion::getRank() const {
@@ -1294,7 +1294,7 @@ LogicalResult mlir::affine::boundCheckLoadOrStoreOp(LoadOrStoreOp loadOrStoreOp,
// Check for overflow: d_i >= memref dim size.
ucst.addBound(BoundType::LB, r, dimSize);
- outOfBounds = !ucst.isEmpty();
+ outOfBounds = !ucst.isEmpty(SolverKind::FourierMotzkin);
if (outOfBounds && emitError) {
loadOrStoreOp.emitOpError()
<< "memref out of upper bound access along dimension #" << (r + 1);
@@ -1305,7 +1305,7 @@ LogicalResult mlir::affine::boundCheckLoadOrStoreOp(LoadOrStoreOp loadOrStoreOp,
std::fill(ineq.begin(), ineq.end(), 0);
// d_i <= -1;
lcst.addBound(BoundType::UB, r, -1);
- outOfBounds = !lcst.isEmpty();
+ outOfBounds = !lcst.isEmpty(SolverKind::FourierMotzkin);
if (outOfBounds && emitError) {
loadOrStoreOp.emitOpError()
<< "memref out of lower bound access along dimension #" << (r + 1);
@@ -1979,7 +1979,7 @@ void mlir::affine::getSequentialLoops(
IntegerSet mlir::affine::simplifyIntegerSet(IntegerSet set) {
FlatAffineValueConstraints fac(set);
- if (fac.isEmpty())
+ if (fac.isEmpty(SolverKind::FourierMotzkin))
return IntegerSet::getEmptySet(set.getNumDims(), set.getNumSymbols(),
set.getContext());
fac.removeTrivialRedundancy();
@@ -2108,7 +2108,7 @@ FailureOr<AffineValueMap> mlir::affine::simplifyConstrainedMinMaxOp(
// If the constraint system is empty, there is an inconsistency. (E.g., this
// can happen if loop lb > ub.)
- if (constraints.isEmpty())
+ if (constraints.isEmpty(SolverKind::FourierMotzkin))
return failure();
// In the case of `isMin` (`!isMin` is inversed):
@@ -2141,7 +2141,7 @@ FailureOr<AffineValueMap> mlir::affine::simplifyConstrainedMinMaxOp(
ineq[i] = isMin ? -1 : 1;
ineq[newConstr.getNumCols() - 1] = -1;
newConstr.addInequality(ineq);
- if (!newConstr.isEmpty())
+ if (!newConstr.isEmpty(SolverKind::FourierMotzkin))
return failure();
}
diff --git a/mlir/lib/Interfaces/ValueBoundsOpInterface.cpp b/mlir/lib/Interfaces/ValueBoundsOpInterface.cpp
index 87937591e60ad..21f96b30c0d8b 100644
--- a/mlir/lib/Interfaces/ValueBoundsOpInterface.cpp
+++ b/mlir/lib/Interfaces/ValueBoundsOpInterface.cpp
@@ -692,7 +692,7 @@ bool ValueBoundsConstraintSet::comparePos(int64_t lhsPos,
// lhs > rhs must be incorrect and we can deduce that lhs <= rhs holds.
// We cannot prove anything if the constraint set is already empty.
- if (cstr.isEmpty()) {
+ if (cstr.isEmpty(presburger::SolverKind::FourierMotzkin)) {
LLVM_DEBUG(
llvm::dbgs()
<< "cannot compare value/dims: constraint system is already empty");
@@ -722,7 +722,7 @@ bool ValueBoundsConstraintSet::comparePos(int64_t lhsPos,
// set empty.
int64_t ineqPos = cstr.getNumInequalities();
cstr.addInequality(eq);
- bool isEmpty = cstr.isEmpty();
+ bool isEmpty = cstr.isEmpty(presburger::SolverKind::FourierMotzkin);
cstr.removeInequality(ineqPos);
return isEmpty;
}
diff --git a/mlir/unittests/Analysis/Presburger/IntegerPolyhedronTest.cpp b/mlir/unittests/Analysis/Presburger/IntegerPolyhedronTest.cpp
index ba035e84ff1fd..9261110b3a678 100644
--- a/mlir/unittests/Analysis/Presburger/IntegerPolyhedronTest.cpp
+++ b/mlir/unittests/Analysis/Presburger/IntegerPolyhedronTest.cpp
@@ -93,7 +93,7 @@ static void checkSample(bool hasSample, const IntegerPolyhedron &poly,
}
break;
case TestFunction::Empty:
- EXPECT_EQ(!hasSample, poly.isIntegerEmpty());
+ EXPECT_EQ(!hasSample, poly.isEmpty(SolverKind::IntegerSimplex));
break;
}
}
@@ -443,35 +443,35 @@ TEST(IntegerPolyhedronTest, FindSampleTest) {
TEST(IntegerPolyhedronTest, IsIntegerEmptyTest) {
// 1 <= 5x and 5x <= 4 (no solution).
EXPECT_TRUE(parseIntegerPolyhedron("(x) : (5 * x - 1 >= 0, -5 * x + 4 >= 0)")
- .isIntegerEmpty());
+ .isEmpty(SolverKind::IntegerSimplex));
// 1 <= 5x and 5x <= 9 (solution: x = 1).
EXPECT_FALSE(parseIntegerPolyhedron("(x) : (5 * x - 1 >= 0, -5 * x + 9 >= 0)")
- .isIntegerEmpty());
+ .isEmpty(SolverKind::IntegerSimplex));
// Unbounded sets.
EXPECT_TRUE(
parseIntegerPolyhedron("(x,y,z) : (2 * y - 1 >= 0, -2 * y + 1 >= 0, "
"2 * z - 1 >= 0, 2 * x - 1 == 0)")
- .isIntegerEmpty());
+ .isEmpty(SolverKind::IntegerSimplex));
EXPECT_FALSE(parseIntegerPolyhedron(
"(x,y,z) : (2 * x - 1 >= 0, -3 * x + 3 >= 0, "
"5 * z - 6 >= 0, -7 * z + 17 >= 0, 3 * y - 2 >= 0)")
- .isIntegerEmpty());
+ .isEmpty(SolverKind::IntegerSimplex));
EXPECT_FALSE(parseIntegerPolyhedron(
"(x,y,z) : (2 * x - 1 >= 0, x - y - 1 == 0, y - z == 0)")
- .isIntegerEmpty());
+ .isEmpty(SolverKind::IntegerSimplex));
- // IntegerPolyhedron::isEmpty() does not detect the following sets to be
- // empty.
+ // IntegerPolyhedron::isEmpty(SolverKind::FourierMotzkin) does
+ // not detect the following sets to be empty.
// 3x + 7y = 1 and 0 <= x, y <= 10.
// Since x and y are non-negative, 3x + 7y can never be 1.
EXPECT_TRUE(parseIntegerPolyhedron(
"(x,y) : (x >= 0, -x + 10 >= 0, y >= 0, -y + 10 >= 0, "
"3 * x + 7 * y - 1 == 0)")
- .isIntegerEmpty());
+ .isEmpty(SolverKind::IntegerSimplex));
// 2x = 3y and y = x - 1 and x + y = 6z + 2 and 0 <= x, y <= 100.
// Substituting y = x - 1 in 3y = 2x, we obtain x = 3 and hence y = 2.
@@ -479,7 +479,7 @@ TEST(IntegerPolyhedronTest, IsIntegerEmptyTest) {
EXPECT_TRUE(parseIntegerPolyhedron(
"(x,y,z) : (x >= 0, -x + 100 >= 0, y >= 0, -y + 100 >= 0, "
"2 * x - 3 * y == 0, x - y - 1 == 0, x + y - 6 * z - 2 == 0)")
- .isIntegerEmpty());
+ .isEmpty(SolverKind::IntegerSimplex));
// 2x = 3y and y = x - 1 + 6z and x + y = 6q + 2 and 0 <= x, y <= 100.
// 2x = 3y implies x is a multiple of 3 and y is even.
@@ -490,11 +490,11 @@ TEST(IntegerPolyhedronTest, IsIntegerEmptyTest) {
parseIntegerPolyhedron(
"(x,y,z,q) : (x >= 0, -x + 100 >= 0, y >= 0, -y + 100 >= 0, "
"2 * x - 3 * y == 0, x - y + 6 * z - 1 == 0, x + y - 6 * q - 2 == 0)")
- .isIntegerEmpty());
+ .isEmpty(SolverKind::IntegerSimplex));
// Set with symbols.
EXPECT_FALSE(parseIntegerPolyhedron("(x)[s] : (x + s >= 0, x - s == 0)")
- .isIntegerEmpty());
+ ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/93010
More information about the Mlir-commits
mailing list