diff options
-rw-r--r-- | src/passes/RemoveUnusedBrs.cpp | 4 | ||||
-rw-r--r-- | test/lit/passes/remove-unused-brs-eh.wast | 40 |
2 files changed, 44 insertions, 0 deletions
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp index c2370aca6..c2f470d80 100644 --- a/src/passes/RemoveUnusedBrs.cpp +++ b/src/passes/RemoveUnusedBrs.cpp @@ -518,6 +518,10 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> { auto* rep = getDroppedChildrenAndAppend( curr, wasm, getPassOptions(), br, DropMode::IgnoreParentEffects); replaceCurrent(rep); + // We modified the code here and may have added a drop, etc., so + // stop the flow (rather than re-scan it somehow). We leave + // optimizing anything that flows out for later iterations. + stopFlow(); } // Return even if we did not optimize: we found our tag was caught. diff --git a/test/lit/passes/remove-unused-brs-eh.wast b/test/lit/passes/remove-unused-brs-eh.wast index b3b89df63..bb4278f86 100644 --- a/test/lit/passes/remove-unused-brs-eh.wast +++ b/test/lit/passes/remove-unused-brs-eh.wast @@ -412,4 +412,44 @@ ) ) ) + + ;; CHECK: (func $no-flow-through-throw (type $4) + ;; CHECK-NEXT: (block $label + ;; CHECK-NEXT: (try_table (catch_all $label) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (br $label) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (else + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $label) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $no-flow-through-throw + ;; The throw here can turn into a break. While doing so, we must clear all + ;; the currently-flowing things, namely the br in the if arm. If we do not + ;; do so then it will try to flow out through the drop that we add for the + ;; throw's value, which is impossible. + (block $label + (try_table (catch_all $label) + (throw $e + (if (result i32) + (i32.const 0) + (then + (br $label) + ) + (else + (i32.const 42) + ) + ) + ) + ) + ) + ) ) |