diff options
author | Alon Zakai <azakai@google.com> | 2020-01-10 06:37:00 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-10 06:37:00 -0800 |
commit | 263d2d5025c98092f781c8b8d9eb7ac6df6aadab (patch) | |
tree | 4994c331c247a7c78d241f655b10a93e59027593 | |
parent | 98747d97f089354091d115fb300006f3cc506a0c (diff) | |
download | binaryen-263d2d5025c98092f781c8b8d9eb7ac6df6aadab.tar.gz binaryen-263d2d5025c98092f781c8b8d9eb7ac6df6aadab.tar.bz2 binaryen-263d2d5025c98092f781c8b8d9eb7ac6df6aadab.zip |
wasm2js: Do not convert x >>> 0 | 0 to x >>> 0 (#2581)
isBinary was used where we should only accept
a signed binary, as removing the | 0 from an unsigned
value may be incorrect.
This does regress a few small things (as can be seen
in the diff). If it's important we can add more sophisticated
optimizations here, perhaps like an assumption that the
signedness of a local never matters.
Fixes emscripten-core/emscripten#10173
-rw-r--r-- | src/tools/wasm2js.cpp | 12 | ||||
-rw-r--r-- | test/wasm2js/conversions-modified.2asm.js.opt | 8 | ||||
-rw-r--r-- | test/wasm2js/float-ops.2asm.js.opt | 4 | ||||
-rw-r--r-- | test/wasm2js/i64-rotate.2asm.js.opt | 16 | ||||
-rw-r--r-- | test/wasm2js/stack-modified.2asm.js.opt | 8 |
5 files changed, 28 insertions, 20 deletions
diff --git a/src/tools/wasm2js.cpp b/src/tools/wasm2js.cpp index 06ab81263..e7b62c16a 100644 --- a/src/tools/wasm2js.cpp +++ b/src/tools/wasm2js.cpp @@ -179,6 +179,14 @@ static void optimizeJS(Ref ast) { return false; }; + auto isSignedBitwise = [](Ref node) { + if (node->isArray() && !node->empty() && node[0] == BINARY) { + auto op = node[1]; + return op == OR || op == AND || op == XOR || op == RSHIFT || op == LSHIFT; + } + return false; + }; + auto isUnary = [](Ref node, IString op) { return node->isArray() && !node->empty() && node[0] == UNARY_PREFIX && node[1] == op; @@ -275,9 +283,9 @@ static void optimizeJS(Ref ast) { // x | 0 going into a bitwise op => skip the | 0 node[2] = removeOrZero(node[2]); node[3] = removeOrZero(node[3]); - // x | 0 | 0 => x | 0 + // (x | 0 or similar) | 0 => (x | 0 or similar) if (isOrZero(node)) { - if (isBitwise(node[2])) { + if (isSignedBitwise(node[2])) { replaceInPlace(node, node[2]); } } diff --git a/test/wasm2js/conversions-modified.2asm.js.opt b/test/wasm2js/conversions-modified.2asm.js.opt index fceed0c6c..b30a95a8e 100644 --- a/test/wasm2js/conversions-modified.2asm.js.opt +++ b/test/wasm2js/conversions-modified.2asm.js.opt @@ -60,7 +60,7 @@ function asmFunc(global, env, buffer) { function $4($0) { $0 = Math_fround($0); - return ~~$0 >>> 0; + return ~~$0 >>> 0 | 0; } function $5($0) { @@ -70,19 +70,19 @@ function asmFunc(global, env, buffer) { function $6($0) { $0 = +$0; - return ~~$0 >>> 0; + return ~~$0 >>> 0 | 0; } function $7($0) { $0 = Math_fround($0); i64toi32_i32$HIGH_BITS = Math_fround(Math_abs($0)) >= Math_fround(1.0) ? ($0 > Math_fround(0.0) ? ~~Math_fround(Math_min(Math_fround(Math_floor(Math_fround($0 / Math_fround(4294967296.0)))), Math_fround(4294967296.0))) >>> 0 : ~~Math_fround(Math_ceil(Math_fround(Math_fround($0 - Math_fround(~~$0 >>> 0 >>> 0)) / Math_fround(4294967296.0)))) >>> 0) : 0; - return ~~$0 >>> 0; + return ~~$0 >>> 0 | 0; } function $9($0) { $0 = +$0; i64toi32_i32$HIGH_BITS = Math_abs($0) >= 1.0 ? ($0 > 0.0 ? ~~Math_min(Math_floor($0 / 4294967296.0), 4294967295.0) >>> 0 : ~~Math_ceil(($0 - +(~~$0 >>> 0 >>> 0)) / 4294967296.0) >>> 0) : 0; - return ~~$0 >>> 0; + return ~~$0 >>> 0 | 0; } function $11($0) { diff --git a/test/wasm2js/float-ops.2asm.js.opt b/test/wasm2js/float-ops.2asm.js.opt index 7f19a7a31..7e3413736 100644 --- a/test/wasm2js/float-ops.2asm.js.opt +++ b/test/wasm2js/float-ops.2asm.js.opt @@ -236,12 +236,12 @@ function asmFunc(global, env, buffer) { function $41($0) { $0 = Math_fround($0); - return ~~$0 >>> 0; + return ~~$0 >>> 0 | 0; } function $42($0) { $0 = +$0; - return ~~$0 >>> 0; + return ~~$0 >>> 0 | 0; } function $47($0) { diff --git a/test/wasm2js/i64-rotate.2asm.js.opt b/test/wasm2js/i64-rotate.2asm.js.opt index 69fefab76..a3e2091fc 100644 --- a/test/wasm2js/i64-rotate.2asm.js.opt +++ b/test/wasm2js/i64-rotate.2asm.js.opt @@ -35,9 +35,9 @@ function asmFunc(global, env, buffer) { $5 = $6; $3 = $5 & 31; if (32 <= $5 >>> 0) { - $3 = -1 >>> $3 + $3 = -1 >>> $3 | 0 } else { - $4 = -1 >>> $3; + $4 = -1 >>> $3 | 0; $3 = (1 << $3) - 1 << 32 - $3 | -1 >>> $3; } $5 = $3 & $0; @@ -66,9 +66,9 @@ function asmFunc(global, env, buffer) { $1 = $4 & 31; if (32 <= $4 >>> 0) { $2 = 0; - $0 = $3 >>> $1; + $0 = $3 >>> $1 | 0; } else { - $2 = $3 >>> $1; + $2 = $3 >>> $1 | 0; $0 = ((1 << $1) - 1 & $3) << 32 - $1 | $0 >>> $1; } $0 = $0 | $6; @@ -92,9 +92,9 @@ function asmFunc(global, env, buffer) { $5 = $6 & 31; if (32 <= $6 >>> 0) { $4 = 0; - $6 = $3 >>> $5; + $6 = $3 >>> $5 | 0; } else { - $4 = $3 >>> $5; + $4 = $3 >>> $5 | 0; $6 = ((1 << $5) - 1 & $3) << 32 - $5 | $7 >>> $5; } $7 = $4; @@ -102,9 +102,9 @@ function asmFunc(global, env, buffer) { $5 = $3 & 31; if (32 <= $3 >>> 0) { $4 = 0; - $2 = -1 >>> $5; + $2 = -1 >>> $5 | 0; } else { - $4 = -1 >>> $5; + $4 = -1 >>> $5 | 0; $2 = (1 << $5) - 1 << 32 - $5 | -1 >>> $5; } $0 = $2 & $0; diff --git a/test/wasm2js/stack-modified.2asm.js.opt b/test/wasm2js/stack-modified.2asm.js.opt index d321f6f67..2cd863f72 100644 --- a/test/wasm2js/stack-modified.2asm.js.opt +++ b/test/wasm2js/stack-modified.2asm.js.opt @@ -52,15 +52,15 @@ function asmFunc(global, env, buffer) { function _ZN17compiler_builtins3int3mul3Mul3mul17h070e9a1c69faec5bE($0_1, $1, $2, $3) { var $4 = 0, $5 = 0, $6 = 0, $7 = 0, $8 = 0, $9 = 0; - $4 = $2 >>> 16; - $5 = $0_1 >>> 16; + $4 = $2 >>> 16 | 0; + $5 = $0_1 >>> 16 | 0; $9 = Math_imul($4, $5); $6 = $2 & 65535; $7 = $0_1 & 65535; $8 = Math_imul($6, $7); - $5 = ($8 >>> 16) + Math_imul($5, $6) | 0; + $5 = ($8 >>> 16 | 0) + Math_imul($5, $6) | 0; $4 = ($5 & 65535) + Math_imul($4, $7) | 0; - $0_1 = (((Math_imul($1, $2) + $9 | 0) + Math_imul($0_1, $3) | 0) + ($5 >>> 16) | 0) + ($4 >>> 16) | 0; + $0_1 = (Math_imul($1, $2) + $9 | 0) + Math_imul($0_1, $3) + ($5 >>> 16) + ($4 >>> 16) | 0; $1 = $8 & 65535 | $4 << 16; i64toi32_i32$HIGH_BITS = $0_1; return $1; |