Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions src/ir/effects.h
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ class EffectAnalyzer {
// the target function throws and we know that will be caught anyhow,
// the same as the code below for the general path.
const auto& targetEffects = iter->second;
if (targetEffects.throws_ && parent.tryDepth > 0) {
if (targetEffects.throws_ && parent.tryDepth > 0 && !curr->isReturn) {
auto filteredEffects = targetEffects;
filteredEffects.throws_ = false;
parent.mergeIn(filteredEffects);
Expand All @@ -492,13 +492,15 @@ class EffectAnalyzer {

parent.calls = true;
// When EH is enabled, any call can throw.
if (parent.features.hasExceptionHandling() && parent.tryDepth == 0) {
if (parent.features.hasExceptionHandling() &&
(parent.tryDepth == 0 || curr->isReturn)) {
parent.throws_ = true;
}
}
void visitCallIndirect(CallIndirect* curr) {
parent.calls = true;
if (parent.features.hasExceptionHandling() && parent.tryDepth == 0) {
if (parent.features.hasExceptionHandling() &&
(parent.tryDepth == 0 || curr->isReturn)) {
parent.throws_ = true;
}
if (curr->isReturn) {
Expand Down Expand Up @@ -750,7 +752,8 @@ class EffectAnalyzer {
return;
}
parent.calls = true;
if (parent.features.hasExceptionHandling() && parent.tryDepth == 0) {
if (parent.features.hasExceptionHandling() &&
(parent.tryDepth == 0 || curr->isReturn)) {
parent.throws_ = true;
}
if (curr->isReturn) {
Expand Down
73 changes: 73 additions & 0 deletions test/lit/passes/global-effects.wast
Original file line number Diff line number Diff line change
Expand Up @@ -450,4 +450,77 @@
(call $cycle-with-unknown-call)
(call $import)
)

;; WITHOUT: (func $throw-through-return-call (type $0)
;; WITHOUT-NEXT: (try $try
;; WITHOUT-NEXT: (do
;; WITHOUT-NEXT: (return_call $throw)
;; WITHOUT-NEXT: )
;; WITHOUT-NEXT: (catch_all
;; WITHOUT-NEXT: (nop)
;; WITHOUT-NEXT: )
;; WITHOUT-NEXT: )
;; WITHOUT-NEXT: )
;; INCLUDE: (func $throw-through-return-call (type $0)
;; INCLUDE-NEXT: (try $try
;; INCLUDE-NEXT: (do
;; INCLUDE-NEXT: (return_call $throw)
;; INCLUDE-NEXT: )
;; INCLUDE-NEXT: (catch_all
;; INCLUDE-NEXT: (nop)
;; INCLUDE-NEXT: )
;; INCLUDE-NEXT: )
;; INCLUDE-NEXT: )
;; DISCARD: (func $throw-through-return-call (type $0)
;; DISCARD-NEXT: (try $try
;; DISCARD-NEXT: (do
;; DISCARD-NEXT: (return_call $throw)
;; DISCARD-NEXT: )
;; DISCARD-NEXT: (catch_all
;; DISCARD-NEXT: (nop)
;; DISCARD-NEXT: )
;; DISCARD-NEXT: )
;; DISCARD-NEXT: )
(func $throw-through-return-call
;; The exception is not catched, so this code cannot be simplified
(try
(do
(return_call $throw)
)
(catch_all)
)
)

;; WITHOUT: (func $catch-all-effects (type $0)
;; WITHOUT-NEXT: (try $try
;; WITHOUT-NEXT: (do
;; WITHOUT-NEXT: (call $throw-through-return-call)
;; WITHOUT-NEXT: )
;; WITHOUT-NEXT: (catch_all
;; WITHOUT-NEXT: (nop)
;; WITHOUT-NEXT: )
;; WITHOUT-NEXT: )
;; WITHOUT-NEXT: )
;; INCLUDE: (func $catch-all-effects (type $0)
;; INCLUDE-NEXT: (nop)
;; INCLUDE-NEXT: )
;; DISCARD: (func $catch-all-effects (type $0)
;; DISCARD-NEXT: (try $try
;; DISCARD-NEXT: (do
;; DISCARD-NEXT: (call $throw-through-return-call)
;; DISCARD-NEXT: )
;; DISCARD-NEXT: (catch_all
;; DISCARD-NEXT: (nop)
;; DISCARD-NEXT: )
;; DISCARD-NEXT: )
;; DISCARD-NEXT: )
(func $catch-all-effects
;; The exception is catched, so the function body can be optimized away
(try
(do
(call $throw-through-return-call)
)
(catch_all)
)
)
)