diff options
author | Max Graey <maxgraey@gmail.com> | 2020-10-05 19:34:17 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-05 09:34:17 -0700 |
commit | 654cfca4fabda64dd91d2df9b07422b8bffc9357 (patch) | |
tree | 545adba4f335f770fc04570fe75c21a67f6a4ce4 /test/passes/optimize-instructions_all-features.wast | |
parent | 3da66481b94cba2d3f5717316755fe3a60fcbe52 (diff) | |
download | binaryen-654cfca4fabda64dd91d2df9b07422b8bffc9357.tar.gz binaryen-654cfca4fabda64dd91d2df9b07422b8bffc9357.tar.bz2 binaryen-654cfca4fabda64dd91d2df9b07422b8bffc9357.zip |
Generalize transforms for #3153 (#3193)
Implement a more general (additional) version of #3153 which also handles negative constant divisors:
`(int32)x % -4 == 0` --> `(x & 3) == 0`
`x % -C_pot == 0` --> `(x & (abs(C_pot) - 1)) == 0`
and special two-complement values as well:
`(int32)x % 0x80000000 == 0` --> `(x & 0x7fffffff) == 0`
`(int64)x % 0x8000000000000000 == 0` --> `(x & 0x7fffffffffffffff) == 0`
as separete rules:
`(int32)x % 0x80000000` --> `x & 0x7fffffff`
`(int64)x % 0x8000000000000000` --> `x & 0x7fffffffffffffff`
The [previous pr](https://github.com/WebAssembly/binaryen/pull/3153) didn't use these possibilities.
Diffstat (limited to 'test/passes/optimize-instructions_all-features.wast')
-rw-r--r-- | test/passes/optimize-instructions_all-features.wast | 81 |
1 files changed, 76 insertions, 5 deletions
diff --git a/test/passes/optimize-instructions_all-features.wast b/test/passes/optimize-instructions_all-features.wast index 71646de93..05e0e37c3 100644 --- a/test/passes/optimize-instructions_all-features.wast +++ b/test/passes/optimize-instructions_all-features.wast @@ -3093,7 +3093,7 @@ ) (unreachable) ) - (func $srem-by-1 (param $x i32) (param $y i64) + (func $srem-by-const (param $x i32) (param $y i64) ;; (signed)x % 1 (drop (i32.rem_s (local.get $x) @@ -3103,6 +3103,16 @@ (local.get $y) (i64.const 1) )) + ;; (signed)x % 0x80000000 -> x & 0x7FFFFFFF + (drop (i32.rem_s + (local.get $x) + (i32.const 0x80000000) + )) + ;; (signed)x % 0x8000000000000000 -> x & 0x7FFFFFFFFFFFFFFF + (drop (i64.rem_s + (local.get $y) + (i64.const 0x8000000000000000) + )) ) (func $srem-by-pot-eq-ne-zero (param $x i32) (param $y i64) ;; eqz((signed)x % 4) @@ -3118,6 +3128,19 @@ (i64.const 4) ) )) + ;; eqz((signed)x % -4) + (drop (i32.eqz + (i32.rem_s + (local.get $x) + (i32.const -4) + ) + )) + (drop (i64.eqz + (i64.rem_s + (local.get $y) + (i64.const -4) + ) + )) ;; (signed)x % 4 == 0 (drop (i32.eq (i32.rem_s @@ -3133,7 +3156,22 @@ ) (i64.const 0) )) - ;; ;; (signed)x % 2 != 0 + ;; (signed)x % -4 == 0 + (drop (i32.eq + (i32.rem_s + (local.get $x) + (i32.const -4) + ) + (i32.const 0) + )) + (drop (i64.eq + (i64.rem_s + (local.get $y) + (i64.const -4) + ) + (i64.const 0) + )) + ;; (signed)x % 2 != 0 (drop (i32.ne (i32.rem_s (local.get $x) @@ -3148,18 +3186,51 @@ ) (i64.const 0) )) - ;; ;; + ;; (signed)x % -1 == 0 -> 0 == 0 (drop (i32.eq (i32.rem_s (local.get $x) - (i32.const 3) ;; skip + (i32.const -1) + ) + (i32.const 0) + )) + ;; (signed)x % 0x80000000 == 0 + (drop (i32.eq + (i32.rem_s + (local.get $x) + (i32.const 0x80000000) + ) + (i32.const 0) + )) + ;; (signed)x % 0x80000000 != 0 + (drop (i32.ne + (i32.rem_s + (local.get $x) + (i32.const 0x80000000) ) (i32.const 0) )) + ;; (signed)x % 0x8000000000000000 == 0 + (drop (i64.eq + (i64.rem_s + (local.get $y) + (i64.const 0x8000000000000000) + ) + (i64.const 0) + )) + ;; (signed)x % 0x8000000000000000 != 0 + (drop (i64.ne + (i64.rem_s + (local.get $y) + (i64.const 0x8000000000000000) + ) + (i64.const 0) + )) + ;; (drop (i32.eq (i32.rem_s (local.get $x) - (i32.const -4) ;; skip + (i32.const 3) ;; skip ) (i32.const 0) )) |