Skip to content

Commit a4baf21

Browse files
authored
wasm2js: handle unreachable select and global.set (#2029)
1 parent 5becae6 commit a4baf21

9 files changed

Lines changed: 195 additions & 11 deletions

src/passes/I64ToI32Lowering.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "support/name.h"
2929
#include "wasm-builder.h"
3030
#include "ir/flat.h"
31+
#include "ir/iteration.h"
3132
#include "ir/memory-utils.h"
3233
#include "ir/module-utils.h"
3334
#include "ir/names.h"
@@ -464,6 +465,7 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
464465
}
465466

466467
void visitSetGlobal(SetGlobal* curr) {
468+
if (handleUnreachable(curr)) return;
467469
if (!originallyI64Globals.count(curr->name)) return;
468470
TempVar highBits = fetchOutParam(curr->value);
469471
auto* setHigh = builder->makeSetGlobal(
@@ -1578,6 +1580,7 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
15781580
}
15791581

15801582
void visitSelect(Select* curr) {
1583+
if (handleUnreachable(curr)) return;
15811584
if (!hasOutParam(curr->ifTrue)) {
15821585
assert(!hasOutParam(curr->ifFalse));
15831586
return;
@@ -1669,6 +1672,24 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
16691672
highBitVars.erase(e);
16701673
return ret;
16711674
}
1675+
1676+
// If e.g. a select is unreachable, then one arm may have an out param
1677+
// but not the other. In this case dce should really have been run
1678+
// before; handle it in a simple way here.
1679+
bool handleUnreachable(Expression* curr) {
1680+
if (curr->type != unreachable) return false;
1681+
std::vector<Expression*> children;
1682+
for (auto* child : ChildIterator(curr)) {
1683+
if (isConcreteType(child->type)) {
1684+
child = builder->makeDrop(child);
1685+
}
1686+
children.push_back(child);
1687+
}
1688+
auto* block = builder->makeBlock(children);
1689+
assert(block->type == unreachable);
1690+
replaceCurrent(block);
1691+
return true;
1692+
}
16721693
};
16731694

16741695
Pass *createI64ToI32LoweringPass() {

test/passes/flatten_i64-to-i32-lowering.txt

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,69 @@
7878
)
7979
)
8080
)
81+
(func $unreachable-select-i64 (; 2 ;) (type $FUNCSIG$j) (result i32)
82+
(local $i64toi32_i32$0 i32)
83+
(unreachable)
84+
(block
85+
(drop
86+
(block (result i32)
87+
(local.set $i64toi32_i32$0
88+
(i32.const 0)
89+
)
90+
(i32.const 1)
91+
)
92+
)
93+
(unreachable)
94+
(drop
95+
(i32.const 2)
96+
)
97+
)
98+
(unreachable)
99+
)
100+
(func $unreachable-select-i64-b (; 3 ;) (type $FUNCSIG$j) (result i32)
101+
(local $i64toi32_i32$0 i32)
102+
(unreachable)
103+
(block
104+
(unreachable)
105+
(drop
106+
(block (result i32)
107+
(local.set $i64toi32_i32$0
108+
(i32.const 0)
109+
)
110+
(i32.const 3)
111+
)
112+
)
113+
(drop
114+
(i32.const 4)
115+
)
116+
)
117+
(unreachable)
118+
)
119+
(func $unreachable-select-i64-c (; 4 ;) (type $FUNCSIG$j) (result i32)
120+
(local $i64toi32_i32$0 i32)
121+
(local $i64toi32_i32$1 i32)
122+
(unreachable)
123+
(block
124+
(drop
125+
(block (result i32)
126+
(local.set $i64toi32_i32$0
127+
(i32.const 0)
128+
)
129+
(i32.const 5)
130+
)
131+
)
132+
(drop
133+
(block (result i32)
134+
(local.set $i64toi32_i32$1
135+
(i32.const 0)
136+
)
137+
(i32.const 6)
138+
)
139+
)
140+
(unreachable)
141+
)
142+
(unreachable)
143+
)
81144
)
82145
(module
83146
(type $0 (func (param i32 i32)))
@@ -88,6 +151,7 @@
88151
(global $g$hi (mut i32) (global.get $f$hi))
89152
(global $i64toi32_i32$HIGH_BITS (mut i32) (i32.const 0))
90153
(export "exp" (func $1))
154+
(export "unreach" (func $2))
91155
(func $call (; 0 ;) (type $0) (param $0 i32) (param $0$hi i32)
92156
(nop)
93157
)
@@ -136,4 +200,42 @@
136200
)
137201
(nop)
138202
)
203+
(func $2 (; 2 ;) (type $1)
204+
(local $0 i32)
205+
(local $0$hi i32)
206+
(local $1 i32)
207+
(local $1$hi i32)
208+
(local $i64toi32_i32$0 i32)
209+
(block $label$1
210+
(unreachable)
211+
(unreachable)
212+
)
213+
(block
214+
(local.set $1
215+
(block (result i32)
216+
(local.set $i64toi32_i32$0
217+
(local.get $0$hi)
218+
)
219+
(local.get $0)
220+
)
221+
)
222+
(local.set $1$hi
223+
(local.get $i64toi32_i32$0)
224+
)
225+
)
226+
(block
227+
(global.set $f
228+
(block (result i32)
229+
(local.set $i64toi32_i32$0
230+
(local.get $1$hi)
231+
)
232+
(local.get $1)
233+
)
234+
)
235+
(global.set $f$hi
236+
(local.get $i64toi32_i32$0)
237+
)
238+
)
239+
(nop)
240+
)
139241
)
Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,29 @@
11
(module
2-
(import "env" "func" (func $import (result i64)))
3-
(func $defined (result i64)
4-
(i64.add (i64.const 1) (i64.const 2))
2+
(import "env" "func" (func $import (result i64)))
3+
(func $defined (result i64)
4+
(i64.add (i64.const 1) (i64.const 2))
5+
)
6+
(func $unreachable-select-i64 (result i64)
7+
(select
8+
(i64.const 1)
9+
(unreachable)
10+
(i32.const 2)
11+
)
12+
)
13+
(func $unreachable-select-i64-b (result i64)
14+
(select
15+
(unreachable)
16+
(i64.const 3)
17+
(i32.const 4)
18+
)
19+
)
20+
(func $unreachable-select-i64-c (result i64)
21+
(select
22+
(i64.const 5)
23+
(i64.const 6)
24+
(unreachable)
525
)
26+
)
627
)
728
(module
829
(global $f (mut i64) (i64.const 0x12345678ABCDEFAF))
@@ -12,4 +33,11 @@
1233
(call $call (global.get $f))
1334
(global.set $f (i64.const 0x1122334455667788))
1435
)
36+
(func "unreach"
37+
(global.set $f
38+
(block $label$1 (result i64)
39+
(unreachable)
40+
)
41+
)
42+
)
1543
)

