Skip to content

Commit 930034f

Browse files
authored
Fix flow reset during throw => break opts in RemoveUnusedBrs (#6993)
#6980 was missing the logic to reset flows after replacing a throw. The process of replacing the throw introduces new code and in particular a drop, which blocks branches from flowing to their targets. In the testcase here, the br was turned into nop before this fix.
1 parent 1eb0126 commit 930034f

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

src/passes/RemoveUnusedBrs.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,10 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
518518
auto* rep = getDroppedChildrenAndAppend(
519519
curr, wasm, getPassOptions(), br, DropMode::IgnoreParentEffects);
520520
replaceCurrent(rep);
521+
// We modified the code here and may have added a drop, etc., so
522+
// stop the flow (rather than re-scan it somehow). We leave
523+
// optimizing anything that flows out for later iterations.
524+
stopFlow();
521525
}
522526

523527
// Return even if we did not optimize: we found our tag was caught.

test/lit/passes/remove-unused-brs-eh.wast

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,4 +412,44 @@
412412
)
413413
)
414414
)
415+
416+
;; CHECK: (func $no-flow-through-throw (type $4)
417+
;; CHECK-NEXT: (block $label
418+
;; CHECK-NEXT: (try_table (catch_all $label)
419+
;; CHECK-NEXT: (drop
420+
;; CHECK-NEXT: (if (result i32)
421+
;; CHECK-NEXT: (i32.const 0)
422+
;; CHECK-NEXT: (then
423+
;; CHECK-NEXT: (br $label)
424+
;; CHECK-NEXT: )
425+
;; CHECK-NEXT: (else
426+
;; CHECK-NEXT: (i32.const 42)
427+
;; CHECK-NEXT: )
428+
;; CHECK-NEXT: )
429+
;; CHECK-NEXT: )
430+
;; CHECK-NEXT: (br $label)
431+
;; CHECK-NEXT: )
432+
;; CHECK-NEXT: )
433+
;; CHECK-NEXT: )
434+
(func $no-flow-through-throw
435+
;; The throw here can turn into a break. While doing so, we must clear all
436+
;; the currently-flowing things, namely the br in the if arm. If we do not
437+
;; do so then it will try to flow out through the drop that we add for the
438+
;; throw's value, which is impossible.
439+
(block $label
440+
(try_table (catch_all $label)
441+
(throw $e
442+
(if (result i32)
443+
(i32.const 0)
444+
(then
445+
(br $label)
446+
)
447+
(else
448+
(i32.const 42)
449+
)
450+
)
451+
)
452+
)
453+
)
454+
)
415455
)

0 commit comments

Comments
 (0)