diff options
-rw-r--r-- | src/passes/SimplifyLocals.cpp | 14 | ||||
-rw-r--r-- | test/passes/simplify-locals_all-features.txt | 38 | ||||
-rw-r--r-- | test/passes/simplify-locals_all-features.wast | 32 |
3 files changed, 84 insertions, 0 deletions
diff --git a/src/passes/SimplifyLocals.cpp b/src/passes/SimplifyLocals.cpp index 85c719d4c..ca3d714f4 100644 --- a/src/passes/SimplifyLocals.cpp +++ b/src/passes/SimplifyLocals.cpp @@ -302,6 +302,20 @@ struct SimplifyLocals Expression** currp) { Expression* curr = *currp; + // Expressions that may throw cannot be sinked into 'try'. At the start of + // 'try', we drop all sinkables that may throw. + if (curr->is<Try>()) { + std::vector<Index> invalidated; + for (auto& sinkable : self->sinkables) { + if (sinkable.second.effects.throws) { + invalidated.push_back(sinkable.first); + } + } + for (auto index : invalidated) { + self->sinkables.erase(index); + } + } + EffectAnalyzer effects(self->getPassOptions(), self->getModule()->features); if (effects.checkPre(curr)) { self->checkInvalidations(effects); diff --git a/test/passes/simplify-locals_all-features.txt b/test/passes/simplify-locals_all-features.txt index 0418e6bd1..fbb1f87ed 100644 --- a/test/passes/simplify-locals_all-features.txt +++ b/test/passes/simplify-locals_all-features.txt @@ -1896,6 +1896,7 @@ (type $none_=>_none (func)) (type $i32_exnref_=>_none (func (param i32 exnref))) (type $exnref_=>_none (func (param exnref))) + (type $none_=>_i32 (func (result i32))) (type $none_=>_exnref (func (result exnref))) (event $event$0 (attr 0) (param)) (event $event$1 (attr 0) (param exnref)) @@ -1980,4 +1981,41 @@ ) ) ) + (func $bar (result i32) + (i32.const 3) + ) + (func $call-cannot-be-sinked-into-try + (local $0 i32) + (local.set $0 + (call $bar) + ) + (try + (do + (drop + (local.get $0) + ) + ) + (catch + (drop + (exnref.pop) + ) + ) + ) + ) + (func $non-call-can-be-sinked-into-try + (local $0 i32) + (nop) + (try + (do + (drop + (i32.const 3) + ) + ) + (catch + (drop + (exnref.pop) + ) + ) + ) + ) ) diff --git a/test/passes/simplify-locals_all-features.wast b/test/passes/simplify-locals_all-features.wast index 4fdedb2f9..a8e1a161f 100644 --- a/test/passes/simplify-locals_all-features.wast +++ b/test/passes/simplify-locals_all-features.wast @@ -1749,4 +1749,36 @@ ) ) ) + + (func $bar (result i32) (i32.const 3)) + (func $call-cannot-be-sinked-into-try (local $0 i32) + (drop + ;; This local.tee should NOT be sinked into 'try' below, because it may + ;; throw + (local.tee $0 (call $bar)) + ) + (try + (do + (drop (local.get $0)) + ) + (catch + (drop (exnref.pop)) + ) + ) + ) + + (func $non-call-can-be-sinked-into-try (local $0 i32) + (drop + ;; This local.tee can be sinked into 'try' below, because it cannot throw + (local.tee $0 (i32.const 3)) + ) + (try + (do + (drop (local.get $0)) + ) + (catch + (drop (exnref.pop)) + ) + ) + ) ) |