Skip to content

Commit b9ce586

Browse files
committed
don't move code around a drop-block when the block contains unreachables, which can cause type changes in the outside. dce should be run on that anyhow
1 parent ffd9a72 commit b9ce586

4 files changed

Lines changed: 64 additions & 31 deletions

File tree

src/passes/MergeBlocks.cpp

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -168,32 +168,42 @@ static void optimizeBlock(Block* curr, Module* module, PassOptions& passOptions)
168168
if (drop) {
169169
child = drop->value->dynCast<Block>();
170170
if (child) {
171-
if (child->name.is()) {
172-
Expression* expression = child;
173-
// check if it's ok to remove the value from all breaks to us
174-
ProblemFinder finder(passOptions);
175-
finder.origin = child->name;
176-
finder.walk(expression);
177-
if (finder.found()) {
171+
// if we move around unreachable code, type changes could occur. avoid that, as
172+
// anyhow it means we should have run dce before getting here
173+
for (auto* test : child->list) {
174+
if (test->type == unreachable) {
178175
child = nullptr;
179-
} else {
180-
// fix up breaks
181-
BreakValueDropper fixer(passOptions);
182-
fixer.origin = child->name;
183-
fixer.setModule(module);
184-
fixer.walk(expression);
176+
break;
185177
}
186178
}
187179
if (child) {
188-
// we can do it!
189-
// reuse the drop
190-
drop->value = child->list.back();
191-
drop->finalize();
192-
child->list.back() = drop;
193-
child->finalize();
194-
curr->list[i] = child;
195-
more = true;
196-
changed = true;
180+
if (child->name.is()) {
181+
Expression* expression = child;
182+
// check if it's ok to remove the value from all breaks to us
183+
ProblemFinder finder(passOptions);
184+
finder.origin = child->name;
185+
finder.walk(expression);
186+
if (finder.found()) {
187+
child = nullptr;
188+
} else {
189+
// fix up breaks
190+
BreakValueDropper fixer(passOptions);
191+
fixer.origin = child->name;
192+
fixer.setModule(module);
193+
fixer.walk(expression);
194+
}
195+
}
196+
if (child) {
197+
// we can do it!
198+
// reuse the drop
199+
drop->value = child->list.back();
200+
drop->finalize();
201+
child->list.back() = drop;
202+
child->finalize();
203+
curr->list[i] = child;
204+
more = true;
205+
changed = true;
206+
}
197207
}
198208
}
199209
}

test/passes/merge-blocks.txt

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@
1414
)
1515
(func $drop-block-br (type $0)
1616
(block $block
17-
(block $x
18-
(drop
19-
(i32.const 1)
20-
)
21-
(br $x)
22-
(drop
17+
(drop
18+
(block $x (result i32)
19+
(br $x
20+
(i32.const 1)
21+
)
2322
(i32.const 0)
2423
)
2524
)
@@ -95,8 +94,8 @@
9594
(func $drop-block-squared-iloop (type $0)
9695
(drop
9796
(block $label$0 (result i32)
98-
(block $label$1
99-
(drop
97+
(drop
98+
(block $label$1
10099
(loop $label$2
101100
(br $label$2)
102101
)
@@ -124,4 +123,15 @@
124123
)
125124
)
126125
)
126+
(func $loop-block-drop-block-return (type $0)
127+
(loop $label$4
128+
(block $label$5
129+
(drop
130+
(block $label$6 (result i32)
131+
(return)
132+
)
133+
)
134+
)
135+
)
136+
)
127137
)

test/passes/merge-blocks.wast

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,5 +101,16 @@
101101
)
102102
)
103103
)
104+
(func $loop-block-drop-block-return
105+
(loop $label$4
106+
(block $label$5
107+
(drop
108+
(block $label$6 (result i32)
109+
(return)
110+
)
111+
)
112+
)
113+
)
114+
)
104115
)
105116

test/passes/remove-unused-names_merge-blocks.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,9 @@
840840
(func $drop-unreachable (type $4) (result i32)
841841
(local $0 i32)
842842
(drop
843-
(unreachable)
843+
(block (result i32)
844+
(unreachable)
845+
)
844846
)
845847
(unreachable)
846848
)

0 commit comments

Comments
 (0)