Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 35 additions & 33 deletions src/passes/OptimizeInstructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3570,36 +3570,6 @@ struct OptimizeInstructions
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
Expand Down Expand Up @@ -3902,6 +3872,9 @@ struct OptimizeInstructions

// 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) ||
Expand Down Expand Up @@ -3935,9 +3908,6 @@ struct OptimizeInstructions
// 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,
Expand Down Expand Up @@ -3969,6 +3939,38 @@ struct OptimizeInstructions
}
}

// 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
Expand Down