summaryrefslogtreecommitdiff
path: root/src/passes/OptimizeInstructions.cpp
diff options
context:
space:
mode:
authorMax Graey <maxgraey@gmail.com>2021-11-17 02:08:30 +0200
committerGitHub <noreply@github.com>2021-11-16 16:08:30 -0800
commit87fce24735f7fb1815fc6d0fa7fda8a33bcaeefd (patch)
tree36f2aa453fb8d8fa01929db0714eac164a577319 /src/passes/OptimizeInstructions.cpp
parenta3ad58215d054db36da7596ec7d082c029e0affa (diff)
downloadbinaryen-87fce24735f7fb1815fc6d0fa7fda8a33bcaeefd.tar.gz
binaryen-87fce24735f7fb1815fc6d0fa7fda8a33bcaeefd.tar.bz2
binaryen-87fce24735f7fb1815fc6d0fa7fda8a33bcaeefd.zip
[OptimizeInstructions] Combine some relational ops joined Or/And (Part 2) (#4336)
(i32(x) != 0) | (i32(y) != 0) ==> i32(x | y) != 0 (i64(x) != 0) | (i64(y) != 0) ==> i64(x | y) != 0
Diffstat (limited to 'src/passes/OptimizeInstructions.cpp')
-rw-r--r--src/passes/OptimizeInstructions.cpp29
1 files changed, 24 insertions, 5 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index c0ba2dc02..aa3de46e8 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -2513,11 +2513,15 @@ private:
}
// We can combine `or` operations, e.g.
- // (x > y) | (x == y) ==> x >= y
- Expression* combineOr(Binary* binary) {
- assert(binary->op == OrInt32);
- if (auto* left = binary->left->dynCast<Binary>()) {
- if (auto* right = binary->right->dynCast<Binary>()) {
+ // (x > y) | (x == y) ==> x >= y
+ // (x != 0) | (y != 0) ==> (x | y) != 0
+ Expression* combineOr(Binary* curr) {
+ using namespace Abstract;
+ using namespace Match;
+
+ assert(curr->op == OrInt32);
+ if (auto* left = curr->left->dynCast<Binary>()) {
+ if (auto* right = curr->right->dynCast<Binary>()) {
if (left->op != right->op &&
ExpressionAnalyzer::equal(left->left, right->left) &&
ExpressionAnalyzer::equal(left->right, right->right) &&
@@ -2538,6 +2542,21 @@ private:
}
}
}
+ {
+ // (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(OrInt32,
+ binary(Ne, any(&x), ival(0)),
+ binary(Ne, any(&y), ival(0)))) &&
+ x->type == y->type) {
+ auto* inner = curr->left->cast<Binary>();
+ inner->left = Builder(*getModule())
+ .makeBinary(Abstract::getBinary(x->type, Or), x, y);
+ return inner;
+ }
+ }
return nullptr;
}