diff options
author | Max Graey <maxgraey@gmail.com> | 2020-11-12 20:18:44 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-12 10:18:44 -0800 |
commit | db64c53579dd925fc48260d4979d1bb9c1dfed9f (patch) | |
tree | dc7376c34f2eb5fcd1b8a75d8bf349601aef7ce8 | |
parent | 1eb48a4f506a31e79be41f3bec091f799c6f5201 (diff) | |
download | binaryen-db64c53579dd925fc48260d4979d1bb9c1dfed9f.tar.gz binaryen-db64c53579dd925fc48260d4979d1bb9c1dfed9f.tar.bz2 binaryen-db64c53579dd925fc48260d4979d1bb9c1dfed9f.zip |
Some refactorings in addition to #3338 (#3336)
See discussion in #3303
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 26 | ||||
-rw-r--r-- | test/passes/optimize-instructions_all-features.txt | 52 | ||||
-rw-r--r-- | test/passes/optimize-instructions_all-features.wast | 52 |
3 files changed, 114 insertions, 16 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 83bee9a0f..019d6bda1 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -1936,31 +1936,27 @@ private: } } } - // signed(x - y) <=> 0 => x <=> y - // + // x - y == 0 => x == y + // x - y != 0 => x != y // unsigned(x - y) > 0 => x != y // unsigned(x - y) <= 0 => x == y { + using namespace Abstract; using namespace Match; - BinaryOp op; Binary* inner; // unsigned(x - y) > 0 => x != y if (matches(curr, - binary(Abstract::GtU, - binary(&inner, Abstract::Sub, any(), any()), - ival(0)))) { - curr->op = Abstract::getBinary(type, Abstract::Ne); + binary(GtU, binary(&inner, Sub, any(), any()), ival(0)))) { + curr->op = Abstract::getBinary(type, Ne); curr->right = inner->right; curr->left = inner->left; return curr; } // unsigned(x - y) <= 0 => x == y if (matches(curr, - binary(Abstract::LeU, - binary(&inner, Abstract::Sub, any(), any()), - ival(0)))) { - curr->op = Abstract::getBinary(type, Abstract::Eq); + binary(LeU, binary(&inner, Sub, any(), any()), ival(0)))) { + curr->op = Abstract::getBinary(type, Eq); curr->right = inner->right; curr->left = inner->left; return curr; @@ -1970,11 +1966,9 @@ private: // This is not true for signed comparisons like x -y < 0 due to overflow // effects (e.g. 8 - 0x80000000 < 0 is not the same as 8 < 0x80000000). if (matches(curr, - binary(&op, - binary(&inner, Abstract::Sub, any(), any()), - ival(0))) && - (op == Abstract::getBinary(type, Abstract::Eq) || - op == Abstract::getBinary(type, Abstract::Ne))) { + binary(Eq, binary(&inner, Sub, any(), any()), ival(0))) || + matches(curr, + binary(Ne, binary(&inner, Sub, any(), any()), ival(0)))) { curr->right = inner->right; curr->left = inner->left; return curr; diff --git a/test/passes/optimize-instructions_all-features.txt b/test/passes/optimize-instructions_all-features.txt index 7d223020f..2cf034c7a 100644 --- a/test/passes/optimize-instructions_all-features.txt +++ b/test/passes/optimize-instructions_all-features.txt @@ -4842,6 +4842,58 @@ (local.get $y) ) ) + (drop + (i32.eq + (local.get $x) + (i32.const -2147483648) + ) + ) + (drop + (i32.ne + (local.get $x) + (i32.const -2147483648) + ) + ) + (drop + (i32.lt_s + (i32.sub + (local.get $x) + (i32.const -2147483648) + ) + (i32.const 0) + ) + ) + (drop + (i32.ge_s + (i32.sub + (local.get $x) + (i32.const -2147483648) + ) + (i32.const 0) + ) + ) + (drop + (i32.gt_s + (i32.sub + (local.get $x) + (block $block (result i32) + (i32.const -2147483648) + ) + ) + (i32.const 0) + ) + ) + (drop + (i32.gt_s + (i32.sub + (local.get $x) + (block $block30 (result i32) + (i32.const -2147483648) + ) + ) + (i32.const 0) + ) + ) ) (func $unsigned-context (param $x i32) (param $y i64) (drop diff --git a/test/passes/optimize-instructions_all-features.wast b/test/passes/optimize-instructions_all-features.wast index 5804c1b2a..24e8a9d61 100644 --- a/test/passes/optimize-instructions_all-features.wast +++ b/test/passes/optimize-instructions_all-features.wast @@ -5360,6 +5360,58 @@ ) (i32.const 0) )) + ;; i32(x - 0x80000000) == 0 -> x == 0x80000000 + (drop (i32.eq + (i32.sub + (local.get $x) + (i32.const 0x80000000) + ) + (i32.const 0) + )) + ;; i32(x - 0x80000000) != 0 -> x == 0x80000000 + (drop (i32.ne + (i32.sub + (local.get $x) + (i32.const 0x80000000) + ) + (i32.const 0) + )) + ;; i32(x - { 0x80000000 }) < 0 -> skip + (drop (i32.lt_s + (i32.sub + (local.get $x) + (i32.const 0x80000000) + ) + (i32.const 0) + )) + ;; i32(x - { 0x80000000 }) >= 0 -> skip + (drop (i32.ge_s + (i32.sub + (local.get $x) + (i32.const 0x80000000) + ) + (i32.const 0) + )) + ;; i32(x - { 0x80000000 }) > 0 -> skip + (drop (i32.gt_s + (i32.sub + (local.get $x) + (block (result i32) + (i32.const 0x80000000) + ) + ) + (i32.const 0) + )) + ;; i32(x - { 0x80000000 }) <= 0 -> skip + (drop (i32.gt_s + (i32.sub + (local.get $x) + (block (result i32) + (i32.const 0x80000000) + ) + ) + (i32.const 0) + )) ) (func $unsigned-context (param $x i32) (param $y i64) (drop (i32.div_s |