diff options
-rw-r--r-- | src/passes/TypeSSA.cpp | 4 | ||||
-rw-r--r-- | test/lit/passes/type-ssa.wast | 33 |
2 files changed, 37 insertions, 0 deletions
diff --git a/src/passes/TypeSSA.cpp b/src/passes/TypeSSA.cpp index 25575e70e..f44df96e1 100644 --- a/src/passes/TypeSSA.cpp +++ b/src/passes/TypeSSA.cpp @@ -51,6 +51,7 @@ #include "ir/module-utils.h" #include "ir/names.h" #include "ir/possible-constant.h" +#include "ir/utils.h" #include "pass.h" #include "support/hash.h" #include "wasm-builder.h" @@ -204,6 +205,9 @@ struct TypeSSA : public Pass { // in the isorecursive type system we want to create a single new rec group // for them all (see below). modifyNews(); + + // Finally, refinalize to propagate the new types to parents. + ReFinalize().run(getPassRunner(), module); } News newsToModify; diff --git a/test/lit/passes/type-ssa.wast b/test/lit/passes/type-ssa.wast index 6980cb46e..dedf43832 100644 --- a/test/lit/passes/type-ssa.wast +++ b/test/lit/passes/type-ssa.wast @@ -453,3 +453,36 @@ ) ) ) + +(module + ;; CHECK: (type $A (struct )) + (type $A (struct )) + + ;; CHECK: (type $A$1 (sub $A (struct ))) + + ;; CHECK: (type $none_=>_ref|$A| (func (result (ref $A)))) + + ;; CHECK: (func $0 (type $none_=>_ref|$A|) (result (ref $A)) + ;; CHECK-NEXT: (block $label (result (ref $A$1)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (br_on_cast $label (ref $A$1) (ref $A$1) + ;; CHECK-NEXT: (struct.new_default $A$1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $0 (result (ref $A)) + ;; After creating a subtype of $A as the input to the br_on_cast, the cast + ;; must be refinalized so that it validates (otherwise, it would try to cast + ;; to a supertype). + (block $label (result (ref $A)) + (drop + (br_on_cast $label (ref $A) (ref $A) + (struct.new_default $A) + ) + ) + (unreachable) + ) + ) +) |