diff options
author | Max Graey <maxgraey@gmail.com> | 2020-09-17 20:31:27 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-17 10:31:27 -0700 |
commit | 9f7a053bf0ca3185336eb4616f88d85df573adbf (patch) | |
tree | d4cfd91bfeffb3864aae2d3d3cca1092129840d2 /test/passes | |
parent | edc03a69da757e9b106b67647d7914b94680b97a (diff) | |
download | binaryen-9f7a053bf0ca3185336eb4616f88d85df573adbf.tar.gz binaryen-9f7a053bf0ca3185336eb4616f88d85df573adbf.tar.bz2 binaryen-9f7a053bf0ca3185336eb4616f88d85df573adbf.zip |
Unary and binary duplicate expression elimination (#3047)
Simplifies patterns in which an expression is applied twice to its operands.
`abs(abs(x))` -> `abs(x)`
`ceil(ceil(x))` -> `ceil(x)`
`floor(floor(x))` -> `floor(x)`
`trunc(trunc(x))` -> `trunc(x)`
`nearest(nearest(x))` -> `nearest(x)`
`eqz(eqz(bool(x)))` -> `bool(x)`
`sext(sext(x))` -> `sext(x)`
`neg(neg(x))` -> `x`
`y - (y - x)` -> `x`
`(x ^ y) ^ y` -> `x`
`(x | y) | y` -> `x | y`
`(x & y) & y` -> `x & y`
`(x % y) % y` -> `x % y`
Diffstat (limited to 'test/passes')
-rw-r--r-- | test/passes/optimize-instructions_all-features.txt | 253 | ||||
-rw-r--r-- | test/passes/optimize-instructions_all-features.wast | 241 |
2 files changed, 490 insertions, 4 deletions
diff --git a/test/passes/optimize-instructions_all-features.txt b/test/passes/optimize-instructions_all-features.txt index 33e137b9d..dda7a47c0 100644 --- a/test/passes/optimize-instructions_all-features.txt +++ b/test/passes/optimize-instructions_all-features.txt @@ -12,6 +12,7 @@ (type $i32_i64_f32_f64_=>_none (func (param i32 i64 f32 f64))) (type $none_=>_anyref (func (result anyref))) (type $i32_i32_i32_=>_none (func (param i32 i32 i32))) + (type $i32_i32_i32_f64_=>_none (func (param i32 i32 i32 f64))) (type $i32_i32_f64_f64_=>_none (func (param i32 i32 f64 f64))) (type $i32_i64_f64_i32_=>_none (func (param i32 i64 f64 i32))) (type $f32_f64_=>_none (func (param f32 f64))) @@ -1301,10 +1302,7 @@ (drop (i32.and (local.get $0) - (i32.and - (local.get $0) - (i32.const 11) - ) + (i32.const 11) ) ) (drop @@ -3786,6 +3784,253 @@ ) ) ) + (func $duplicate-elimination (param $x i32) (param $y i32) (param $z i32) (param $w f64) + (drop + (f64.abs + (local.get $w) + ) + ) + (drop + (f64.ceil + (local.get $w) + ) + ) + (drop + (f64.floor + (local.get $w) + ) + ) + (drop + (f64.trunc + (local.get $w) + ) + ) + (drop + (f64.nearest + (local.get $w) + ) + ) + (drop + (f64.nearest + (f64.trunc + (local.get $w) + ) + ) + ) + (drop + (f64.trunc + (f64.nearest + (local.get $w) + ) + ) + ) + (drop + (local.get $w) + ) + (drop + (f64.neg + (local.get $w) + ) + ) + (drop + (local.get $w) + ) + (drop + (i32.eqz + (i32.eqz + (local.get $x) + ) + ) + ) + (drop + (i32.eqz + (local.get $x) + ) + ) + (drop + (i64.eqz + (i64.const 1) + ) + ) + (drop + (i32.ne + (local.get $x) + (i32.const 2) + ) + ) + (drop + (i32.extend8_s + (local.get $x) + ) + ) + (drop + (i32.extend16_s + (local.get $x) + ) + ) + (drop + (i32.and + (local.get $x) + (i32.const 1) + ) + ) + (drop + (i32.rem_s + (local.get $x) + (local.get $y) + ) + ) + (drop + (i32.rem_u + (local.get $x) + (local.get $y) + ) + ) + (drop + (local.get $y) + ) + (drop + (local.get $y) + ) + (drop + (i32.sub + (local.get $y) + (i32.sub + (local.get $x) + (local.get $y) + ) + ) + ) + (drop + (local.get $y) + ) + (drop + (local.get $y) + ) + (drop + (local.get $y) + ) + (drop + (local.get $y) + ) + (drop + (local.get $x) + ) + (drop + (i32.and + (local.get $x) + (local.get $y) + ) + ) + (drop + (i32.and + (local.get $x) + (local.get $y) + ) + ) + (drop + (i32.and + (local.get $x) + (local.get $y) + ) + ) + (drop + (i32.and + (local.get $x) + (local.get $y) + ) + ) + (drop + (i32.or + (local.get $x) + (local.get $y) + ) + ) + (drop + (i32.or + (local.get $x) + (local.get $y) + ) + ) + (drop + (i32.or + (local.get $x) + (local.get $y) + ) + ) + (drop + (i32.or + (local.get $x) + (local.get $y) + ) + ) + (drop + (i32.or + (local.get $z) + (i32.or + (local.get $x) + (local.get $y) + ) + ) + ) + (drop + (i32.or + (local.get $y) + (i32.or + (local.get $x) + (local.get $z) + ) + ) + ) + (drop + (i32.or + (call $ne0) + (local.get $x) + ) + ) + (drop + (i32.or + (i32.or + (call $ne0) + (local.get $x) + ) + (call $ne0) + ) + ) + (drop + (i32.or + (call $ne0) + (local.get $x) + ) + ) + (drop + (i32.or + (call $ne0) + (i32.or + (call $ne0) + (local.get $x) + ) + ) + ) + (drop + (i32.rem_s + (i32.rem_s + (local.get $y) + (local.get $x) + ) + (local.get $y) + ) + ) + (drop + (i32.rem_u + (local.get $y) + (i32.rem_u + (local.get $x) + (local.get $y) + ) + ) + ) + ) (func $optimize-bulk-memory-copy (param $dst i32) (param $src i32) (param $sz i32) (memory.copy (local.get $dst) diff --git a/test/passes/optimize-instructions_all-features.wast b/test/passes/optimize-instructions_all-features.wast index c67270a4f..7dc8cffbf 100644 --- a/test/passes/optimize-instructions_all-features.wast +++ b/test/passes/optimize-instructions_all-features.wast @@ -4289,6 +4289,247 @@ ) )) ) + (func $duplicate-elimination (param $x i32) (param $y i32) (param $z i32) (param $w f64) + ;; unary + (drop (f64.abs (f64.abs (local.get $w)))) + (drop (f64.ceil (f64.ceil (local.get $w)))) + (drop (f64.floor (f64.floor (local.get $w)))) + (drop (f64.trunc (f64.trunc (local.get $w)))) + (drop (f64.nearest (f64.nearest (local.get $w)))) + + (drop (f64.nearest (f64.trunc (local.get $w)))) ;; skip + (drop (f64.trunc (f64.nearest (local.get $w)))) ;; skip + + (drop (f64.neg (f64.neg (local.get $w)))) + (drop (f64.neg (f64.neg (f64.neg (local.get $w))))) + (drop (f64.neg (f64.neg (f64.neg (f64.neg (local.get $w)))))) + + (drop (i32.eqz (i32.eqz (local.get $x)))) ;; skip + (drop (i32.eqz (i32.eqz (i32.eqz (local.get $x))))) + (drop (i32.eqz (i32.eqz (i64.eqz (i64.const 1))))) + (drop (i32.eqz (i32.eqz (i32.ne (local.get $x) (i32.const 2))))) + + (drop (i32.extend8_s (i32.extend8_s (local.get $x)))) + (drop (i32.extend16_s (i32.extend16_s (local.get $x)))) + (drop (i32.eqz + (i32.eqz + (i32.and + (local.get $x) + (i32.const 1) + ) + ) + )) + + ;; binary + ;; ((signed)x % y) % y + (drop (i32.rem_s + (i32.rem_s + (local.get $x) + (local.get $y) + ) + (local.get $y) + )) + ;; ((unsigned)x % y) % y + (drop (i32.rem_u + (i32.rem_u + (local.get $x) + (local.get $y) + ) + (local.get $y) + )) + ;; 0 - (0 - y) + (drop (i32.sub + (i32.const 0) + (i32.sub + (i32.const 0) + (local.get $y) + ) + )) + ;; x - (x - y) + (drop (i32.sub + (local.get $x) + (i32.sub + (local.get $x) + (local.get $y) + ) + )) + ;; y - (x - y) - skip + (drop (i32.sub + (local.get $y) + (i32.sub + (local.get $x) + (local.get $y) + ) + )) + ;; x ^ (x ^ y) + (drop (i32.xor + (local.get $x) + (i32.xor + (local.get $x) + (local.get $y) + ) + )) + ;; x ^ (y ^ x) + (drop (i32.xor + (local.get $x) + (i32.xor + (local.get $y) + (local.get $x) + ) + )) + ;; (x ^ y) ^ x + (drop (i32.xor + (i32.xor + (local.get $x) + (local.get $y) + ) + (local.get $x) + )) + ;; (y ^ x) ^ x + (drop (i32.xor + (i32.xor + (local.get $y) + (local.get $x) + ) + (local.get $x) + )) + ;; x ^ (x ^ x) + (drop (i32.xor + (local.get $x) + (i32.xor + (local.get $x) + (local.get $x) + ) + )) + ;; x & (x & y) + (drop (i32.and + (local.get $x) + (i32.and + (local.get $x) + (local.get $y) + ) + )) + ;; x & (y & x) + (drop (i32.and + (local.get $x) + (i32.and + (local.get $y) + (local.get $x) + ) + )) + ;; (x & y) & x + (drop (i32.and + (i32.and + (local.get $x) + (local.get $y) + ) + (local.get $x) + )) + ;; (y & x) & x + (drop (i32.and + (i32.and + (local.get $y) + (local.get $x) + ) + (local.get $x) + )) + ;; x | (x | y) + (drop (i32.or + (local.get $x) + (i32.or + (local.get $x) + (local.get $y) + ) + )) + ;; x | (y | x) + (drop (i32.or + (local.get $x) + (i32.or + (local.get $y) + (local.get $x) + ) + )) + ;; (x | y) | x + (drop (i32.or + (i32.or + (local.get $x) + (local.get $y) + ) + (local.get $x) + )) + ;; (y | x) | x + (drop (i32.or + (i32.or + (local.get $y) + (local.get $x) + ) + (local.get $x) + )) + ;; (y | x) | z - skip + (drop (i32.or + (i32.or + (local.get $y) + (local.get $x) + ) + (local.get $z) + )) + ;; (z | x) | y - skip + (drop (i32.or + (i32.or + (local.get $z) + (local.get $x) + ) + (local.get $y) + )) + ;; (SE() | x) | x + (drop (i32.or + (i32.or + (call $ne0) ;; side effect + (local.get $x) + ) + (local.get $x) + )) + ;; (x | SE()) | SE() - skip + (drop (i32.or + (i32.or + (local.get $x) + (call $ne0) ;; side effect + ) + (call $ne0) ;; side effect + )) + ;; x | (SE() | x) + (drop (i32.or + (local.get $x) + (i32.or + (local.get $x) + (call $ne0) ;; side effect + ) + )) + ;; SE() | (x | SE()) - skip + (drop (i32.or + (call $ne0) ;; side effect + (i32.or + (call $ne0) ;; side effect + (local.get $x) + ) + )) + ;; (y % x) % y - skip + (drop (i32.rem_s + (i32.rem_s + (local.get $y) + (local.get $x) + ) + (local.get $y) + )) + ;; y % (x % y) - skip + (drop (i32.rem_u + (local.get $y) + (i32.rem_u + (local.get $x) + (local.get $y) + ) + )) + ) (func $optimize-bulk-memory-copy (param $dst i32) (param $src i32) (param $sz i32) (memory.copy ;; skip (local.get $dst) |