summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2023-04-13 08:33:40 -0700
committerGitHub <noreply@github.com>2023-04-13 08:33:40 -0700
commit1034a6be0b411444f4a2e4fb610a655982d30e31 (patch)
tree808a96699f52c9d1f1692f2b3d34f2bc22589798
parent42fc582162899aed64f2e1fa6a7a544fcba27a6d (diff)
downloadbinaryen-1034a6be0b411444f4a2e4fb610a655982d30e31.tar.gz
binaryen-1034a6be0b411444f4a2e4fb610a655982d30e31.tar.bz2
binaryen-1034a6be0b411444f4a2e4fb610a655982d30e31.zip
Convert some tests off of --nominal (#5660)
In preparation to remove the nominal type system, which is nonstandard and not usable for modules with nontrivial external linkage requirements, port an initial batch of tests to use the standard isorecursive type system. The port involves reordering input types to ensure that supertypes precede their subtypes and inserting rec groups to ensure that structurally identical types maintain their separate identities. More tests will be ported in future PRs before the nominal type system is removed entirely.
-rw-r--r--test/lit/binary/annotated-array-len.test2
-rw-r--r--test/lit/gc-eh.wast16
-rw-r--r--test/lit/gc-read-write-effects.wast15
-rw-r--r--test/lit/heap-types.wast43
-rw-r--r--test/lit/isorecursive-good.wast1
-rw-r--r--test/lit/nominal-bad.wast29
-rw-r--r--test/lit/nominal-good.wast52
-rw-r--r--test/lit/parse-bad-supertype.wast2
-rw-r--r--test/lit/parse-double-unreachable.wast2
-rw-r--r--test/lit/parse-nominal-types-extends.wast50
-rw-r--r--test/lit/parse-nominal-types.wast50
-rw-r--r--test/lit/passes/abstract-type-refining.wast206
-rw-r--r--test/lit/passes/cfp.wast71
-rw-r--r--test/lit/subtype-chain.wast (renamed from test/lit/nominal-chain.wast)12
-rw-r--r--test/lit/subtypes.wast72
15 files changed, 286 insertions, 337 deletions
diff --git a/test/lit/binary/annotated-array-len.test b/test/lit/binary/annotated-array-len.test
index 62e51fcf3..9cf6eecbe 100644
--- a/test/lit/binary/annotated-array-len.test
+++ b/test/lit/binary/annotated-array-len.test
@@ -3,7 +3,7 @@
;; Test the we can properly parse the annotated array.len format that we no
;; longer emit.
-;; RUN: wasm-dis %s.wasm -all --nominal | filecheck %s
+;; RUN: wasm-dis %s.wasm -all | filecheck %s
;; CHECK: (type $none_=>_i32 (func (result i32)))
diff --git a/test/lit/gc-eh.wast b/test/lit/gc-eh.wast
index df2f3b416..b037086ca 100644
--- a/test/lit/gc-eh.wast
+++ b/test/lit/gc-eh.wast
@@ -3,17 +3,14 @@
;; Check that pops of GC types work correctly.
;; RUN: wasm-opt -all %s -S -o - | filecheck %s
-;; RUN: wasm-opt -all --nominal %s -S -o - | filecheck %s --check-prefix=NOMNL
(module
;; CHECK: (type $A (struct (field (mut i32))))
- ;; NOMNL: (type $A (struct (field (mut i32))))
(type $A (struct
(field (mut i32))
))
;; CHECK: (tag $tagA (param (ref $A)))
- ;; NOMNL: (tag $tagA (param (ref $A)))
(tag $tagA (param (ref $A)))
;; CHECK: (func $foo (type $none_=>_ref?|$A|) (result (ref null $A))
@@ -29,19 +26,6 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
- ;; NOMNL: (func $foo (type $none_=>_ref?|$A|) (result (ref null $A))
- ;; NOMNL-NEXT: (try $try
- ;; NOMNL-NEXT: (do
- ;; NOMNL-NEXT: (nop)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (catch $tagA
- ;; NOMNL-NEXT: (return
- ;; NOMNL-NEXT: (pop (ref $A))
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (ref.null none)
- ;; NOMNL-NEXT: )
(func $foo (result (ref null $A))
(try
(do
diff --git a/test/lit/gc-read-write-effects.wast b/test/lit/gc-read-write-effects.wast
index da869e9b9..e05335554 100644
--- a/test/lit/gc-read-write-effects.wast
+++ b/test/lit/gc-read-write-effects.wast
@@ -4,11 +4,9 @@
;; struct field.
;; RUN: wasm-opt -all --simplify-locals %s -S -o - | filecheck %s
-;; RUN: wasm-opt -all --simplify-locals %s --nominal -S -o - | filecheck %s --check-prefix=NOMNL
(module
;; CHECK: (type $A (struct (field (mut i32))))
- ;; NOMNL: (type $A (struct (field (mut i32))))
(type $A (struct
(field (mut i32))
))
@@ -37,19 +35,6 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $y)
;; CHECK-NEXT: )
- ;; NOMNL: (func $test (type $ref?|$A|_=>_i32) (param $x (ref null $A)) (result i32)
- ;; NOMNL-NEXT: (local $y i32)
- ;; NOMNL-NEXT: (local.set $y
- ;; NOMNL-NEXT: (struct.get $A 0
- ;; NOMNL-NEXT: (local.get $x)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (struct.set $A 0
- ;; NOMNL-NEXT: (local.get $x)
- ;; NOMNL-NEXT: (i32.const 10)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: (local.get $y)
- ;; NOMNL-NEXT: )
(func $test (export "test") (param $x (ref null $A)) (result i32)
(local $y i32)
(local.set $y
diff --git a/test/lit/heap-types.wast b/test/lit/heap-types.wast
index 9dc8f11a8..9f0e43602 100644
--- a/test/lit/heap-types.wast
+++ b/test/lit/heap-types.wast
@@ -6,12 +6,10 @@
;; type, and hit an error during --roundtrip.
;; RUN: foreach %s %t wasm-opt -all --roundtrip -S -o - | filecheck %s
-;; RUN: foreach %s %t wasm-opt -all --roundtrip -S --nominal -o - | filecheck %s --check-prefix NOMNL
(module
;; CHECK: (type $struct.A (struct (field i32)))
(type $struct.A (struct i32))
- ;; NOMNL: (type $struct.B (struct (field i32)))
(type $struct.B (struct i32))
;; CHECK: (func $test (type $none_=>_none)
;; CHECK-NEXT: (drop
@@ -20,13 +18,6 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; NOMNL: (func $test (type $none_=>_none)
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.test $struct.B
- ;; NOMNL-NEXT: (ref.null none)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
(func $test
(drop
(ref.test $struct.B (ref.null $struct.A))
@@ -37,7 +28,6 @@
(module
;; CHECK: (type $struct.A (struct (field i32)))
(type $struct.A (struct i32))
- ;; NOMNL: (type $struct.B (struct (field i32)))
(type $struct.B (struct i32))
;; CHECK: (func $test (type $none_=>_none)
;; CHECK-NEXT: (drop
@@ -46,13 +36,6 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; NOMNL: (func $test (type $none_=>_none)
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (ref.cast null $struct.B
- ;; NOMNL-NEXT: (ref.null none)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
(func $test
(drop
(ref.cast null $struct.B (ref.null $struct.A))
@@ -62,18 +45,12 @@
(module
;; CHECK: (type $struct.A (struct (field i32)))
- ;; NOMNL: (type $struct.A (struct (field i32)))
(type $struct.A (struct i32))
;; CHECK: (func $test (type $none_=>_none)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new_default $struct.A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; NOMNL: (func $test (type $none_=>_none)
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (struct.new_default $struct.A)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
(func $test
(drop
(struct.new_default $struct.A)
@@ -83,7 +60,6 @@
(module
;; CHECK: (type $vector (array (mut f64)))
- ;; NOMNL: (type $vector (array (mut f64)))
(type $vector (array (mut f64)))
;; CHECK: (func $test (type $none_=>_none)
;; CHECK-NEXT: (drop
@@ -93,14 +69,6 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; NOMNL: (func $test (type $none_=>_none)
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (array.new $vector
- ;; NOMNL-NEXT: (f64.const 3.14159)
- ;; NOMNL-NEXT: (i32.const 3)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
(func $test
(drop
(array.new $vector
@@ -113,7 +81,6 @@
(module
;; CHECK: (type $vector (array (mut f64)))
- ;; NOMNL: (type $vector (array (mut f64)))
(type $vector (array (mut f64)))
;; CHECK: (func $test (type $none_=>_none)
;; CHECK-NEXT: (drop
@@ -125,16 +92,6 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; NOMNL: (func $test (type $none_=>_none)
- ;; NOMNL-NEXT: (drop
- ;; NOMNL-NEXT: (array.new_fixed $vector
- ;; NOMNL-NEXT: (f64.const 1)
- ;; NOMNL-NEXT: (f64.const 2)
- ;; NOMNL-NEXT: (f64.const 4)
- ;; NOMNL-NEXT: (f64.const 8)
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
- ;; NOMNL-NEXT: )
(func $test
(drop
(array.new_fixed $vector
diff --git a/test/lit/isorecursive-good.wast b/test/lit/isorecursive-good.wast
index 0f5cbddf0..53631c92b 100644
--- a/test/lit/isorecursive-good.wast
+++ b/test/lit/isorecursive-good.wast
@@ -2,7 +2,6 @@
;; RUN: wasm-opt %s -all --hybrid -S -o - | filecheck %s --check-prefix HYBRID
;; RUN: wasm-opt %s -all --hybrid --roundtrip -S -o - | filecheck %s --check-prefix HYBRID
-;; RUN: wasm-opt %s -all --nominal -S -o - | filecheck %s --check-prefix NOMINAL
(module
(rec
diff --git a/test/lit/nominal-bad.wast b/test/lit/nominal-bad.wast
deleted file mode 100644
index 43a1eea95..000000000
--- a/test/lit/nominal-bad.wast
+++ /dev/null
@@ -1,29 +0,0 @@
-;; RUN: not wasm-opt %s -all --nominal -S -o - 2>&1 | filecheck %s
-
-;; CHECK: [wasm-validator error in function make-super-struct] function body type must match
-;; CHECK: [wasm-validator error in function make-super-array] function body type must match
-
-(module
-
- (type $sub-struct (struct i32 i64))
- (type $super-struct (struct i32))
-
- (type $sub-array (array (ref $sub-struct)))
- (type $super-array (array (ref $super-struct)))
-
- (func $make-sub-struct (result (ref $sub-struct))
- (unreachable)
- )
-
- (func $make-super-struct (result (ref $super-struct))
- (call $make-sub-struct)
- )
-
- (func $make-sub-array (result (ref $sub-array))
- (unreachable)
- )
-
- (func $make-super-array (result (ref $super-array))
- (call $make-sub-array)
- )
-)
diff --git a/test/lit/nominal-good.wast b/test/lit/nominal-good.wast
deleted file mode 100644
index 76863d637..000000000
--- a/test/lit/nominal-good.wast
+++ /dev/null
@@ -1,52 +0,0 @@
-;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
-;; RUN: wasm-opt %s -all --nominal -S -o - | filecheck %s --check-prefix CHECK
-;; RUN: wasm-opt %s -all --nominal --roundtrip -S -o - | filecheck %s
-;; RUN: wasm-opt %s -all --hybrid -S -o - | filecheck %s --check-prefix CHECK
-;; RUN: wasm-opt %s -all --hybrid --roundtrip -S -o - | filecheck %s
-
-;; Note that --hybrid and --nominal have the same output, so they share the CHECK prefix.
-
-(module
-
- ;; CHECK: (type $super-struct (struct (field i32)))
- (type $super-struct (struct i32))
-
- ;; CHECK: (type $sub-struct (struct_subtype (field i32) (field i64) $super-struct))
- (type $sub-struct (struct_subtype i32 i64 $super-struct))
-
- ;; CHECK: (type $super-array (array (ref $super-struct)))
- (type $super-array (array (ref $super-struct)))
-
- ;; CHECK: (type $sub-array (array_subtype (ref $sub-struct) $super-array))
- (type $sub-array (array_subtype (ref $sub-struct) $super-array))
-
- ;; TODO: signature types as well, once functions store their HeapTypes.
-
- ;; CHECK: (func $make-super-struct (type $none_=>_ref|$super-struct|) (result (ref $super-struct))
- ;; CHECK-NEXT: (call $make-sub-struct)
- ;; CHECK-NEXT: )
- (func $make-super-struct (result (ref $super-struct))
- (call $make-sub-struct)
- )
-
- ;; CHECK: (func $make-sub-struct (type $none_=>_ref|$sub-struct|) (result (ref $sub-struct))
- ;; CHECK-NEXT: (unreachable)
- ;; CHECK-NEXT: )
- (func $make-sub-struct (result (ref $sub-struct))
- (unreachable)
- )
-
- ;; CHECK: (func $make-super-array (type $none_=>_ref|$super-array|) (result (ref $super-array))
- ;; CHECK-NEXT: (call $make-sub-array)
- ;; CHECK-NEXT: )
- (func $make-super-array (result (ref $super-array))
- (call $make-sub-array)
- )
-
- ;; CHECK: (func $make-sub-array (type $none_=>_ref|$sub-array|) (result (ref $sub-array))
- ;; CHECK-NEXT: (unreachable)
- ;; CHECK-NEXT: )
- (func $make-sub-array (result (ref $sub-array))
- (unreachable)
- )
-)
diff --git a/test/lit/parse-bad-supertype.wast b/test/lit/parse-bad-supertype.wast
index 3a50efecf..cbb53c675 100644
--- a/test/lit/parse-bad-supertype.wast
+++ b/test/lit/parse-bad-supertype.wast
@@ -1,6 +1,6 @@
;; Test that an invalid supertype results in a useful error message
-;; RUN: not wasm-opt %s -all --nominal 2>&1 | filecheck %s
+;; RUN: not wasm-opt %s -all 2>&1 | filecheck %s
;; CHECK: Fatal: Invalid type: Heap type has an invalid supertype at type $sub
(module
diff --git a/test/lit/parse-double-unreachable.wast b/test/lit/parse-double-unreachable.wast
index 333eb6fa9..2abdd2e5b 100644
--- a/test/lit/parse-double-unreachable.wast
+++ b/test/lit/parse-double-unreachable.wast
@@ -1,6 +1,6 @@
;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
-;; RUN: wasm-opt %s -all --nominal --roundtrip -S -o - | filecheck %s
+;; RUN: wasm-opt %s -all --roundtrip -S -o - | filecheck %s
;; Regression test for a bug in which we could pop the expression stack past an
;; unreachable if we were already in unreachable parsing mode.
diff --git a/test/lit/parse-nominal-types-extends.wast b/test/lit/parse-nominal-types-extends.wast
index e7641937d..ade4f5e6b 100644
--- a/test/lit/parse-nominal-types-extends.wast
+++ b/test/lit/parse-nominal-types-extends.wast
@@ -1,62 +1,66 @@
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
;; Test that new-style nominal types are parsed correctly.
-;; TODO: Remove --nominal below once nominal types are parsed as nominal by default.
-;; RUN: foreach %s %t wasm-opt --nominal -all -S -o - | filecheck %s
-;; RUN: foreach %s %t wasm-opt --nominal -all --roundtrip -S -o - | filecheck %s
+;; RUN: foreach %s %t wasm-opt -all -S -o - | filecheck %s
+;; RUN: foreach %s %t wasm-opt -all --roundtrip -S -o - | filecheck %s
;; void function type
(module
- (type $sub (func) (extends $super))
-
;; CHECK: (type $super (func))
(type $super (func))
- ;; CHECK: (global $g (ref null $super) (ref.null nofunc))
- (global $g (ref null $super) (ref.null $sub))
+ ;; CHECK: (type $sub (func_subtype $super))
+ (type $sub (func) (extends $super))
+
+ ;; CHECK: (global $g (ref null $sub) (ref.null nofunc))
+ (global $g (ref null $sub) (ref.null nofunc))
)
;; function type with params and results
(module
- (type $sub (func (param i32) (result i32)) (extends $super))
-
;; CHECK: (type $super (func (param i32) (result i32)))
(type $super (func (param i32) (result i32)))
- ;; CHECK: (global $g (ref null $super) (ref.null nofunc))
- (global $g (ref null $super) (ref.null $sub))
+ ;; CHECK: (type $sub (func_subtype (param i32) (result i32) $super))
+ (type $sub (func (param i32) (result i32)) (extends $super))
+
+ ;; CHECK: (global $g (ref null $sub) (ref.null nofunc))
+ (global $g (ref null $sub) (ref.null nofunc))
)
;; empty struct type
(module
- (type $sub (struct) (extends $super))
-
;; CHECK: (type $super (struct ))
(type $super (struct))
- ;; CHECK: (global $g (ref null $super) (ref.null none))
- (global $g (ref null $super) (ref.null $sub))
+ ;; CHECK: (type $sub (struct_subtype $super))
+ (type $sub (struct) (extends $super))
+
+ ;; CHECK: (global $g (ref null $sub) (ref.null none))
+ (global $g (ref null $sub) (ref.null none))
)
;; struct type with fields
(module
- (type $sub (struct i32 (field i64)) (extends $super))
-
;; CHECK: (type $super (struct (field i32) (field i64)))
(type $super (struct (field i32) i64))
- ;; CHECK: (global $g (ref null $super) (ref.null none))
- (global $g (ref null $super) (ref.null $sub))
+ ;; CHECK: (type $sub (struct_subtype (field i32) (field i64) $super))
+ (type $sub (struct i32 (field i64)) (extends $super))
+
+ ;; CHECK: (global $g (ref null $sub) (ref.null none))
+ (global $g (ref null $sub) (ref.null none))
)
;; array type
(module
- (type $sub (array i8) (extends $super))
-
;; CHECK: (type $super (array i8))
(type $super (array i8))
- ;; CHECK: (global $g (ref null $super) (ref.null none))
- (global $g (ref null $super) (ref.null $sub))
+ ;; CHECK: (type $sub (array_subtype i8 $super))
+ (type $sub (array i8) (extends $super))
+
+ ;; CHECK: (global $g (ref null $sub) (ref.null none))
+ (global $g (ref null $sub) (ref.null none))
)
diff --git a/test/lit/parse-nominal-types.wast b/test/lit/parse-nominal-types.wast
index 45f110a36..46b27bc58 100644
--- a/test/lit/parse-nominal-types.wast
+++ b/test/lit/parse-nominal-types.wast
@@ -1,62 +1,66 @@
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
;; Test that new-style nominal types are parsed correctly.
-;; TODO: Remove --nominal below once nominal types are parsed as nominal by default.
-;; RUN: foreach %s %t wasm-opt --nominal -all -S -o - | filecheck %s
-;; RUN: foreach %s %t wasm-opt --nominal -all --roundtrip -S -o - | filecheck %s
+;; RUN: foreach %s %t wasm-opt -all -S -o - | filecheck %s
+;; RUN: foreach %s %t wasm-opt -all --roundtrip -S -o - | filecheck %s
;; void function type
(module
- (type $sub (func_subtype $super))
-
;; CHECK: (type $super (func))
(type $super (func_subtype func))
- ;; CHECK: (global $g (ref null $super) (ref.null nofunc))
- (global $g (ref null $super) (ref.null $sub))
+ ;; CHECK: (type $sub (func_subtype $super))
+ (type $sub (func_subtype $super))
+
+ ;; CHECK: (global $g (ref null $sub) (ref.null nofunc))
+ (global $g (ref null $sub) (ref.null nofunc))
)
;; function type with params and results
(module
- (type $sub (func_subtype (param i32) (result i32) $super))
-
;; CHECK: (type $super (func (param i32) (result i32)))
(type $super (func_subtype (param i32) (result i32) func))
- ;; CHECK: (global $g (ref null $super) (ref.null nofunc))
- (global $g (ref null $super) (ref.null $sub))
+ ;; CHECK: (type $sub (func_subtype (param i32) (result i32) $super))
+ (type $sub (func_subtype (param i32) (result i32) $super))
+
+ ;; CHECK: (global $g (ref null $sub) (ref.null nofunc))
+ (global $g (ref null $sub) (ref.null nofunc))
)
;; empty struct type
(module
- (type $sub (struct_subtype $super))
-
;; CHECK: (type $super (struct ))
(type $super (struct_subtype data))
- ;; CHECK: (global $g (ref null $super) (ref.null none))
- (global $g (ref null $super) (ref.null $sub))
+ ;; CHECK: (type $sub (struct_subtype $super))
+ (type $sub (struct_subtype $super))
+
+ ;; CHECK: (global $g (ref null $sub) (ref.null none))
+ (global $g (ref null $sub) (ref.null none))
)
;; struct type with fields
(module
- (type $sub (struct_subtype i32 (field i64) $super))
-
;; CHECK: (type $super (struct (field i32) (field i64)))
(type $super (struct_subtype (field i32) i64 data))
- ;; CHECK: (global $g (ref null $super) (ref.null none))
- (global $g (ref null $super) (ref.null $sub))
+ ;; CHECK: (type $sub (struct_subtype (field i32) (field i64) $super))
+ (type $sub (struct_subtype i32 (field i64) $super))
+
+ ;; CHECK: (global $g (ref null $sub) (ref.null none))
+ (global $g (ref null $sub) (ref.null none))
)
;; array type
(module
- (type $sub (array_subtype i8 $super))
-
;; CHECK: (type $super (array i8))
(type $super (array_subtype i8 data))
- ;; CHECK: (global $g (ref null $super) (ref.null none))
- (global $g (ref null $super) (ref.null $sub))
+ ;; CHECK: (type $sub (array_subtype i8 $super))
+ (type $sub (array_subtype i8 $super))
+
+ ;; CHECK: (global $g (ref null $sub) (ref.null none))
+ (global $g (ref null $sub) (ref.null none))
)
diff --git a/test/lit/passes/abstract-type-refining.wast b/test/lit/passes/abstract-type-refining.wast
index f373acd87..5fffa7972 100644
--- a/test/lit/passes/abstract-type-refining.wast
+++ b/test/lit/passes/abstract-type-refining.wast
@@ -1,7 +1,7 @@
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
-;; RUN: foreach %s %t wasm-opt --abstract-type-refining --traps-never-happen -all --closed-world --nominal -S -o - | filecheck %s --check-prefix=YESTNH
-;; RUN: foreach %s %t wasm-opt --abstract-type-refining -all --closed-world --nominal -S -o - | filecheck %s --check-prefix=NO_TNH
+;; RUN: foreach %s %t wasm-opt --abstract-type-refining --remove-unused-types --traps-never-happen -all --closed-world -S -o - | filecheck %s --check-prefix=YESTNH
+;; RUN: foreach %s %t wasm-opt --abstract-type-refining --remove-unused-types -all --closed-world -S -o - | filecheck %s --check-prefix=NO_TNH
;; Run in both TNH and non-TNH mode.
@@ -11,32 +11,34 @@
;; actually refer to a subtype of them (that has a struct.new). As a result, in
;; TNH mode $A and $D will also not be emitted in the output anymore.
(module
- ;; NO_TNH: (type $anyref_=>_none (func (param anyref)))
+ ;; NO_TNH: (rec
+ ;; NO_TNH-NEXT: (type $none_=>_none (func))
- ;; NO_TNH: (type $A (struct ))
+ ;; NO_TNH: (type $A (struct ))
(type $A (struct))
- ;; YESTNH: (type $B (struct ))
- ;; NO_TNH: (type $B (struct_subtype $A))
- (type $B (struct_subtype $A))
+ ;; YESTNH: (rec
+ ;; YESTNH-NEXT: (type $none_=>_none (func))
- ;; YESTNH: (type $anyref_=>_none (func (param anyref)))
+ ;; YESTNH: (type $B (struct ))
+ ;; NO_TNH: (type $B (struct_subtype $A))
+ (type $B (struct_subtype $A))
- ;; YESTNH: (type $C (struct_subtype $B))
- ;; NO_TNH: (type $C (struct_subtype $B))
+ ;; YESTNH: (type $C (struct_subtype $B))
+ ;; NO_TNH: (type $C (struct_subtype $B))
(type $C (struct_subtype $B))
- ;; NO_TNH: (type $D (struct_subtype $C))
+ ;; NO_TNH: (type $D (struct_subtype $C))
(type $D (struct_subtype $C))
- ;; YESTNH: (type $E (struct_subtype $C))
- ;; NO_TNH: (type $E (struct_subtype $D))
+ ;; YESTNH: (type $E (struct_subtype $C))
+ ;; NO_TNH: (type $E (struct_subtype $D))
(type $E (struct_subtype $D))
- ;; YESTNH: (type $none_=>_none (func))
+ ;; YESTNH: (type $anyref_=>_none (func (param anyref)))
;; YESTNH: (global $global anyref (struct.new_default $B))
- ;; NO_TNH: (type $none_=>_none (func))
+ ;; NO_TNH: (type $anyref_=>_none (func (param anyref)))
;; NO_TNH: (global $global anyref (struct.new_default $B))
(global $global anyref (struct.new $B))
@@ -275,21 +277,27 @@
;; $A has two subtypes. As a result, we cannot optimize it.
(module
- ;; YESTNH: (type $A (struct ))
- ;; NO_TNH: (type $A (struct ))
- (type $A (struct))
+ (rec
+ ;; YESTNH: (rec
+ ;; YESTNH-NEXT: (type $A (struct ))
+ ;; NO_TNH: (rec
+ ;; NO_TNH-NEXT: (type $A (struct ))
+ (type $A (struct))
- ;; YESTNH: (type $B (struct_subtype $A))
- ;; NO_TNH: (type $B (struct_subtype $A))
- (type $B (struct_subtype $A))
+ ;; YESTNH: (type $B1 (struct_subtype $A))
+
+ ;; YESTNH: (type $anyref_=>_none (func (param anyref)))
- ;; YESTNH: (type $anyref_=>_none (func (param anyref)))
+ ;; YESTNH: (type $B (struct_subtype $A))
+ ;; NO_TNH: (type $B1 (struct_subtype $A))
- ;; YESTNH: (type $B1 (struct_subtype $A))
- ;; NO_TNH: (type $anyref_=>_none (func (param anyref)))
+ ;; NO_TNH: (type $anyref_=>_none (func (param anyref)))
- ;; NO_TNH: (type $B1 (struct_subtype $A))
- (type $B1 (struct_subtype $A)) ;; this is a new type
+ ;; NO_TNH: (type $B (struct_subtype $A))
+ (type $B (struct_subtype $A))
+
+ (type $B1 (struct_subtype $A)) ;; this is a new type
+ )
;; YESTNH: (global $global anyref (struct.new_default $B))
;; NO_TNH: (global $global anyref (struct.new_default $B))
@@ -367,24 +375,28 @@
;; As above, but now $B is never created, so we can optimize casts of $A to
;; $B1.
(module
- ;; NO_TNH: (type $anyref_=>_none (func (param anyref)))
-
- ;; NO_TNH: (type $A (struct ))
- (type $A (struct))
+ (rec
+ ;; NO_TNH: (rec
+ ;; NO_TNH-NEXT: (type $A (struct ))
+ (type $A (struct))
- (type $B (struct_subtype $A))
+ (type $B (struct_subtype $A))
- ;; YESTNH: (type $B1 (struct ))
- ;; NO_TNH: (type $B1 (struct_subtype $A))
- (type $B1 (struct_subtype $A)) ;; this is a new type
+ ;; YESTNH: (rec
+ ;; YESTNH-NEXT: (type $B1 (struct ))
+ ;; NO_TNH: (type $B1 (struct_subtype $A))
+ (type $B1 (struct_subtype $A)) ;; this is a new type
+ )
- ;; YESTNH: (type $anyref_=>_none (func (param anyref)))
+ ;; YESTNH: (type $anyref_=>_none (func (param anyref)))
;; YESTNH: (func $new (type $anyref_=>_none) (param $x anyref)
;; YESTNH-NEXT: (drop
;; YESTNH-NEXT: (struct.new_default $B1)
;; YESTNH-NEXT: )
;; YESTNH-NEXT: )
+ ;; NO_TNH: (type $anyref_=>_none (func (param anyref)))
+
;; NO_TNH: (func $new (type $anyref_=>_none) (param $x anyref)
;; NO_TNH-NEXT: (drop
;; NO_TNH-NEXT: (struct.new_default $B1)
@@ -451,25 +463,27 @@
;; A chain, $A :> $B :> $C, where we can optimize $A all the way to $C.
(module
- ;; NO_TNH: (type $anyref_=>_none (func (param anyref)))
-
- ;; NO_TNH: (type $A (struct ))
+ ;; NO_TNH: (rec
+ ;; NO_TNH-NEXT: (type $A (struct ))
(type $A (struct))
- ;; NO_TNH: (type $B (struct_subtype $A))
+ ;; NO_TNH: (type $B (struct_subtype $A))
(type $B (struct_subtype $A))
- ;; YESTNH: (type $C (struct ))
- ;; NO_TNH: (type $C (struct_subtype $B))
+ ;; YESTNH: (rec
+ ;; YESTNH-NEXT: (type $C (struct ))
+ ;; NO_TNH: (type $C (struct_subtype $B))
(type $C (struct_subtype $B))
- ;; YESTNH: (type $anyref_=>_none (func (param anyref)))
+ ;; YESTNH: (type $anyref_=>_none (func (param anyref)))
;; YESTNH: (func $new (type $anyref_=>_none) (param $x anyref)
;; YESTNH-NEXT: (drop
;; YESTNH-NEXT: (struct.new_default $C)
;; YESTNH-NEXT: )
;; YESTNH-NEXT: )
+ ;; NO_TNH: (type $anyref_=>_none (func (param anyref)))
+
;; NO_TNH: (func $new (type $anyref_=>_none) (param $x anyref)
;; NO_TNH-NEXT: (drop
;; NO_TNH-NEXT: (struct.new_default $C)
@@ -537,17 +551,20 @@
;; More testing for cases where no types or subtypes are created. No type is
;; created here. No type needs to be emitted in the output.
(module
- (type $A (struct))
+ (rec
+ (type $A (struct))
- (type $B (struct_subtype $A))
+ (type $B (struct_subtype $A))
- (type $C1 (struct_subtype $B))
+ (type $C1 (struct_subtype $B))
- (type $C2 (struct_subtype $B))
+ (type $C2 (struct_subtype $B))
+ )
- ;; YESTNH: (type $anyref_=>_none (func (param anyref)))
+ ;; YESTNH: (rec
+ ;; YESTNH-NEXT: (type $none_=>_none (func))
- ;; YESTNH: (type $none_=>_none (func))
+ ;; YESTNH: (type $anyref_=>_none (func (param anyref)))
;; YESTNH: (func $ref.cast (type $anyref_=>_none) (param $x anyref)
;; YESTNH-NEXT: (drop
@@ -571,9 +588,10 @@
;; YESTNH-NEXT: )
;; YESTNH-NEXT: )
;; YESTNH-NEXT: )
- ;; NO_TNH: (type $anyref_=>_none (func (param anyref)))
+ ;; NO_TNH: (rec
+ ;; NO_TNH-NEXT: (type $none_=>_none (func))
- ;; NO_TNH: (type $none_=>_none (func))
+ ;; NO_TNH: (type $anyref_=>_none (func (param anyref)))
;; NO_TNH: (func $ref.cast (type $anyref_=>_none) (param $x anyref)
;; NO_TNH-NEXT: (drop
@@ -817,23 +835,27 @@
;; As above, but now $C1 is created.
(module
- ;; NO_TNH: (type $A (struct ))
- (type $A (struct))
+ (rec
+ ;; NO_TNH: (rec
+ ;; NO_TNH-NEXT: (type $anyref_=>_none (func (param anyref)))
- ;; NO_TNH: (type $B (struct_subtype $A))
- (type $B (struct_subtype $A))
+ ;; NO_TNH: (type $A (struct ))
+ (type $A (struct))
- ;; YESTNH: (type $C1 (struct ))
- ;; NO_TNH: (type $C1 (struct_subtype $B))
- (type $C1 (struct_subtype $B))
+ ;; NO_TNH: (type $B (struct_subtype $A))
+ (type $B (struct_subtype $A))
- (type $C2 (struct_subtype $B))
+ ;; YESTNH: (rec
+ ;; YESTNH-NEXT: (type $anyref_=>_none (func (param anyref)))
- ;; YESTNH: (type $anyref_=>_none (func (param anyref)))
+ ;; YESTNH: (type $C1 (struct ))
+ ;; NO_TNH: (type $C1 (struct_subtype $B))
+ (type $C1 (struct_subtype $B))
- ;; YESTNH: (global $global anyref (struct.new_default $C1))
- ;; NO_TNH: (type $anyref_=>_none (func (param anyref)))
+ (type $C2 (struct_subtype $B))
+ )
+ ;; YESTNH: (global $global anyref (struct.new_default $C1))
;; NO_TNH: (global $global anyref (struct.new_default $C1))
(global $global anyref (struct.new $C1))
@@ -978,25 +1000,27 @@
;; Function subtyping, which is a TODO - for now we do nothing.
(module
- ;; YESTNH: (type $A (func))
- ;; NO_TNH: (type $A (func))
+ ;; YESTNH: (rec
+ ;; YESTNH-NEXT: (type $A (func))
+ ;; NO_TNH: (rec
+ ;; NO_TNH-NEXT: (type $A (func))
(type $A (func))
- ;; YESTNH: (type $funcref_=>_none (func (param funcref)))
-
- ;; YESTNH: (type $B (func_subtype $A))
- ;; NO_TNH: (type $funcref_=>_none (func (param funcref)))
-
- ;; NO_TNH: (type $B (func_subtype $A))
+ ;; YESTNH: (type $B (func_subtype $A))
+ ;; NO_TNH: (type $B (func_subtype $A))
(type $B (func_subtype $A))
- ;; YESTNH: (type $C (func_subtype $B))
- ;; NO_TNH: (type $C (func_subtype $B))
+ ;; YESTNH: (type $C (func_subtype $B))
+ ;; NO_TNH: (type $C (func_subtype $B))
(type $C (func_subtype $B))
+ ;; YESTNH: (type $funcref_=>_none (func (param funcref)))
+
;; YESTNH: (func $A (type $A)
;; YESTNH-NEXT: (nop)
;; YESTNH-NEXT: )
+ ;; NO_TNH: (type $funcref_=>_none (func (param funcref)))
+
;; NO_TNH: (func $A (type $A)
;; NO_TNH-NEXT: (nop)
;; NO_TNH-NEXT: )
@@ -1074,16 +1098,20 @@
;; NO_TNH: (type $A (func))
(type $A (func))
- ;; YESTNH: (type $B (func_subtype $A))
- ;; NO_TNH: (type $B (func_subtype $A))
+ ;; YESTNH: (rec
+ ;; YESTNH-NEXT: (type $funcref_=>_none (func (param funcref)))
+
+ ;; YESTNH: (type $B (func_subtype $A))
+ ;; NO_TNH: (rec
+ ;; NO_TNH-NEXT: (type $funcref_=>_none (func (param funcref)))
+
+ ;; NO_TNH: (type $B (func_subtype $A))
(type $B (func_subtype $A))
- ;; YESTNH: (type $C (func_subtype $B))
- ;; NO_TNH: (type $C (func_subtype $B))
+ ;; YESTNH: (type $C (func_subtype $B))
+ ;; NO_TNH: (type $C (func_subtype $B))
(type $C (func_subtype $B))
- ;; YESTNH: (type $funcref_=>_none (func (param funcref)))
-
;; YESTNH: (elem declare func $A $C)
;; YESTNH: (export "A" (func $A))
@@ -1093,8 +1121,6 @@
;; YESTNH-NEXT: (ref.func $A)
;; YESTNH-NEXT: )
;; YESTNH-NEXT: )
- ;; NO_TNH: (type $funcref_=>_none (func (param funcref)))
-
;; NO_TNH: (elem declare func $A $C)
;; NO_TNH: (export "A" (func $A))
@@ -1184,26 +1210,28 @@
;; Array subtyping, which is a TODO - for now we do nothing.
(module
- ;; YESTNH: (type $A (array (mut i32)))
- ;; NO_TNH: (type $A (array (mut i32)))
+ ;; YESTNH: (rec
+ ;; YESTNH-NEXT: (type $anyref_=>_none (func (param anyref)))
+
+ ;; YESTNH: (type $A (array (mut i32)))
+ ;; NO_TNH: (rec
+ ;; NO_TNH-NEXT: (type $anyref_=>_none (func (param anyref)))
+
+ ;; NO_TNH: (type $A (array (mut i32)))
(type $A (array (mut i32)))
- ;; YESTNH: (type $B (array_subtype (mut i32) $A))
- ;; NO_TNH: (type $B (array_subtype (mut i32) $A))
+ ;; YESTNH: (type $B (array_subtype (mut i32) $A))
+ ;; NO_TNH: (type $B (array_subtype (mut i32) $A))
(type $B (array_subtype (mut i32) $A))
- ;; YESTNH: (type $C (array_subtype (mut i32) $B))
- ;; NO_TNH: (type $C (array_subtype (mut i32) $B))
+ ;; YESTNH: (type $C (array_subtype (mut i32) $B))
+ ;; NO_TNH: (type $C (array_subtype (mut i32) $B))
(type $C (array_subtype (mut i32) $B))
- ;; YESTNH: (type $anyref_=>_none (func (param anyref)))
-
;; YESTNH: (global $A (ref $A) (array.new $A
;; YESTNH-NEXT: (i32.const 10)
;; YESTNH-NEXT: (i32.const 20)
;; YESTNH-NEXT: ))
- ;; NO_TNH: (type $anyref_=>_none (func (param anyref)))
-
;; NO_TNH: (global $A (ref $A) (array.new $A
;; NO_TNH-NEXT: (i32.const 10)
;; NO_TNH-NEXT: (i32.const 20)
diff --git a/test/lit/passes/cfp.wast b/test/lit/passes/cfp.wast
index 4647599e0..48b1210b7 100644
--- a/test/lit/passes/cfp.wast
+++ b/test/lit/passes/cfp.wast
@@ -1,5 +1,7 @@
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
-;; RUN: foreach %s %t wasm-opt --nominal --remove-unused-names --cfp -all -S -o - | filecheck %s
+
+;; RUN: foreach %s %t wasm-opt --remove-unused-names --cfp -all -S -o - | filecheck %s
+
;; (remove-unused-names is added to test fallthrough values without a block
;; name getting in the way)
@@ -454,10 +456,10 @@
;; Test a function reference instead of a number.
(module
- ;; CHECK: (type $ref?|$struct|_=>_none (func (param (ref null $struct))))
-
;; CHECK: (type $struct (struct (field funcref)))
(type $struct (struct funcref))
+ ;; CHECK: (type $ref?|$struct|_=>_none (func (param (ref null $struct))))
+
;; CHECK: (elem declare func $test)
;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
@@ -549,11 +551,11 @@
;; CHECK: (type $struct (struct (field i32)))
(type $struct (struct i32))
- ;; CHECK: (type $ref?|$substruct|_=>_none (func (param (ref null $substruct))))
-
;; CHECK: (type $substruct (struct_subtype (field i32) $struct))
(type $substruct (struct_subtype i32 $struct))
+ ;; CHECK: (type $ref?|$substruct|_=>_none (func (param (ref null $substruct))))
+
;; CHECK: (func $create (type $none_=>_none)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
@@ -596,11 +598,11 @@
(type $struct (struct (mut i32)))
;; CHECK: (type $ref?|$struct|_=>_none (func (param (ref null $struct))))
- ;; CHECK: (type $ref?|$substruct|_=>_none (func (param (ref null $substruct))))
-
;; CHECK: (type $substruct (struct_subtype (field (mut i32)) $struct))
(type $substruct (struct_subtype (mut i32) $struct))
+ ;; CHECK: (type $ref?|$substruct|_=>_none (func (param (ref null $substruct))))
+
;; CHECK: (func $create (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new $struct
@@ -651,12 +653,11 @@
;; CHECK: (type $none_=>_none (func))
;; CHECK: (type $struct (struct (field i32)))
+ (type $struct (struct i32))
;; CHECK: (type $substruct (struct_subtype (field i32) (field f64) $struct))
(type $substruct (struct_subtype i32 f64 $struct))
- (type $struct (struct i32))
-
;; CHECK: (type $ref?|$struct|_=>_none (func (param (ref null $struct))))
;; CHECK: (func $create (type $none_=>_none)
@@ -815,13 +816,13 @@
;; shared between the types, but we only create the substruct with
;; one value, so we can optimize.
(module
+
;; CHECK: (type $struct (struct (field i32)))
+ (type $struct (struct i32))
;; CHECK: (type $substruct (struct_subtype (field i32) (field f64) $struct))
(type $substruct (struct_subtype i32 f64 $struct))
- (type $struct (struct i32))
-
;; CHECK: (type $none_=>_none (func))
;; CHECK: (type $ref?|$substruct|_=>_none (func (param (ref null $substruct))))
@@ -939,16 +940,14 @@
;; supertype but all the way as needed.
(module
;; CHECK: (type $struct1 (struct (field i32)))
+ (type $struct1 (struct i32))
;; CHECK: (type $struct2 (struct_subtype (field i32) (field f64) $struct1))
+ (type $struct2 (struct_subtype i32 f64 $struct1))
;; CHECK: (type $struct3 (struct_subtype (field i32) (field f64) (field anyref) $struct2))
(type $struct3 (struct_subtype i32 f64 anyref $struct2))
- (type $struct2 (struct_subtype i32 f64 $struct1))
-
- (type $struct1 (struct i32))
-
;; CHECK: (type $none_=>_none (func))
;; CHECK: (type $ref?|$struct1|_ref?|$struct2|_ref?|$struct3|_=>_none (func (param (ref null $struct1) (ref null $struct2) (ref null $struct3))))
@@ -1076,16 +1075,14 @@
;; not the middle one.
(module
;; CHECK: (type $struct1 (struct (field i32) (field i32)))
+ (type $struct1 (struct i32 i32))
;; CHECK: (type $struct2 (struct_subtype (field i32) (field i32) (field f64) (field f64) $struct1))
+ (type $struct2 (struct_subtype i32 i32 f64 f64 $struct1))
;; CHECK: (type $struct3 (struct_subtype (field i32) (field i32) (field f64) (field f64) (field anyref) (field anyref) $struct2))
(type $struct3 (struct_subtype i32 i32 f64 f64 anyref anyref $struct2))
- (type $struct1 (struct i32 i32))
-
- (type $struct2 (struct_subtype i32 i32 f64 f64 $struct1))
-
;; CHECK: (type $anyref_=>_none (func (param anyref)))
;; CHECK: (type $ref?|$struct1|_ref?|$struct2|_ref?|$struct3|_=>_none (func (param (ref null $struct1) (ref null $struct2) (ref null $struct3))))
@@ -1403,13 +1400,13 @@
;; As above, but add not just a new of the middle class with a different value
;; but also a set. That prevents all optimizations.
(module
+
;; CHECK: (type $struct1 (struct (field (mut i32))))
+ (type $struct1 (struct (mut i32)))
;; CHECK: (type $struct2 (struct_subtype (field (mut i32)) (field f64) $struct1))
(type $struct2 (struct_subtype (mut i32) f64 $struct1))
- (type $struct1 (struct (mut i32)))
-
;; CHECK: (type $struct3 (struct_subtype (field (mut i32)) (field f64) (field anyref) $struct2))
(type $struct3 (struct_subtype (mut i32) f64 anyref $struct2))
@@ -1631,16 +1628,14 @@
;; apply to it, preventing optimization.
(module
;; CHECK: (type $A (struct (field (mut i32))))
+ (type $A (struct (mut i32)))
;; CHECK: (type $B (struct_subtype (field (mut i32)) $A))
+ (type $B (struct_subtype (mut i32) $A))
;; CHECK: (type $C (struct_subtype (field (mut i32)) $B))
(type $C (struct_subtype (mut i32) $B))
- (type $A (struct (mut i32)))
-
- (type $B (struct_subtype (mut i32) $A))
-
;; CHECK: (type $none_=>_none (func))
;; CHECK: (type $ref|$A|_=>_none (func (param (ref $A))))
@@ -1748,11 +1743,11 @@
(module
;; CHECK: (type $struct (struct (field (mut f32)) (field (mut i32))))
(type $struct (struct (mut f32) (mut i32)))
- ;; CHECK: (type $ref?|$struct|_ref?|$other|_=>_none (func (param (ref null $struct) (ref null $other))))
-
;; CHECK: (type $other (struct (field (mut f64)) (field (mut i32))))
(type $other (struct (mut f64) (mut i32)))
+ ;; CHECK: (type $ref?|$struct|_ref?|$other|_=>_none (func (param (ref null $struct) (ref null $other))))
+
;; CHECK: (func $test (type $ref?|$struct|_ref?|$other|_=>_none) (param $struct (ref null $struct)) (param $other (ref null $other))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.new_default $struct)
@@ -2064,11 +2059,10 @@
;; Test a global type other than i32. Arrays of structs are a realistic case
;; as they are used to implement itables.
- ;; CHECK: (type $itable (array (ref $vtable)))
-
;; CHECK: (type $vtable (struct (field funcref)))
(type $vtable (struct funcref))
+ ;; CHECK: (type $itable (array (ref $vtable)))
(type $itable (array (ref $vtable)))
;; CHECK: (type $object (struct (field $itable (ref $itable))))
@@ -2138,14 +2132,17 @@
;; Test we handle packed fields properly.
(module
- ;; CHECK: (type $none_=>_none (func))
-
- ;; CHECK: (type $A_8 (struct (field i8)))
- (type $A_8 (struct (field i8)))
- ;; CHECK: (type $A_16 (struct (field i16)))
- (type $A_16 (struct (field i16)))
- ;; CHECK: (type $B_16 (struct (field i16)))
- (type $B_16 (struct (field i16)))
+ (rec
+ ;; CHECK: (type $none_=>_none (func))
+
+ ;; CHECK: (rec
+ ;; CHECK-NEXT: (type $A_8 (struct (field i8)))
+ (type $A_8 (struct (field i8)))
+ ;; CHECK: (type $A_16 (struct (field i16)))
+ (type $A_16 (struct (field i16)))
+ ;; CHECK: (type $B_16 (struct (field i16)))
+ (type $B_16 (struct (field i16)))
+ )
;; CHECK: (import "a" "b" (global $g i32))
(import "a" "b" (global $g i32))
diff --git a/test/lit/nominal-chain.wast b/test/lit/subtype-chain.wast
index 7a1b3c933..03d0ec81f 100644
--- a/test/lit/nominal-chain.wast
+++ b/test/lit/subtype-chain.wast
@@ -1,6 +1,6 @@
;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
-;; RUN: wasm-opt %s -all --nominal -S -o - | filecheck %s
-;; RUN: wasm-opt %s -all --nominal --roundtrip -S -o - | filecheck %s
+;; RUN: wasm-opt %s -all -S -o - | filecheck %s
+;; RUN: wasm-opt %s -all --roundtrip -S -o - | filecheck %s
;; Check that intermediate types in subtype chains are also included in the
;; output module, even if there are no other references to those intermediate
@@ -16,15 +16,15 @@
;; CHECK: (type $twig (struct_subtype (field i32) (field i64) (field f32) $branch))
;; CHECK: (type $leaf (struct_subtype (field i32) (field i64) (field f32) (field f64) $twig))
- (type $leaf (struct_subtype i32 i64 f32 f64 $twig))
+ (type $root (struct))
- (type $twig (struct_subtype i32 i64 f32 $branch))
+ (type $trunk (struct_subtype i32 $root))
(type $branch (struct_subtype i32 i64 $trunk))
- (type $trunk (struct_subtype i32 $root))
+ (type $twig (struct_subtype i32 i64 f32 $branch))
- (type $root (struct))
+ (type $leaf (struct_subtype i32 i64 f32 f64 $twig))
;; CHECK: (func $make-root (type $ref|$leaf|_=>_ref?|$root|) (param $leaf (ref $leaf)) (result (ref null $root))
;; CHECK-NEXT: (local.get $leaf)
diff --git a/test/lit/subtypes.wast b/test/lit/subtypes.wast
new file mode 100644
index 000000000..75618ab0a
--- /dev/null
+++ b/test/lit/subtypes.wast
@@ -0,0 +1,72 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
+
+;; RUN: wasm-opt %s -all --hybrid -S -o - | filecheck %s
+;; RUN: wasm-opt %s -all --hybrid --roundtrip -S -o - | filecheck %s
+
+(module
+ (rec
+ ;; CHECK: (rec
+ ;; CHECK-NEXT: (type $super-struct (struct (field i32)))
+ (type $super-struct (struct i32))
+ ;; CHECK: (type $sub-struct (struct_subtype (field i32) (field i64) $super-struct))
+ (type $sub-struct (struct_subtype i32 i64 $super-struct))
+ )
+
+ (rec
+ ;; CHECK: (rec
+ ;; CHECK-NEXT: (type $super-array (array (ref $super-struct)))
+ (type $super-array (array (ref $super-struct)))
+ ;; CHECK: (type $sub-array (array_subtype (ref $sub-struct) $super-array))
+ (type $sub-array (array_subtype (ref $sub-struct) $super-array))
+ )
+
+ (rec
+ ;; CHECK: (rec
+ ;; CHECK-NEXT: (type $super-func (func (param (ref $sub-array)) (result (ref $super-array))))
+ (type $super-func (func (param (ref $sub-array)) (result (ref $super-array))))
+ ;; CHECK: (type $sub-func (func_subtype (param (ref $super-array)) (result (ref $sub-array)) $super-func))
+ (type $sub-func (func_subtype (param (ref $super-array)) (result (ref $sub-array)) $super-func))
+ )
+
+ ;; CHECK: (func $make-super-struct (type $none_=>_ref|$super-struct|) (result (ref $super-struct))
+ ;; CHECK-NEXT: (call $make-sub-struct)
+ ;; CHECK-NEXT: )
+ (func $make-super-struct (result (ref $super-struct))
+ (call $make-sub-struct)
+ )
+
+ ;; CHECK: (func $make-sub-struct (type $none_=>_ref|$sub-struct|) (result (ref $sub-struct))
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $make-sub-struct (result (ref $sub-struct))
+ (unreachable)
+ )
+
+ ;; CHECK: (func $make-super-array (type $none_=>_ref|$super-array|) (result (ref $super-array))
+ ;; CHECK-NEXT: (call $make-sub-array)
+ ;; CHECK-NEXT: )
+ (func $make-super-array (result (ref $super-array))
+ (call $make-sub-array)
+ )
+
+ ;; CHECK: (func $make-sub-array (type $none_=>_ref|$sub-array|) (result (ref $sub-array))
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $make-sub-array (result (ref $sub-array))
+ (unreachable)
+ )
+
+ ;; CHECK: (func $make-super-func (type $none_=>_ref|$super-func|) (result (ref $super-func))
+ ;; CHECK-NEXT: (call $make-sub-func)
+ ;; CHECK-NEXT: )
+ (func $make-super-func (result (ref $super-func))
+ (call $make-sub-func)
+ )
+
+ ;; CHECK: (func $make-sub-func (type $none_=>_ref|$sub-func|) (result (ref $sub-func))
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $make-sub-func (result (ref $sub-func))
+ (unreachable)
+ )
+)