summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ir/lubs.cpp7
-rw-r--r--test/lit/passes/dae_all-features.wast36
2 files changed, 42 insertions, 1 deletions
diff --git a/src/ir/lubs.cpp b/src/ir/lubs.cpp
index ead1299b5..1f844c244 100644
--- a/src/ir/lubs.cpp
+++ b/src/ir/lubs.cpp
@@ -82,10 +82,15 @@ LUBFinder getResultsLUB(Function* func, Module& wasm) {
for (auto* call : FindAll<CallRef>(func->body).list) {
if (call->isReturn) {
auto targetType = call->target->type;
+ // We can skip unreachable code and calls to bottom types, as both trap.
if (targetType == Type::unreachable) {
continue;
}
- if (!processReturnType(targetType.getHeapType().getSignature().results)) {
+ auto targetHeapType = targetType.getHeapType();
+ if (targetHeapType.isBottom()) {
+ continue;
+ }
+ if (!processReturnType(targetHeapType.getSignature().results)) {
return lub;
}
}
diff --git a/test/lit/passes/dae_all-features.wast b/test/lit/passes/dae_all-features.wast
index 3e628d6af..71af5a0bc 100644
--- a/test/lit/passes/dae_all-features.wast
+++ b/test/lit/passes/dae_all-features.wast
@@ -692,3 +692,39 @@
)
)
)
+
+(module
+ ;; CHECK: (type $A (func (result (ref $A))))
+ (type $A (func (result (ref $A))))
+
+ ;; CHECK: (type $none_=>_none (func))
+
+ ;; CHECK: (func $no-caller (type $A) (result (ref $A))
+ ;; CHECK-NEXT: (block ;; (replaces something unreachable we can't emit)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (ref.null nofunc)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $no-caller (type $A) (result (ref $A))
+ ;; This return_call is to a bottom type, which we should ignore and not error
+ ;; on. There is nothing to optimize here (other passes will turn this call
+ ;; into an unreachable). In particular we should not be confused by the fact
+ ;; that this expression itself is unreachable (as a return call).
+ (return_call_ref $A
+ (ref.null nofunc)
+ )
+ )
+
+ ;; CHECK: (func $caller (type $none_=>_none)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (call $no-caller)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $caller
+ (drop
+ (call $no-caller)
+ )
+ )
+)