summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/OptimizeInstructions.cpp68
1 files changed, 35 insertions, 33 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 9b207d6e7..286bfd2b6 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -3570,36 +3570,6 @@ private:
return left;
}
}
- // x + C1 > C2 ==> x > (C2-C1) if no overflowing, C2 >= C1
- // x + C1 > C2 ==> x + (C1-C2) > 0 if no overflowing, C2 < C1
- // And similarly for other relational operations on integers.
- if (curr->isRelational()) {
- Binary* add;
- Const* c1;
- Const* c2;
- if ((matches(curr,
- binary(binary(&add, Add, any(), ival(&c1)), ival(&c2))) ||
- matches(curr,
- binary(binary(&add, Add, any(), ival(&c1)), ival(&c2)))) &&
- !canOverflow(add)) {
- if (c2->value.geU(c1->value).getInteger()) {
- // This is the first line above, we turn into x > (C2-C1)
- c2->value = c2->value.sub(c1->value);
- curr->left = add->left;
- return curr;
- }
- // This is the second line above, we turn into x + (C1-C2) > 0. Other
- // optimizations can often kick in later. However, we must rule out the
- // case where C2 is already 0 (as then we would not actually change
- // anything, and we could infinite loop).
- auto zero = Literal::makeZero(c2->type);
- if (c2->value != zero) {
- c1->value = c1->value.sub(c2->value);
- c2->value = zero;
- return curr;
- }
- }
- }
{
// x != NaN ==> 1
// x <=> NaN ==> 0
@@ -3902,6 +3872,9 @@ private:
// TODO: templatize on type?
Expression* optimizeRelational(Binary* curr) {
+ using namespace Abstract;
+ using namespace Match;
+
auto type = curr->right->type;
if (curr->left->type.isInteger()) {
if (curr->op == Abstract::getBinary(type, Abstract::Eq) ||
@@ -3935,9 +3908,6 @@ private:
// unsigned(x - y) > 0 => x != y
// unsigned(x - y) <= 0 => x == y
{
- using namespace Abstract;
- using namespace Match;
-
Binary* inner;
// unsigned(x - y) > 0 => x != y
if (matches(curr,
@@ -3969,6 +3939,38 @@ private:
}
}
+ // x + C1 > C2 ==> x > (C2-C1) if no overflowing, C2 >= C1
+ // x + C1 > C2 ==> x + (C1-C2) > 0 if no overflowing, C2 < C1
+ // And similarly for other relational operations on integers with a "+"
+ // on the left.
+ {
+ Binary* add;
+ Const* c1;
+ Const* c2;
+ if ((matches(curr,
+ binary(binary(&add, Add, any(), ival(&c1)), ival(&c2))) ||
+ matches(curr,
+ binary(binary(&add, Add, any(), ival(&c1)), ival(&c2)))) &&
+ !canOverflow(add)) {
+ if (c2->value.geU(c1->value).getInteger()) {
+ // This is the first line above, we turn into x > (C2-C1)
+ c2->value = c2->value.sub(c1->value);
+ curr->left = add->left;
+ return curr;
+ }
+ // This is the second line above, we turn into x + (C1-C2) > 0. Other
+ // optimizations can often kick in later. However, we must rule out
+ // the case where C2 is already 0 (as then we would not actually
+ // change anything, and we could infinite loop).
+ auto zero = Literal::makeZero(c2->type);
+ if (c2->value != zero) {
+ c1->value = c1->value.sub(c2->value);
+ c2->value = zero;
+ return curr;
+ }
+ }
+ }
+
// Comparisons can sometimes be simplified depending on the number of
// bits, e.g. (unsigned)x > y must be true if x has strictly more bits.
// A common case is a constant on the right, e.g. (x & 255) < 256 must be