diff --git a/src/passes/AbstractTypeRefining.cpp b/src/passes/AbstractTypeRefining.cpp index af095d07a38..73551f3c729 100644 --- a/src/passes/AbstractTypeRefining.cpp +++ b/src/passes/AbstractTypeRefining.cpp @@ -406,7 +406,8 @@ struct AbstractTypeRefining : public Pass { auto subDescriptor = *optimized; Builder builder(*getModule()); - if (curr->type.isExact() || subDescriptor == HeapTypes::none) { + if (curr->type.isExact() || + subDescriptor.isMaybeShared(HeapType::none)) { // This is exact, so we can ignore subtypes, or there is no subtype to // optimize to. In this case it must trap. replaceCurrent(builder.makeSequence(builder.makeDrop(curr->ref), diff --git a/test/lit/passes/abstract-type-refining-desc.wast b/test/lit/passes/abstract-type-refining-desc.wast index 35358c6f1a6..8b8e082c234 100644 --- a/test/lit/passes/abstract-type-refining-desc.wast +++ b/test/lit/passes/abstract-type-refining-desc.wast @@ -1189,3 +1189,58 @@ ) ) +;; Shared abstract described types. +(module + (rec + (type $A (sub (shared (descriptor $B (struct))))) + (type $B (sub (shared (describes $A (descriptor $C (struct)))))) + (type $C (sub (shared (describes $B (struct))))) + ) + + ;; YESTNH: (rec + ;; YESTNH-NEXT: (type $0 (func (param (ref (shared none))) (result (ref (shared none))))) + + ;; YESTNH: (type $1 (func (param (ref (shared none))) (result (ref (shared none))))) + + ;; YESTNH: (func $A (type $0) (param $x (ref (shared none))) (result (ref (shared none))) + ;; YESTNH-NEXT: (drop + ;; YESTNH-NEXT: (local.get $x) + ;; YESTNH-NEXT: ) + ;; YESTNH-NEXT: (unreachable) + ;; YESTNH-NEXT: ) + ;; NO_TNH: (rec + ;; NO_TNH-NEXT: (type $0 (func (param (ref (shared none))) (result (ref (shared none))))) + + ;; NO_TNH: (type $1 (func (param (ref (shared none))) (result (ref (shared none))))) + + ;; NO_TNH: (func $A (type $0) (param $x (ref (shared none))) (result (ref (shared none))) + ;; NO_TNH-NEXT: (drop + ;; NO_TNH-NEXT: (local.get $x) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: (unreachable) + ;; NO_TNH-NEXT: ) + (func $A (param $x (ref $A)) (result (ref $B)) + (ref.get_desc $A + (local.get $x) + ) + ) + + ;; YESTNH: (func $B (type $1) (param $x (ref (shared none))) (result (ref (shared none))) + ;; YESTNH-NEXT: (drop + ;; YESTNH-NEXT: (local.get $x) + ;; YESTNH-NEXT: ) + ;; YESTNH-NEXT: (unreachable) + ;; YESTNH-NEXT: ) + ;; NO_TNH: (func $B (type $1) (param $x (ref (shared none))) (result (ref (shared none))) + ;; NO_TNH-NEXT: (drop + ;; NO_TNH-NEXT: (local.get $x) + ;; NO_TNH-NEXT: ) + ;; NO_TNH-NEXT: (unreachable) + ;; NO_TNH-NEXT: ) + (func $B (param $x (ref $B)) (result (ref $C)) + (ref.get_desc $B + (local.get $x) + ) + ) +) +