diff options
-rw-r--r-- | src/ir/properties.h | 7 | ||||
-rw-r--r-- | test/lit/passes/optimize-instructions-gc.wast | 31 |
2 files changed, 37 insertions, 1 deletions
diff --git a/src/ir/properties.h b/src/ir/properties.h index 2214eecaf..cddcbc5f2 100644 --- a/src/ir/properties.h +++ b/src/ir/properties.h @@ -311,7 +311,12 @@ inline Expression* getImmediateFallthrough( } else if (auto* as = curr->dynCast<RefCast>()) { return as->ref; } else if (auto* as = curr->dynCast<RefAs>()) { - return as->value; + // Extern conversions are not casts and actually produce new values. + // Treating them as fallthroughs would lead to misoptimizations of + // subsequent casts. + if (as->op != ExternInternalize && as->op != ExternExternalize) { + return as->value; + } } else if (auto* br = curr->dynCast<BrOn>()) { return br->ref; } diff --git a/test/lit/passes/optimize-instructions-gc.wast b/test/lit/passes/optimize-instructions-gc.wast index c5100434d..c0ea515d0 100644 --- a/test/lit/passes/optimize-instructions-gc.wast +++ b/test/lit/passes/optimize-instructions-gc.wast @@ -3251,4 +3251,35 @@ ) ) ) + + ;; CHECK: (func $cast-internalized-extern (type $externref_=>_none) (param $externref externref) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.cast $A + ;; CHECK-NEXT: (extern.internalize + ;; CHECK-NEXT: (local.get $externref) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; NOMNL: (func $cast-internalized-extern (type $externref_=>_none) (param $externref externref) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.cast $A + ;; NOMNL-NEXT: (extern.internalize + ;; NOMNL-NEXT: (local.get $externref) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + (func $cast-internalized-extern (param $externref externref) + ;; We cannot optimize this cast, and in particular we should not treat the + ;; externref as falling through to the cast and incorrectly inferring that + ;; the cast cannot succeed. + (drop + (ref.cast $A + (extern.internalize + (local.get $externref) + ) + ) + ) + ) ) |