summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/OptimizeInstructions.cpp13
-rw-r--r--test/passes/optimize-instructions_all-features.txt30
-rw-r--r--test/passes/optimize-instructions_all-features.wast46
3 files changed, 87 insertions, 2 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 85ab2a168..1790623eb 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -515,12 +515,21 @@ struct OptimizeInstructions
if (auto* left = binary->left->dynCast<Binary>()) {
if (left->op == binary->op) {
if (auto* leftRight = left->right->dynCast<Const>()) {
- if (left->op == AndInt32) {
+ if (left->op == AndInt32 || left->op == AndInt64) {
leftRight->value = leftRight->value.and_(right->value);
return left;
- } else if (left->op == OrInt32) {
+ } else if (left->op == OrInt32 || left->op == OrInt64) {
leftRight->value = leftRight->value.or_(right->value);
return left;
+ } else if (left->op == XorInt32 || left->op == XorInt64) {
+ leftRight->value = leftRight->value.xor_(right->value);
+ return left;
+ } else if (left->op == MulInt32 || left->op == MulInt64) {
+ leftRight->value = leftRight->value.mul(right->value);
+ return left;
+
+ // TODO:
+ // handle signed / unsigned divisions. They are more complex
} else if (left->op == ShlInt32 || left->op == ShrUInt32 ||
left->op == ShrSInt32 || left->op == ShlInt64 ||
left->op == ShrUInt64 || left->op == ShrSInt64) {
diff --git a/test/passes/optimize-instructions_all-features.txt b/test/passes/optimize-instructions_all-features.txt
index 93f4c3087..edebe0bc2 100644
--- a/test/passes/optimize-instructions_all-features.txt
+++ b/test/passes/optimize-instructions_all-features.txt
@@ -23,6 +23,36 @@
(memory $0 0)
(export "load-off-2" (func $load-off-2))
(func $f (param $i1 i32) (param $i2 i64)
+ (drop
+ (i32.and
+ (local.get $i1)
+ (i32.const 1)
+ )
+ )
+ (drop
+ (i32.or
+ (local.get $i1)
+ (i32.const 3)
+ )
+ )
+ (drop
+ (i32.xor
+ (local.get $i1)
+ (i32.const 5)
+ )
+ )
+ (drop
+ (i32.mul
+ (local.get $i1)
+ (i32.const -10)
+ )
+ )
+ (drop
+ (i32.mul
+ (local.get $i1)
+ (i32.const -133169153)
+ )
+ )
(if
(i32.eqz
(local.get $i1)
diff --git a/test/passes/optimize-instructions_all-features.wast b/test/passes/optimize-instructions_all-features.wast
index 80f440a59..cf3938cdf 100644
--- a/test/passes/optimize-instructions_all-features.wast
+++ b/test/passes/optimize-instructions_all-features.wast
@@ -2,6 +2,52 @@
(memory 0)
(type $0 (func (param i32 i64)))
(func $f (type $0) (param $i1 i32) (param $i2 i64)
+ (drop
+ (i32.and
+ (i32.and
+ (local.get $i1)
+ (i32.const 5)
+ )
+ (i32.const 3)
+ )
+ )
+ (drop
+ (i32.or
+ (i32.or
+ (local.get $i1)
+ (i32.const 1)
+ )
+ (i32.const 2)
+ )
+ )
+ (drop
+ (i32.xor
+ (i32.xor
+ (local.get $i1)
+ (i32.const -2)
+ )
+ (i32.const -5)
+ )
+ )
+ (drop
+ (i32.mul
+ (i32.mul
+ (local.get $i1)
+ (i32.const -2)
+ )
+ (i32.const 5)
+ )
+ )
+ ;; overflow also valid
+ (drop
+ (i32.mul
+ (i32.mul
+ (local.get $i1)
+ (i32.const 0xfffff)
+ )
+ (i32.const 0x8000001)
+ )
+ )
(if
(i32.eqz
(local.get $i1)