summaryrefslogtreecommitdiff
path: root/src/passes/OptimizeInstructions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes/OptimizeInstructions.cpp')
-rw-r--r--src/passes/OptimizeInstructions.cpp42
1 files changed, 34 insertions, 8 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 7c450ac06..c0ba2dc02 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -772,16 +772,21 @@ struct OptimizeInstructions
return replaceCurrent(ret);
}
}
- // bitwise operations
- // for and and or, we can potentially conditionalize
if (curr->op == AndInt32 || curr->op == OrInt32) {
- if (auto* ret = conditionalizeExpensiveOnBitwise(curr)) {
- return replaceCurrent(ret);
+ if (curr->op == AndInt32) {
+ if (auto* ret = combineAnd(curr)) {
+ return replaceCurrent(ret);
+ }
}
- }
- // for or, we can potentially combine
- if (curr->op == OrInt32) {
- if (auto* ret = combineOr(curr)) {
+ // for or, we can potentially combine
+ if (curr->op == OrInt32) {
+ if (auto* ret = combineOr(curr)) {
+ return replaceCurrent(ret);
+ }
+ }
+ // bitwise operations
+ // for and and or, we can potentially conditionalize
+ if (auto* ret = conditionalizeExpensiveOnBitwise(curr)) {
return replaceCurrent(ret);
}
}
@@ -2486,6 +2491,27 @@ private:
}
}
+ // We can combine `and` operations, e.g.
+ // (x == 0) & (y == 0) ==> (x | y) == 0
+ Expression* combineAnd(Binary* curr) {
+ using namespace Abstract;
+ using namespace Match;
+ {
+ // (i32(x) == 0) & (i32(y) == 0) ==> i32(x | y) == 0
+ // (i64(x) == 0) & (i64(y) == 0) ==> i64(x | y) == 0
+ Expression *x, *y;
+ if (matches(curr,
+ binary(AndInt32, unary(EqZ, any(&x)), unary(EqZ, any(&y)))) &&
+ x->type == y->type) {
+ auto* inner = curr->left->cast<Unary>();
+ inner->value = Builder(*getModule())
+ .makeBinary(Abstract::getBinary(x->type, Or), x, y);
+ return inner;
+ }
+ }
+ return nullptr;
+ }
+
// We can combine `or` operations, e.g.
// (x > y) | (x == y) ==> x >= y
Expression* combineOr(Binary* binary) {