diff options
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 38 | ||||
-rw-r--r-- | test/emcc_O2_hello_world.fromasm | 7 | ||||
-rw-r--r-- | test/emcc_O2_hello_world.fromasm.clamp | 7 | ||||
-rw-r--r-- | test/emcc_O2_hello_world.fromasm.imprecise | 7 | ||||
-rw-r--r-- | test/emcc_hello_world.fromasm | 7 | ||||
-rw-r--r-- | test/emcc_hello_world.fromasm.clamp | 7 | ||||
-rw-r--r-- | test/emcc_hello_world.fromasm.imprecise | 11 | ||||
-rw-r--r-- | test/memorygrowth.fromasm | 7 | ||||
-rw-r--r-- | test/memorygrowth.fromasm.clamp | 7 | ||||
-rw-r--r-- | test/memorygrowth.fromasm.imprecise | 7 | ||||
-rw-r--r-- | test/passes/optimize-instructions.txt | 32 | ||||
-rw-r--r-- | test/passes/optimize-instructions.wast | 45 |
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 @@ ) ) ) + |