summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/passes/OptimizeInstructions.cpp48
1 files changed, 46 insertions, 2 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index f23c119ec..a52126c5a 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -1869,14 +1869,58 @@ private:
};
// Prefer a const on the right.
if (binary->left->is<Const>() && !binary->right->is<Const>()) {
- return swap();
+ swap();
}
if (auto* c = binary->right->dynCast<Const>()) {
- // x - C ==> x + (-C)
+ // x - C ==> x + (-C)
// Prefer use addition if there is a constant on the right.
if (binary->op == Abstract::getBinary(c->type, Abstract::Sub)) {
c->value = c->value.neg();
binary->op = Abstract::getBinary(c->type, Abstract::Add);
+ return;
+ }
+ // Prefer to compare to 0 instead of to -1 or 1.
+ // (signed)x > -1 ==> x >= 0
+ if (binary->op == Abstract::getBinary(c->type, Abstract::GtS) &&
+ c->value.getInteger() == -1LL) {
+ binary->op = Abstract::getBinary(c->type, Abstract::GeS);
+ c->value = Literal::makeZero(c->type);
+ return;
+ }
+ // (signed)x <= -1 ==> x < 0
+ if (binary->op == Abstract::getBinary(c->type, Abstract::LeS) &&
+ c->value.getInteger() == -1LL) {
+ binary->op = Abstract::getBinary(c->type, Abstract::LtS);
+ c->value = Literal::makeZero(c->type);
+ return;
+ }
+ // (signed)x < 1 ==> x <= 0
+ if (binary->op == Abstract::getBinary(c->type, Abstract::LtS) &&
+ c->value.getInteger() == 1LL) {
+ binary->op = Abstract::getBinary(c->type, Abstract::LeS);
+ c->value = Literal::makeZero(c->type);
+ return;
+ }
+ // (signed)x >= 1 ==> x > 0
+ if (binary->op == Abstract::getBinary(c->type, Abstract::GeS) &&
+ c->value.getInteger() == 1LL) {
+ binary->op = Abstract::getBinary(c->type, Abstract::GtS);
+ c->value = Literal::makeZero(c->type);
+ return;
+ }
+ // (unsigned)x < 1 ==> x == 0
+ if (binary->op == Abstract::getBinary(c->type, Abstract::LtU) &&
+ c->value.getInteger() == 1LL) {
+ binary->op = Abstract::getBinary(c->type, Abstract::Eq);
+ c->value = Literal::makeZero(c->type);
+ return;
+ }
+ // (unsigned)x >= 1 ==> x != 0
+ if (binary->op == Abstract::getBinary(c->type, Abstract::GeU) &&
+ c->value.getInteger() == 1LL) {
+ binary->op = Abstract::getBinary(c->type, Abstract::Ne);
+ c->value = Literal::makeZero(c->type);
+ return;
}
return;
}