Skip to content

Commit 69408e6

Browse files
authored
fix re-reloop fuzz bug, we need to ensure a terminator in all relooper blocks (#1214)
1 parent d11d874 commit 69408e6

File tree

5 files changed

+118
-2
lines changed

5 files changed

+118
-2
lines changed

src/cfg/Relooper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ struct InsertOrderedSet
136136
}
137137

138138
size_t size() const { return Map.size(); }
139+
bool empty() const { return Map.empty(); }
139140

140141
void clear() {
141142
Map.clear();
@@ -194,6 +195,7 @@ struct InsertOrderedMap
194195
}
195196

196197
size_t size() const { return Map.size(); }
198+
bool empty() const { return Map.empty(); }
197199
size_t count(const Key& k) const { return Map.count(k); }
198200

199201
InsertOrderedMap() {}

src/passes/ReReloop.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
#include "cfg/Relooper.h"
3131
#include "ast_utils.h"
3232

33+
#ifdef RERELOOP_DEBUG
34+
#include <wasm-printing.h>
35+
#endif
36+
3337
namespace wasm {
3438

3539
struct ReReloop final : public Pass {
@@ -307,6 +311,33 @@ struct ReReloop final : public Pass {
307311
}
308312
// finish the current block
309313
finishBlock();
314+
// blocks that do not have any exits are dead ends in the relooper. we need
315+
// to make sure that are in fact dead ends, and do not flow control anywhere.
316+
// add a return as needed
317+
for (auto* cfgBlock : relooper.Blocks) {
318+
auto* block = cfgBlock->Code->cast<Block>();
319+
if (cfgBlock->BranchesOut.empty() && block->type != unreachable) {
320+
block->list.push_back(
321+
function->result == none ? (Expression*)builder->makeReturn()
322+
: (Expression*)builder->makeUnreachable()
323+
);
324+
block->finalize();
325+
}
326+
}
327+
#ifdef RERELOOP_DEBUG
328+
std::cout << "rerelooping " << function->name << '\n';
329+
for (auto* block : relooper.Blocks) {
330+
std::cout << block << " block:\n" << block->Code << '\n';
331+
for (auto& pair : block->BranchesOut) {
332+
auto* target = pair.first;
333+
auto* branch = pair.second;
334+
std::cout << "branch to " << target << "\n";
335+
if (branch->Condition) {
336+
std::cout << " with condition\n" << branch->Condition << '\n';
337+
}
338+
}
339+
}
340+
#endif
310341
// run the relooper to recreate control flow
311342
relooper.Calculate(entry);
312343
// render

test/passes/rereloop.txt

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
(local $0 i32)
99
(block
1010
(nop)
11+
(return)
1112
)
1213
)
1314
(func $trivial2 (type $0)
1415
(local $0 i32)
1516
(block
1617
(call $trivial)
1718
(call $trivial)
19+
(return)
1820
)
1921
)
2022
(func $return-void (type $0)
@@ -161,6 +163,7 @@
161163
)
162164
(block
163165
(block
166+
(return)
164167
)
165168
)
166169
)
@@ -182,6 +185,7 @@
182185
)
183186
(block
184187
(block
188+
(return)
185189
)
186190
)
187191
)
@@ -206,6 +210,7 @@
206210
)
207211
(block
208212
(block
213+
(return)
209214
)
210215
)
211216
)
@@ -254,6 +259,7 @@
254259
)
255260
(block
256261
(block
262+
(return)
257263
)
258264
)
259265
)
@@ -509,6 +515,7 @@
509515
(call $before-and-after
510516
(i32.const 25)
511517
)
518+
(return)
512519
)
513520
)
514521
)
@@ -598,6 +605,7 @@
598605
)
599606
(block
600607
(block
608+
(return)
601609
)
602610
)
603611
)
@@ -634,6 +642,7 @@
634642
)
635643
(block
636644
(block
645+
(return)
637646
)
638647
)
639648
)
@@ -697,6 +706,7 @@
697706
(call $if-br-wat
698707
(i32.const 3)
699708
)
709+
(return)
700710
)
701711
)
702712
)
@@ -744,3 +754,52 @@
744754
)
745755
)
746756
)
757+
(module
758+
(type $0 (func))
759+
(type $1 (func (result i32)))
760+
(global $global$0 (mut i32) (i32.const 1))
761+
(memory $0 0)
762+
(export "one" (func $0))
763+
(export "two" (func $1))
764+
(func $0 (type $0)
765+
(local $0 i32)
766+
(block $block$4$break
767+
(block
768+
)
769+
(if
770+
(i32.const 1)
771+
(block
772+
(block
773+
(return)
774+
)
775+
)
776+
(br $block$4$break)
777+
)
778+
)
779+
(block
780+
(block $block$3$break
781+
(block
782+
(set_global $global$0
783+
(i32.const 0)
784+
)
785+
)
786+
(block
787+
(br $block$3$break)
788+
)
789+
)
790+
(block
791+
(block
792+
(unreachable)
793+
)
794+
)
795+
)
796+
)
797+
(func $1 (type $1) (result i32)
798+
(local $0 i32)
799+
(block
800+
(return
801+
(get_global $global$0)
802+
)
803+
)
804+
)
805+
)

test/passes/rereloop.wast

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,4 +197,25 @@
197197
)
198198
)
199199
)
200+
(module
201+
(global $global$0 (mut i32) (i32.const 1))
202+
(export "one" (func $0))
203+
(export "two" (func $1))
204+
(func $0
205+
(block $outer
206+
(block
207+
(br_if $outer ;; taken - do not modify the global, stay it at 1
208+
(i32.const 1)
209+
)
210+
(set_global $global$0 ;; never get here!
211+
(i32.const 0)
212+
)
213+
)
214+
(unreachable)
215+
)
216+
)
217+
(func $1 (result i32)
218+
(return (get_global $global$0))
219+
)
220+
)
200221

test/passes/rereloop_dce_remove-unused-brs_remove-unused-names_coalesce-locals_simplify-locals_reorder-locals_remove-unused-brs_merge-blocks_vacuum.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,11 @@
6868
(i32.eqz
6969
(get_local $0)
7070
)
71-
(call $unreachable
72-
(i32.const 5)
71+
(block
72+
(call $unreachable
73+
(i32.const 5)
74+
)
75+
(return)
7376
)
7477
)
7578
(if

0 commit comments

Comments
 (0)