-
Notifications
You must be signed in to change notification settings - Fork 871
ConstraintAnalysis: Add OR fusing of { x == C || x > C } => x >= C #8936
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
37e3f98
aa3dc24
6c7e2b0
8854733
f9ae5f1
f708a61
d00bed6
e58adf7
d9f1f87
1617154
0da0740
e793be3
e508ca6
48ee24c
c4b9d36
b31d7f9
f0dd6c8
cf8f32e
f6b58b4
60e9620
a4fc9e9
7d337dc
fb07869
023cb40
6268c82
f15411c
fd61010
9a7e163
9458a8a
0628af6
7e267ba
71736fd
859faa7
e72fa61
ebcfa80
8c76ee7
65f7508
f28a35a
2b6e73b
753490d
fa1144a
dc858e8
ed9d41f
00b33c5
e470ae1
65f85dd
2ac1514
e713c6b
f478cd0
70085e5
d153b16
e16c4c6
5ad4c40
abcfee8
a3d9a54
4b16180
14e5098
3c59516
ea598cb
f31ae72
6a3d5bc
437174c
ba4f0b5
8a4f04a
1b9efc0
0789050
5f0ad62
242dd6e
cda9027
b141979
32fa2b3
51cf381
60d3fdf
8362896
d350b97
b56f466
c536d88
0f48d73
d8747d7
09ebda2
5d4a89f
7cd6884
9b7cac8
8678398
b11e984
0069b7a
2ce896f
1acec6e
d6599aa
128e9f4
e11289e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -240,5 +240,103 @@ TEST(ConstraintTest, TestDeredundancy) { | |
| EXPECT_EQ(t[0], eq0); | ||
| } | ||
|
|
||
| // TODO: test an approximateOr of { x = 10 } and { x >= 0 }, once we support | ||
| // inequalities | ||
| static void checkOr(const AndedConstraintSet& a, | ||
| const AndedConstraintSet& b, | ||
| const AndedConstraintSet& result) { | ||
| auto ored = a; | ||
| ored.approximateOr(b); | ||
| EXPECT_EQ(ored, result); | ||
|
|
||
| ored = b; | ||
| ored.approximateOr(a); | ||
| EXPECT_EQ(ored, result); | ||
| } | ||
|
|
||
| TEST(ConstraintTest, TestOrInequality) { | ||
| // x == 5 || x >= 0 => x >= 0 | ||
| AndedConstraintSet eq5{Constraint{Eq, {Literal(int32_t(5))}}}; | ||
| AndedConstraintSet ge0{Constraint{GeU, {Literal(int32_t(0))}}}; | ||
| checkOr(eq5, ge0, ge0); | ||
|
|
||
| // x == 5 || x > 5 => x >= 5 | ||
| AndedConstraintSet gts5{Constraint{GtS, {Literal(int32_t(5))}}}; | ||
| AndedConstraintSet ges5{Constraint{GeS, {Literal(int32_t(5))}}}; | ||
| checkOr(eq5, gts5, ges5); | ||
|
|
||
| // x == 5 || x >= 5 => x >= 5 | ||
| checkOr(eq5, ges5, ges5); | ||
| } | ||
|
|
||
| TEST(ConstraintTest, TestOrLoop) { | ||
| // Check common loop patterns: | ||
| // { x == A } || { x > A && x <= B } ==> { x >= A && x <= B } | ||
|
|
||
| // { x == 5 } || { x > 5 && x <= 42 } ==> { x >= 5 && x <= 42 } | ||
| AndedConstraintSet left{Constraint{Eq, {Literal(int32_t(5))}}}; | ||
| AndedConstraintSet right( | ||
| {{GtS, {Literal(int32_t(5))}}, {LeS, {Literal(int32_t(42))}}}); | ||
| AndedConstraintSet result( | ||
| {{GeS, {Literal(int32_t(5))}}, {LeS, {Literal(int32_t(42))}}}); | ||
| checkOr(left, right, result); | ||
|
|
||
| // Changes to constants: | ||
|
|
||
| // Change 5 on the left to 7: | ||
| // { x == 7 } || { x > 5 && x <= 42 } ==> { x > 5 && x <= 42} | ||
| AndedConstraintSet left7{Constraint{Eq, {Literal(int32_t(7))}}}; | ||
| checkOr(left7, right, right); | ||
|
|
||
| // Change 5 on the left to 99: | ||
| // { x == 99 } || { x > 5 && x <= 42 } ==> { x > 5 } | ||
| // TODO: we could emit a range (5, 99] | ||
| AndedConstraintSet left99{Constraint{Eq, {Literal(int32_t(99))}}}; | ||
| AndedConstraintSet rightOnly5{Constraint{GtS, {Literal(int32_t(5))}}}; | ||
| checkOr(left99, right, rightOnly5); | ||
|
|
||
| // Change 5 on the left to 4: | ||
| // { x == 4 } || { x > 5 && x <= 42 } ==> { x <= 42 } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similarly, we can have a TODO for adding |
||
| // TODO: we could emit a range [4, 42] | ||
| AndedConstraintSet left4{Constraint{Eq, {Literal(int32_t(4))}}}; | ||
| AndedConstraintSet rightOnly42({{LeS, {Literal(int32_t(42))}}}); | ||
| checkOr(left4, right, rightOnly42); | ||
|
|
||
| // Change 5 on the right to 6: | ||
| // { x == 5 } || { x > 6 && x <= 42 } ==> { x <= 42 } | ||
| AndedConstraintSet right6( | ||
| {{GtS, {Literal(int32_t(6))}}, {LeS, {Literal(int32_t(42))}}}); | ||
| checkOr(left, right6, rightOnly42); | ||
|
|
||
| // Changes to operations: | ||
|
|
||
| // Change the Eq on the left to Ne. We fail to find anything for the OR. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TODO the result could be |
||
| // { x != 5 } || { x > 5 && x <= 42 } ==> {} | ||
| // TODO: we could emit x != 5 | ||
| AndedConstraintSet leftNe{Constraint{Ne, {Literal(int32_t(5))}}}; | ||
| auto empty = AndedConstraintSet::makeProvesNothing(); | ||
| checkOr(leftNe, right, empty); | ||
|
|
||
| // Change the GtS on the right to GtU: | ||
| // { x == 5 } || { x >U 5 && x <= 42 } ==> { x <= 42 } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume this will be improved in the next PR?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Eventually, yes, though maybe not the next PR. I'm trying to prove out the path to getting some specific Kotlin code working. I'll fill out related cases later. |
||
| AndedConstraintSet rightGtU( | ||
| {{GtU, {Literal(int32_t(5))}}, {LeS, {Literal(int32_t(42))}}}); | ||
| checkOr(left, rightGtU, rightOnly42); | ||
|
|
||
| // Change the LeS on the right to LeU: | ||
| // { x == 5 } || { x > 5 && x <=U 42 } ==> { x >= 5 && x <=U 42 } | ||
| AndedConstraintSet rightLeU( | ||
| {{GtS, {Literal(int32_t(5))}}, {LeU, {Literal(int32_t(42))}}}); | ||
| AndedConstraintSet rightGesLeU( | ||
| {{GeS, {Literal(int32_t(5))}}, {LeU, {Literal(int32_t(42))}}}); | ||
| checkOr(left, rightLeU, rightGesLeU); | ||
|
|
||
| // Add an operation on the right, x != 21: | ||
| // { x == 5 } || { x > 5 && x <= 42 && x != 21 } ==> | ||
| // { x >= 5 && x <= 42 && x != 21 } | ||
| AndedConstraintSet rightAdded({{GtS, {Literal(int32_t(5))}}, | ||
| {LeS, {Literal(int32_t(42))}}, | ||
| {Ne, {Literal(int32_t(21))}}}); | ||
| AndedConstraintSet resultAdded({{GeS, {Literal(int32_t(5))}}, | ||
| {LeS, {Literal(int32_t(42))}}, | ||
| {Ne, {Literal(int32_t(21))}}}); | ||
| checkOr(left, rightAdded, resultAdded); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can have a TODO for adding
x <= 99to the result.