summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMax Graey <maxgraey@gmail.com>2021-11-17 00:58:13 +0200
committerGitHub <noreply@github.com>2021-11-16 14:58:13 -0800
commit62c5209be6482836175a236f946b3a7261a47856 (patch)
tree0a479520c4479647506766b29424e7c9d418a92e /src
parent4b3d5be999baac642e7664da39c37c6012c11513 (diff)
downloadbinaryen-62c5209be6482836175a236f946b3a7261a47856.tar.gz
binaryen-62c5209be6482836175a236f946b3a7261a47856.tar.bz2
binaryen-62c5209be6482836175a236f946b3a7261a47856.zip
[OptimizeInstructions] Combine some relational ops joined Or/And (Part 1) (#4333)
(i32(x) == 0) & (i32(y) == 0) ==> i32(x | y) == 0 (i64(x) == 0) & (i64(y) == 0) ==> i64(x | y) == 0
Diffstat (limited to 'src')
-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) {