Skip to content

Commit 2b0604f

Browse files
author
v01dxyz
committed
[ConstraintSystem] Relax system if elimination not possible
When constructing a new constraint from a pair of lower/upper constraints on the variable to eliminate, it simply ignores the new constraint by not adding it if an overflow occurs when computing one of its coefficients or if there are already too many constraints. Previously, it simply stopped at this stage and considered the system as having solution. Thus adding new constraints could turn a unsatisfiable system into a possibly satisfiable one which is a little bit strange. Unsatisfiability of the new system still implies unsatisfiability of the former one (the projected solution set of the original system is included in the solution set of the new system).
1 parent bf6ccd2 commit 2b0604f

File tree

3 files changed

+25
-15
lines changed

3 files changed

+25
-15
lines changed

llvm/include/llvm/Analysis/ConstraintSystem.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ class ConstraintSystem {
4343
return 0;
4444
}
4545

46+
// WARNING: it represents rather the maximum number of coefficients in the constraints
47+
// which is actually the number of variables PLUS one (for the constant part).
4648
size_t NumVariables = 0;
4749

4850
/// Current linear constraints in the system.
@@ -54,7 +56,13 @@ class ConstraintSystem {
5456
/// constraint system.
5557
DenseMap<Value *, unsigned> Value2Index;
5658

57-
// Eliminate constraints from the system using Fourier–Motzkin elimination.
59+
// Eliminate the last variable from the system using Fourier–Motzkin
60+
// elimination, while possibly relaxing it if it is beyond
61+
// acceptable means (too many created constraints, overflow when
62+
// computing the coefficients)
63+
//
64+
// return true if the updated system is equivalent, otherwise return
65+
// false if it is relaxed.
5866
bool eliminateUsingFM();
5967

6068
/// Returns true if there may be a solution for the constraints in the system.

llvm/lib/Analysis/ConstraintSystem.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ bool ConstraintSystem::eliminateUsingFM() {
4747
}
4848
}
4949

50+
// Track if an overflow occurred when computing coefficents
51+
bool Overflow = false;
52+
5053
// Process rows where the variable is != 0.
5154
unsigned NumRemainingConstraints = RemainingRows.size();
5255
for (unsigned R1 = 0; R1 < NumRemainingConstraints; R1++) {
@@ -95,14 +98,11 @@ bool ConstraintSystem::eliminateUsingFM() {
9598
IdxLower += 1;
9699
}
97100

98-
if (MulOverflow(UpperV, -1 * LowerLast, M1))
99-
return false;
100-
101-
if (MulOverflow(LowerV, UpperLast, M2))
102-
return false;
103-
104-
if (AddOverflow(M1, M2, N))
105-
return false;
101+
if (MulOverflow(UpperV, -1 * LowerLast, M1) ||
102+
MulOverflow(LowerV, UpperLast, M2) || AddOverflow(M1, M2, N)) {
103+
Overflow = true;
104+
continue;
105+
}
106106

107107
// useless to add a 0 to a sparse vector
108108
if (N == 0)
@@ -120,13 +120,16 @@ bool ConstraintSystem::eliminateUsingFM() {
120120
}
121121
NumVariables -= 1;
122122

123-
return true;
123+
return !Overflow;
124124
}
125125

126126
bool ConstraintSystem::mayHaveSolutionImpl() {
127-
while (!Constraints.empty() && NumVariables > 1) {
128-
if (!eliminateUsingFM())
129-
return true;
127+
while (!Constraints.empty() && Constraints.size() <= 500 && NumVariables > 1) {
128+
if(!eliminateUsingFM()) {
129+
LLVM_DEBUG(
130+
dbgs()
131+
<< "Some new constraints has been ignored during elimination.\n");
132+
};
130133
}
131134

132135
if (Constraints.empty() || NumVariables > 1)

llvm/test/Transforms/ConstraintElimination/constraint-overflow.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ define i32 @f(i64 %a3, i64 %numElements) {
1313
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[A1]], [[A3]]
1414
; CHECK-NEXT: br i1 [[CMP]], label [[IF_END_I:%.*]], label [[ABORT:%.*]]
1515
; CHECK: if.end.i:
16-
; CHECK-NEXT: [[CMP2_NOT_I:%.*]] = icmp ult i64 [[A1]], [[A3]]
17-
; CHECK-NEXT: br i1 [[CMP2_NOT_I]], label [[ABORT]], label [[EXIT:%.*]]
16+
; CHECK-NEXT: br i1 false, label [[ABORT]], label [[EXIT:%.*]]
1817
; CHECK: abort:
1918
; CHECK-NEXT: ret i32 -1
2019
; CHECK: exit:

0 commit comments

Comments
 (0)