Skip to content

Commit 7a10abf

Browse files
committed
fix
1 parent b520ed6 commit 7a10abf

2 files changed

Lines changed: 66 additions & 0 deletions

File tree

src/passes/Vacuum.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <ir/branch-hints.h>
2323
#include <ir/drop.h>
2424
#include <ir/effects.h>
25+
#include <ir/eh-utils.h>
2526
#include <ir/find_all.h>
2627
#include <ir/intrinsics.h>
2728
#include <ir/iteration.h>
@@ -38,8 +39,18 @@ struct Vacuum : public WalkerPass<ExpressionStackWalker<Vacuum>> {
3839

3940
std::unique_ptr<Pass> create() override { return std::make_unique<Vacuum>(); }
4041

42+
// Track whether we need to fix up pops at the end: adding a block in a Try
43+
// can require that.
44+
bool hasTry = false;
45+
bool addedBlocks = false;
46+
4147
void doWalkFunction(Function* func) {
4248
walk(func->body);
49+
50+
if (hasTry && addedBlocks) {
51+
EHUtils::handleBlockNestedPops(func, *getModule());
52+
}
53+
4354
ReFinalize().walkFunctionInModule(func, getModule());
4455
}
4556

@@ -122,6 +133,7 @@ struct Vacuum : public WalkerPass<ExpressionStackWalker<Vacuum>> {
122133
if (curr->type.isDefaultable()) {
123134
auto* dummy = Builder(*getModule())
124135
.makeConstantExpression(Literal::makeZeros(curr->type));
136+
addedBlocks = true;
125137
return getDroppedChildrenAndAppend(
126138
curr, *getModule(), getPassOptions(), dummy);
127139
}
@@ -438,6 +450,8 @@ struct Vacuum : public WalkerPass<ExpressionStackWalker<Vacuum>> {
438450
}
439451

440452
void visitTry(Try* curr) {
453+
hasTry = true;
454+
441455
// If try's body does not throw, the whole try-catch can be replaced with
442456
// the try's body.
443457
if (!EffectAnalyzer(getPassOptions(), *getModule(), curr->body).throws()) {

test/lit/passes/vacuum-eh-legacy.wast

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,4 +293,56 @@
293293
(catch_all)
294294
)
295295
)
296+
297+
;; CHECK: (func $add-block-in-catch-pop (type $void)
298+
;; CHECK-NEXT: (local $temp i32)
299+
;; CHECK-NEXT: (local $1 i32)
300+
;; CHECK-NEXT: (try
301+
;; CHECK-NEXT: (do
302+
;; CHECK-NEXT: (call $add-block-in-catch-pop)
303+
;; CHECK-NEXT: )
304+
;; CHECK-NEXT: (catch $e
305+
;; CHECK-NEXT: (local.set $1
306+
;; CHECK-NEXT: (pop i32)
307+
;; CHECK-NEXT: )
308+
;; CHECK-NEXT: (block
309+
;; CHECK-NEXT: (block
310+
;; CHECK-NEXT: (drop
311+
;; CHECK-NEXT: (local.get $1)
312+
;; CHECK-NEXT: )
313+
;; CHECK-NEXT: (drop
314+
;; CHECK-NEXT: (local.tee $temp
315+
;; CHECK-NEXT: (i32.const 0)
316+
;; CHECK-NEXT: )
317+
;; CHECK-NEXT: )
318+
;; CHECK-NEXT: )
319+
;; CHECK-NEXT: (call $add-block-in-catch-pop)
320+
;; CHECK-NEXT: )
321+
;; CHECK-NEXT: )
322+
;; CHECK-NEXT: )
323+
;; CHECK-NEXT: )
324+
(func $add-block-in-catch-pop
325+
(local $temp i32)
326+
(try
327+
(do
328+
;; We need a call so the try does not vanish entirely.
329+
(call $add-block-in-catch-pop)
330+
)
331+
(catch $e
332+
(drop
333+
;; This select will be removed, and a block appear, which must be handled
334+
;; for the pop.
335+
(select
336+
(pop i32)
337+
(local.tee $temp
338+
(i32.const 0)
339+
)
340+
(i32.const 0)
341+
)
342+
)
343+
;; Needed to avoid the catch being trivial.
344+
(call $add-block-in-catch-pop)
345+
)
346+
)
347+
)
296348
)

0 commit comments

Comments
 (0)