diff options
author | Alon Zakai <azakai@google.com> | 2023-06-12 16:10:14 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-12 16:10:14 -0700 |
commit | 585af93ec6a22feb8954bc118f0bff997d1fc165 (patch) | |
tree | 764471911b2baf7f81148591b4db76fae08f72e2 | |
parent | 87f3807796cb7b04321914bea491e806a54883b6 (diff) | |
download | binaryen-585af93ec6a22feb8954bc118f0bff997d1fc165.tar.gz binaryen-585af93ec6a22feb8954bc118f0bff997d1fc165.tar.bz2 binaryen-585af93ec6a22feb8954bc118f0bff997d1fc165.zip |
DeadArgumentElimination: Do not error on bottom types in result refining (#5763)
More generally, the LUB computation that code relies on did not handle
bottom types properly.
-rw-r--r-- | src/ir/lubs.cpp | 7 | ||||
-rw-r--r-- | test/lit/passes/dae_all-features.wast | 36 |
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) + ) + ) +) |