summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2018-01-17 21:20:53 -0800
committerGitHub <noreply@github.com>2018-01-17 21:20:53 -0800
commit14cb0c01ee22fbcd2923db0502e11b1fc51df05d (patch)
treeeb4c6c854a803482c2891e7235ea8700886d289c
parent692069c6eef63754c27e815fd948fea6185d7619 (diff)
downloadbinaryen-14cb0c01ee22fbcd2923db0502e11b1fc51df05d.tar.gz
binaryen-14cb0c01ee22fbcd2923db0502e11b1fc51df05d.tar.bz2
binaryen-14cb0c01ee22fbcd2923db0502e11b1fc51df05d.zip
optimize out 0-x, a zero only used to negate an int, when possible (#1365)
-rw-r--r--src/passes/OptimizeInstructions.cpp38
-rw-r--r--test/emcc_O2_hello_world.fromasm7
-rw-r--r--test/emcc_O2_hello_world.fromasm.clamp7
-rw-r--r--test/emcc_O2_hello_world.fromasm.imprecise7
-rw-r--r--test/emcc_hello_world.fromasm7
-rw-r--r--test/emcc_hello_world.fromasm.clamp7
-rw-r--r--test/emcc_hello_world.fromasm.imprecise11
-rw-r--r--test/memorygrowth.fromasm7
-rw-r--r--test/memorygrowth.fromasm.clamp7
-rw-r--r--test/memorygrowth.fromasm.imprecise7
-rw-r--r--test/passes/optimize-instructions.txt32
-rw-r--r--test/passes/optimize-instructions.wast45
12 files changed, 134 insertions, 48 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 06f3d5b02..efea99247 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -506,7 +506,43 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions,
}
}
// note that both left and right may be consts, but then we let precompute compute the constant result
- } else if (binary->op == AddInt32 || binary->op == SubInt32) {
+ } else if (binary->op == AddInt32) {
+ // try to get rid of (0 - ..), that is, a zero only used to negate an
+ // int. an add of a subtract can be flipped in order to remove it:
+ // (i32.add
+ // (i32.sub
+ // (i32.const 0)
+ // X
+ // )
+ // Y
+ // )
+ // =>
+ // (i32.sub
+ // Y
+ // X
+ // )
+ if (auto* sub = binary->left->dynCast<Binary>()) {
+ if (sub->op == SubInt32) {
+ if (auto* subZero = sub->left->dynCast<Const>()) {
+ if (subZero->value.geti32() == 0) {
+ sub->left = binary->right;
+ return sub;
+ }
+ }
+ }
+ }
+ if (auto* sub = binary->right->dynCast<Binary>()) {
+ if (sub->op == SubInt32) {
+ if (auto* subZero = sub->left->dynCast<Const>()) {
+ if (subZero->value.geti32() == 0) {
+ sub->left = binary->left;
+ return sub;
+ }
+ }
+ }
+ }
+ return optimizeAddedConstants(binary);
+ } else if (binary->op == SubInt32) {
return optimizeAddedConstants(binary);
}
// a bunch of operations on a constant right side can be simplified
diff --git a/test/emcc_O2_hello_world.fromasm b/test/emcc_O2_hello_world.fromasm
index 0bc4edf68..082240fc4 100644
--- a/test/emcc_O2_hello_world.fromasm
+++ b/test/emcc_O2_hello_world.fromasm
@@ -5966,12 +5966,9 @@
(if
(i32.lt_u
(tee_local $1
- (i32.add
+ (i32.sub
(get_local $1)
- (i32.sub
- (i32.const 0)
- (get_local $11)
- )
+ (get_local $11)
)
)
(get_local $14)
diff --git a/test/emcc_O2_hello_world.fromasm.clamp b/test/emcc_O2_hello_world.fromasm.clamp
index 0bc4edf68..082240fc4 100644
--- a/test/emcc_O2_hello_world.fromasm.clamp
+++ b/test/emcc_O2_hello_world.fromasm.clamp
@@ -5966,12 +5966,9 @@
(if
(i32.lt_u
(tee_local $1
- (i32.add
+ (i32.sub
(get_local $1)
- (i32.sub
- (i32.const 0)
- (get_local $11)
- )
+ (get_local $11)
)
)
(get_local $14)
diff --git a/test/emcc_O2_hello_world.fromasm.imprecise b/test/emcc_O2_hello_world.fromasm.imprecise
index 1fe0499f9..0bad341fb 100644
--- a/test/emcc_O2_hello_world.fromasm.imprecise
+++ b/test/emcc_O2_hello_world.fromasm.imprecise
@@ -5965,12 +5965,9 @@
(if
(i32.lt_u
(tee_local $1
- (i32.add
+ (i32.sub
(get_local $1)
- (i32.sub
- (i32.const 0)
- (get_local $11)
- )
+ (get_local $11)
)
)
(get_local $14)
diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm
index 17fb1483f..849b42aac 100644
--- a/test/emcc_hello_world.fromasm
+++ b/test/emcc_hello_world.fromasm
@@ -13329,12 +13329,9 @@
(if
(i32.lt_u
(tee_local $1
- (i32.add
+ (i32.sub
(get_local $1)
- (i32.sub
- (i32.const 0)
- (get_local $7)
- )
+ (get_local $7)
)
)
(get_local $11)
diff --git a/test/emcc_hello_world.fromasm.clamp b/test/emcc_hello_world.fromasm.clamp
index 230b06413..1a55405ac 100644
--- a/test/emcc_hello_world.fromasm.clamp
+++ b/test/emcc_hello_world.fromasm.clamp
@@ -13379,12 +13379,9 @@
(if
(i32.lt_u
(tee_local $1
- (i32.add
+ (i32.sub
(get_local $1)
- (i32.sub
- (i32.const 0)
- (get_local $7)
- )
+ (get_local $7)
)
)
(get_local $11)
diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise
index d932b35eb..34f3e1c95 100644
--- a/test/emcc_hello_world.fromasm.imprecise
+++ b/test/emcc_hello_world.fromasm.imprecise
@@ -13263,14 +13263,11 @@
(if
(i32.lt_u
(tee_local $1
- (i32.add
+ (i32.sub
(get_local $1)
- (i32.sub
- (i32.const 0)
- (tee_local $8
- (i32.load
- (get_local $1)
- )
+ (tee_local $8
+ (i32.load
+ (get_local $1)
)
)
)
diff --git a/test/memorygrowth.fromasm b/test/memorygrowth.fromasm
index c807bf937..291cd515d 100644
--- a/test/memorygrowth.fromasm
+++ b/test/memorygrowth.fromasm
@@ -6017,12 +6017,9 @@
(if
(i32.lt_u
(tee_local $1
- (i32.add
+ (i32.sub
(get_local $1)
- (i32.sub
- (i32.const 0)
- (get_local $10)
- )
+ (get_local $10)
)
)
(get_local $14)
diff --git a/test/memorygrowth.fromasm.clamp b/test/memorygrowth.fromasm.clamp
index c807bf937..291cd515d 100644
--- a/test/memorygrowth.fromasm.clamp
+++ b/test/memorygrowth.fromasm.clamp
@@ -6017,12 +6017,9 @@
(if
(i32.lt_u
(tee_local $1
- (i32.add
+ (i32.sub
(get_local $1)
- (i32.sub
- (i32.const 0)
- (get_local $10)
- )
+ (get_local $10)
)
)
(get_local $14)
diff --git a/test/memorygrowth.fromasm.imprecise b/test/memorygrowth.fromasm.imprecise
index bf23a9a1f..bb9d95844 100644
--- a/test/memorygrowth.fromasm.imprecise
+++ b/test/memorygrowth.fromasm.imprecise
@@ -6015,12 +6015,9 @@
(if
(i32.lt_u
(tee_local $1
- (i32.add
+ (i32.sub
(get_local $1)
- (i32.sub
- (i32.const 0)
- (get_local $10)
- )
+ (get_local $10)
)
)
(get_local $14)
diff --git a/test/passes/optimize-instructions.txt b/test/passes/optimize-instructions.txt
index 50858c81d..88709e2fe 100644
--- a/test/passes/optimize-instructions.txt
+++ b/test/passes/optimize-instructions.txt
@@ -2264,6 +2264,38 @@
)
)
)
+ (func $subzero1 (; 56 ;) (type $3) (param $0 i32) (result i32)
+ (i32.sub
+ (i32.const 32)
+ (i32.clz
+ (get_local $0)
+ )
+ )
+ )
+ (func $subzero2 (; 57 ;) (type $3) (param $0 i32) (result i32)
+ (i32.sub
+ (i32.const 32)
+ (i32.clz
+ (get_local $0)
+ )
+ )
+ )
+ (func $subzero3 (; 58 ;) (type $6) (param $0 i32) (param $1 i32) (result i32)
+ (i32.sub
+ (get_local $1)
+ (i32.clz
+ (get_local $0)
+ )
+ )
+ )
+ (func $subzero4 (; 59 ;) (type $6) (param $0 i32) (param $1 i32) (result i32)
+ (i32.sub
+ (get_local $0)
+ (i32.clz
+ (get_local $1)
+ )
+ )
+ )
)
(module
(type $0 (func))
diff --git a/test/passes/optimize-instructions.wast b/test/passes/optimize-instructions.wast
index 34b805f3d..60bfc9b7d 100644
--- a/test/passes/optimize-instructions.wast
+++ b/test/passes/optimize-instructions.wast
@@ -2663,6 +2663,50 @@
(i32.and (i32.wrap/i64 (i64.const 1)) (i32.eqz (get_local $y)))
)
)
+ (func $subzero1 (param $0 i32) (result i32)
+ (i32.add
+ (i32.sub
+ (i32.const 1)
+ (i32.clz
+ (get_local $0)
+ )
+ )
+ (i32.const 31)
+ )
+ )
+ (func $subzero2 (param $0 i32) (result i32)
+ (i32.add
+ (i32.const 31)
+ (i32.sub
+ (i32.const 1)
+ (i32.clz
+ (get_local $0)
+ )
+ )
+ )
+ )
+ (func $subzero3 (param $0 i32) (param $1 i32) (result i32)
+ (i32.add
+ (i32.sub
+ (i32.const 0)
+ (i32.clz
+ (get_local $0)
+ )
+ )
+ (get_local $1)
+ )
+ )
+ (func $subzero4 (param $0 i32) (param $1 i32) (result i32)
+ (i32.add
+ (get_local $0)
+ (i32.sub
+ (i32.const 0)
+ (i32.clz
+ (get_local $1)
+ )
+ )
+ )
+ )
)
(module
(import "env" "memory" (memory $0 (shared 256 256)))
@@ -2680,3 +2724,4 @@
)
)
)
+