Skip to content

Commit 29e7e44

Browse files
authored
wasm2js: ignore implicit traps (#2079)
We don't actually try to emit traps for loads, stores, invalid float to ints, etc., so when optimizing we may as well do so under the assumption those traps do not exist. This lets us emit nice code for a select whose operands are loads, for example - otherwise, the values seem to have side effects.
1 parent b394fcc commit 29e7e44

9 files changed

Lines changed: 41 additions & 60 deletions

src/tools/wasm2js.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ void AssertionEmitter::emit() {
603603
}
604604
605605
function i64Equal(actual_lo, actual_hi, expected_lo, expected_hi) {
606-
return actual_lo == (expected_lo | 0) && actual_hi == (expected_hi | 0);
606+
return (actual_lo | 0) == (expected_lo | 0) && (actual_hi | 0) == (expected_hi | 0);
607607
}
608608
)";
609609

src/wasm2js.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,15 @@ class Wasm2JSBuilder {
124124
bool emscripten = false;
125125
};
126126

127-
Wasm2JSBuilder(Flags f, PassOptions options) : flags(f), options(options) {}
127+
Wasm2JSBuilder(Flags f, PassOptions options_) : flags(f), options(options_) {
128+
// We don't try to model wasm's trapping precisely - if we did, each load
129+
// and store would need to do a check. Given that, we can just ignore
130+
// implicit traps like those when optimizing. (When not optimizing, it's
131+
// nice to see codegen that matches wasm more precisely.)
132+
if (options.optimizeLevel > 0) {
133+
options.ignoreImplicitTraps = true;
134+
}
135+
}
128136

129137
Ref processWasm(Module* wasm, Name funcName = ASM_FUNC);
130138
Ref processFunction(Module* wasm, Function* func, bool standalone = false);

test/wasm2js.asserts.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
}
2828

2929
function i64Equal(actual_lo, actual_hi, expected_lo, expected_hi) {
30-
return actual_lo == (expected_lo | 0) && actual_hi == (expected_hi | 0);
30+
return (actual_lo | 0) == (expected_lo | 0) && (actual_hi | 0) == (expected_hi | 0);
3131
}
3232

3333
function asmFunc0(global, env, buffer) {

test/wasm2js.traps.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
}
2828

2929
function i64Equal(actual_lo, actual_hi, expected_lo, expected_hi) {
30-
return actual_lo == (expected_lo | 0) && actual_hi == (expected_hi | 0);
30+
return (actual_lo | 0) == (expected_lo | 0) && (actual_hi | 0) == (expected_hi | 0);
3131
}
3232