test/wasm2js/br.2asm.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ function asmFunc(global, env, buffer) {
262262
function $27($0, $1_1) {
263263
$0 = $0 | 0;
264264
$1_1 = $1_1 | 0;
265-
var $2_1 = 0, $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0;
265+
var $2_1 = 0, $3_1 = 0, $4_1 = 0;
266266
block : {
267267
$2_1 = 5;
268268
break block;
@@ -273,7 +273,7 @@ function asmFunc(global, env, buffer) {
273273
function $28($0, $1_1) {
274274
$0 = $0 | 0;
275275
$1_1 = $1_1 | 0;
276-
var $2_1 = 0, $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0;
276+
var $2_1 = 0, $3_1 = 0, $4_1 = 0;
277277
block : {
278278
$2_1 = $0;
279279
$3_1 = 6;

test/wasm2js/br_table.2asm.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49727,7 +49727,7 @@ function asmFunc(global, env, buffer) {
4972749727
function $34($0, $1_1) {
4972849728
$0 = $0 | 0;
4972949729
$1_1 = $1_1 | 0;
49730-
var $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0;
49730+
var $3_1 = 0, $4_1 = 0, $5_1 = 0;
4973149731
block : {
4973249732
$3_1 = 5;
4973349733
switch (0 | 0) {
@@ -49741,7 +49741,7 @@ function asmFunc(global, env, buffer) {
4974149741
function $35($0, $1_1) {
4974249742
$0 = $0 | 0;
4974349743
$1_1 = $1_1 | 0;
49744-
var $2_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0;
49744+
var $2_1 = 0, $4_1 = 0, $5_1 = 0;
4974549745
block : {
4974649746
$2_1 = $0;
4974749747
$4_1 = 6;

test/wasm2js/br_table_temp.2asm.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49725,7 +49725,7 @@ function asmFunc(global, env, buffer) {
4972549725
function $34($0, $1_1) {
4972649726
$0 = $0 | 0;
4972749727
$1_1 = $1_1 | 0;
49728-
var $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0;
49728+
var $3_1 = 0, $4_1 = 0, $5_1 = 0;
4972949729
block : {
4973049730
$3_1 = 5;
4973149731
switch (0 | 0) {
@@ -49739,7 +49739,7 @@ function asmFunc(global, env, buffer) {
4973949739
function $35($0, $1_1) {
4974049740
$0 = $0 | 0;
4974149741
$1_1 = $1_1 | 0;
49742-
var $2_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0;
49742+
var $2_1 = 0, $4_1 = 0, $5_1 = 0;
4974349743
block : {
4974449744
$2_1 = $0;
4974549745
$4_1 = 6;

test/wasm2js/i64-select.2asm.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,18 @@ function asmFunc(global, env, buffer) {
4242
return i64toi32_i32$3 | 0;
4343
}
4444

45+
function unreachable_select_i64() {
46+
return abort() | 0;
47+
}
48+
49+
function unreachable_select_i64_b() {
50+
return abort() | 0;
51+
}
52+
53+
function unreachable_select_i64_c() {
54+
return abort() | 0;
55+
}
56+
4557
var FUNCTION_TABLE = [];
4658
return {
4759

test/wasm2js/i64-select.wast

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,25 @@
2020
)
2121
)
2222
)
23+
(func $unreachable-select-i64 (result i64)
24+
(select
25+
(i64.const 1)
26+
(unreachable)
27+
(i32.const 268435456)
28+
)
29+
)
30+
(func $unreachable-select-i64-b (result i64)
31+
(select
32+
(unreachable)
33+
(i64.const 1)
34+
(i32.const 268435456)
35+
)
36+
)
37+
(func $unreachable-select-i64-c (result i64)
38+
(select
39+
(i64.const 1)
40+
(i64.const 1)
41+
(unreachable)
42+
)
43+
)
2344
)

test/wasm2js/select.2asm.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,13 @@ function asmFunc(global, env, buffer) {
6565

6666
function $4(cond) {
6767
cond = cond | 0;
68-
var $1_1 = 0, $2_1 = 0;
68+
var $1_1 = 0;
6969
return abort() | 0;
7070
}
7171

7272
function $5(cond) {
7373
cond = cond | 0;
74-
var $1_1 = 0, $2_1 = 0;
74+
var $1_1 = 0;
7575
return abort() | 0;
7676
}
7777

0 commit comments

Comments
 (0)