diff --git a/mlir/lib/Analysis/Presburger/Simplex.cpp b/mlir/lib/Analysis/Presburger/Simplex.cpp --- a/mlir/lib/Analysis/Presburger/Simplex.cpp +++ b/mlir/lib/Analysis/Presburger/Simplex.cpp @@ -357,6 +357,11 @@ /// Mark this tableau empty and push an entry to the undo stack. void Simplex::markEmpty() { + // If the set is already empty, then we shouldn't add another UnmarkEmpty log + // entry, since in that case the Simplex will be erroneously marked as + // non-empty when rolling back past this point. + if (empty) + return; undoLog.push_back(UndoLogEntry::UnmarkEmpty); empty = true; } diff --git a/mlir/unittests/Analysis/Presburger/SimplexTest.cpp b/mlir/unittests/Analysis/Presburger/SimplexTest.cpp --- a/mlir/unittests/Analysis/Presburger/SimplexTest.cpp +++ b/mlir/unittests/Analysis/Presburger/SimplexTest.cpp @@ -19,14 +19,22 @@ Simplex simplex(2); // (u - v) >= 0 simplex.addInequality({1, -1, 0}); - EXPECT_FALSE(simplex.isEmpty()); + ASSERT_FALSE(simplex.isEmpty()); unsigned snapshot = simplex.getSnapshot(); // (u - v) <= -1 simplex.addInequality({-1, 1, -1}); - EXPECT_TRUE(simplex.isEmpty()); + ASSERT_TRUE(simplex.isEmpty()); + + unsigned snapshot2 = simplex.getSnapshot(); + simplex.addInequality({-1, 1, -3}); + ASSERT_TRUE(simplex.isEmpty()); + + simplex.rollback(snapshot2); + ASSERT_TRUE(simplex.isEmpty()); + simplex.rollback(snapshot); - EXPECT_FALSE(simplex.isEmpty()); + ASSERT_FALSE(simplex.isEmpty()); } /// Check that the set gets marked as empty when we add contradictory