3333
function asmFunc0(global, env, buffer) {

test/wasm2js/conversions-modified.2asm.js.opt

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -76,36 +76,14 @@ function asmFunc(global, env, buffer) {
7676

7777
function $7($0) {
7878
$0 = Math_fround($0);
79-
var $1 = 0, $2 = 0;
80-
$2 = ~~$0 >>> 0;
81-
if (Math_fround(Math_abs($0)) >= Math_fround(1.0)) {
82-
if ($0 > Math_fround(0.0)) {
83-
$1 = ~~Math_fround(Math_min(Math_fround(Math_floor(Math_fround($0 / Math_fround(4294967296.0)))), Math_fround(4294967296.0))) >>> 0
84-
} else {
85-
$1 = ~~Math_fround(Math_ceil(Math_fround(Math_fround($0 - Math_fround(~~$0 >>> 0 >>> 0)) / Math_fround(4294967296.0)))) >>> 0
86-
}
87-
} else {
88-
$1 = 0
89-
}
90-
i64toi32_i32$HIGH_BITS = $1;
91-
return $2 | 0;
79+
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;
80+
return ~~$0 >>> 0;
9281
}
9382

9483
function $9($0) {
9584
$0 = +$0;
96-
var $1 = 0, $2 = 0;
97-
$2 = ~~$0 >>> 0;
98-
if (Math_abs($0) >= 1.0) {
99-
if ($0 > 0.0) {
100-
$1 = ~~Math_min(Math_floor($0 / 4294967296.0), 4294967295.0) >>> 0
101-
} else {
102-
$1 = ~~Math_ceil(($0 - +(~~$0 >>> 0 >>> 0)) / 4294967296.0) >>> 0
103-
}
104-
} else {
105-
$1 = 0
106-
}
107-
i64toi32_i32$HIGH_BITS = $1;
108-
return $2 | 0;
85+
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;
86+
return ~~$0 >>> 0;
10987
}
11088

11189
function $11($0) {

test/wasm2js/emscripten.2asm.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ function asmFunc(global, env, buffer) {
8080
return x - -5 | 0 | 0;
8181
}
8282

83+
function select(x) {
84+
x = x | 0;
85+
var wasm2js_i32$0 = 0, wasm2js_i32$1 = 0, wasm2js_i32$2 = 0;
86+
return (wasm2js_i32$0 = x, wasm2js_i32$1 = HEAP32[16 >> 2] | 0, wasm2js_i32$2 = x, wasm2js_i32$2 ? wasm2js_i32$0 : wasm2js_i32$1) | 0;
87+
}
88+
8389
// EMSCRIPTEN_END_FUNCS;
8490
FUNCTION_TABLE[1] = foo;
8591
FUNCTION_TABLE[2] = bar;
@@ -89,7 +95,8 @@ function asmFunc(global, env, buffer) {
8995
"other": other,
9096
"__growWasmMemory": __growWasmMemory,
9197
"exported": exported,
92-
"sub_zero": sub_zero
98+
"sub_zero": sub_zero,
99+
"select": select
93100
};
94101
}
95102

test/wasm2js/emscripten.2asm.js.opt

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,6 @@ function asmFunc(global, env, buffer) {
4141
}
4242

4343
function bar() {
44-
HEAPU8[128 | 0];
45-
HEAP8[128 | 0];
46-
HEAPU16[128 >> 1];
47-
HEAP16[128 >> 1];
4844
HEAP32[16 >> 2] = 3;
4945
HEAPF32[16 >> 2] = 7;
5046
HEAPF64[16 >> 3] = 11;
@@ -66,6 +62,11 @@ function asmFunc(global, env, buffer) {
6662
return $0 + 5 | 0;
6763
}
6864

65+
function select($0) {
66+
$0 = $0 | 0;
67+
return ($0 ? $0 : HEAP32[16 >> 2]) | 0;
68+
}
69+
6970
// EMSCRIPTEN_END_FUNCS;
7071
FUNCTION_TABLE[1] = foo;
7172
FUNCTION_TABLE[2] = bar;
@@ -75,7 +76,8 @@ function asmFunc(global, env, buffer) {
7576
"other": other,
7677
"__growWasmMemory": __growWasmMemory,
7778
"exported": internal,
78-
"sub_zero": sub_zero
79+
"sub_zero": sub_zero,
80+
"select": select
7981
};
8082
}
8183

test/wasm2js/emscripten.wast

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
(export "__growWasmMemory" (func $__growWasmMemory))
1414
(export "exported" (func $exported))
1515
(export "sub-zero" (func $sub-zero))
16+
(export "select" (func $select))
1617
(func $main
1718
(drop (call $syscall$6 (i32.const 1) (i32.const 2)))
1819
(drop (call $syscall$54 (i32.const 3) (i32.const 4)))
@@ -90,5 +91,12 @@
9091
(func $sub-zero (param $x i32) (result i32)
9192
(i32.sub (local.get $x) (i32.const -5))
9293
)
94+
(func $select (param $x i32) (result i32)
95+
(select
96+
(local.get $x)
97+
(i32.load (i32.const 16)) ;; we can ignore this implicit trap, no side effects
98+
(local.get $x)
99+
)
100+
)
93101
)
94102

test/wasm2js/float-ops.2asm.js.opt

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -247,34 +247,12 @@ function asmFunc(global, env, buffer) {
247247

248248
function $47($0) {
249249
$0 = Math_fround($0);
250-
var $1_1 = 0, $2_1 = 0;
251-
$2_1 = ~~$0 >>> 0;
252-
if (Math_fround(Math_abs($0)) >= Math_fround(1.0)) {
253-
if ($0 > Math_fround(0.0)) {
254-
$1_1 = ~~Math_fround(Math_min(Math_fround(Math_floor(Math_fround($0 / Math_fround(4294967296.0)))), Math_fround(4294967296.0))) >>> 0
255-
} else {
256-
$1_1 = ~~Math_fround(Math_ceil(Math_fround(Math_fround($0 - Math_fround(~~$0 >>> 0 >>> 0)) / Math_fround(4294967296.0)))) >>> 0
257-
}
258-
} else {
259-
$1_1 = 0
260-
}
261-
return !($2_1 | $1_1) | 0;
250+
return !(~~$0 >>> 0 | (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)) | 0;
262251
}
263252

264253
function $48($0) {
265254
$0 = +$0;
266-
var $1_1 = 0, $2_1 = 0;
267-
$2_1 = ~~$0 >>> 0;
268-
if (Math_abs($0) >= 1.0) {
269-
if ($0 > 0.0) {
270-
$1_1 = ~~Math_min(Math_floor($0 / 4294967296.0), 4294967295.0) >>> 0
271-
} else {
272-
$1_1 = ~~Math_ceil(($0 - +(~~$0 >>> 0 >>> 0)) / 4294967296.0) >>> 0
273-
}
274-
} else {
275-
$1_1 = 0
276-
}
277-
return !($2_1 | $1_1) | 0;
255+
return !(~~$0 >>> 0 | (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)) | 0;
278256
}
279257

280258
function legalstub$43($0, $1_1) {

0 commit comments

Comments
 (0)