Skip to content

Commit d8c46cf

Browse files
authored
Fix an infinite loop in avoid-reinterprets in unreachable code with loops of gets (#2118)
In unreachable code, a get may have a single set that assigns to it, and that set may be assigned to by that very get.
1 parent 9c63728 commit d8c46cf

File tree

5 files changed

+104
-1
lines changed

5 files changed

+104
-1
lines changed

src/passes/AvoidReinterprets.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
namespace wasm {
2929

3030
static Load* getSingleLoad(LocalGraph* localGraph, GetLocal* get) {
31+
std::set<GetLocal*> seen;
32+
seen.insert(get);
3133
while (1) {
3234
auto& sets = localGraph->getSetses[get];
3335
if (sets.size() != 1) {
@@ -39,7 +41,12 @@ static Load* getSingleLoad(LocalGraph* localGraph, GetLocal* get) {
3941
}
4042
auto* value = Properties::getFallthrough(set->value);
4143
if (auto* parentGet = value->dynCast<GetLocal>()) {
44+
if (seen.count(parentGet)) {
45+
// We are in a cycle of gets, in unreachable code.
46+
return nullptr;
47+
}
4248
get = parentGet;
49+
seen.insert(get);
4350
continue;
4451
}
4552
if (auto* load = value->dynCast<Load>()) {

test/emscripten

Submodule emscripten deleted from 1d979a7
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
function asmFunc(global, env, buffer) {
3+
"almost asm";
4+
var HEAP8 = new global.Int8Array(buffer);
5+
var HEAP16 = new global.Int16Array(buffer);
6+
var HEAP32 = new global.Int32Array(buffer);
7+
var HEAPU8 = new global.Uint8Array(buffer);
8+
var HEAPU16 = new global.Uint16Array(buffer);
9+
var HEAPU32 = new global.Uint32Array(buffer);
10+
var HEAPF32 = new global.Float32Array(buffer);
11+
var HEAPF64 = new global.Float64Array(buffer);
12+
var Math_imul = global.Math.imul;
13+
var Math_fround = global.Math.fround;
14+
var Math_abs = global.Math.abs;
15+
var Math_clz32 = global.Math.clz32;
16+
var Math_min = global.Math.min;
17+
var Math_max = global.Math.max;
18+
var Math_floor = global.Math.floor;
19+
var Math_ceil = global.Math.ceil;
20+
var Math_sqrt = global.Math.sqrt;
21+
var abort = env.abort;
22+
var nan = global.NaN;
23+
var infinity = global.Infinity;
24+
var FUNCTION_TABLE = [];
25+
return {
26+
27+
};
28+
}
29+
30+
var memasmFunc = new ArrayBuffer(65536);
31+
var retasmFunc = asmFunc({Math,Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,NaN,Infinity}, {abort:function() { throw new Error('abort'); }},memasmFunc);
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
function asmFunc(global, env, buffer) {
3+
"almost asm";
4+
var HEAP8 = new global.Int8Array(buffer);
5+
var HEAP16 = new global.Int16Array(buffer);
6+
var HEAP32 = new global.Int32Array(buffer);
7+
var HEAPU8 = new global.Uint8Array(buffer);
8+
var HEAPU16 = new global.Uint16Array(buffer);
9+
var HEAPU32 = new global.Uint32Array(buffer);
10+
var HEAPF32 = new global.Float32Array(buffer);
11+
var HEAPF64 = new global.Float64Array(buffer);
12+
var Math_imul = global.Math.imul;
13+
var Math_fround = global.Math.fround;
14+
var Math_abs = global.Math.abs;
15+
var Math_clz32 = global.Math.clz32;
16+
var Math_min = global.Math.min;
17+
var Math_max = global.Math.max;
18+
var Math_floor = global.Math.floor;
19+
var Math_ceil = global.Math.ceil;
20+
var Math_sqrt = global.Math.sqrt;
21+
var abort = env.abort;
22+
var nan = global.NaN;
23+
var infinity = global.Infinity;
24+
var FUNCTION_TABLE = [];
25+
return {
26+
27+
};
28+
}
29+
30+
var memasmFunc = new ArrayBuffer(65536);
31+
var retasmFunc = asmFunc({Math,Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,NaN,Infinity}, {abort:function() { throw new Error('abort'); }},memasmFunc);
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
(module
2+
(type $0 (func (param i64 f64) (result i64)))
3+
(memory $0 1 1)
4+
(func $0 (; 0 ;) (type $0) (param $0 i64) (param $1 f64) (result i64)
5+
(local $2 f32)
6+
(if (result i64)
7+
(loop $label$1 (result i32)
8+
(br_if $label$1
9+
(i32.const 1)
10+
)
11+
(i32.const 0)
12+
)
13+
(loop $label$3
14+
(block $label$4
15+
(f32.store offset=22 align=2
16+
(i32.const 0)
17+
(local.get $2)
18+
)
19+
(drop
20+
(local.tee $2
21+
(if (result f32)
22+
(i32.const -19666)
23+
(local.get $2)
24+
(unreachable)
25+
)
26+
)
27+
)
28+
)
29+
(br $label$3)
30+
)
31+
(i64.const 1)
32+
)
33+
)
34+
)
35+

0 commit comments

Comments
 (0)