diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2021-08-02 12:06:51 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-02 09:06:51 -0700 |
commit | 7835f7d4d4d2d0118ba40b9f60fb32de8a43c272 (patch) | |
tree | d9f8afe0dacc3887a440870280d2a388de0c91b6 | |
parent | f35f02c1ce1b3129aa83d2dddeababd414c1ca8f (diff) | |
download | binaryen-7835f7d4d4d2d0118ba40b9f60fb32de8a43c272.tar.gz binaryen-7835f7d4d4d2d0118ba40b9f60fb32de8a43c272.tar.bz2 binaryen-7835f7d4d4d2d0118ba40b9f60fb32de8a43c272.zip |
Test GC lit tests with --nominal as well (#4043)
Add a new run line to every list test containing a struct type to run the test
again with nominal typing. In cases where tests do not use any struct subtyping,
this does not change the test output. In cases where struct subtyping is used, a
new check prefix is introduced to capture the difference that `(extends ...)`
clauses are emitted in nominal mode but not in equirecursive mode. There are no
other test differences.
Some tests are cleaned up along the way. Notably,
O_all-features{,-ignore-implicit-traps}.wast is consolidated to a single file.
26 files changed, 561 insertions, 83 deletions
diff --git a/src/ir/module-utils.h b/src/ir/module-utils.h index 2cbab414b..d916f51a2 100644 --- a/src/ir/module-utils.h +++ b/src/ir/module-utils.h @@ -569,8 +569,12 @@ inline void collectHeapTypes(Module& wasm, if (ht.getSuperType(super)) { if (!counts.count(super)) { newTypes.insert(super); + // We should unconditionally count supertypes, but while the type system + // is in flux, skip counting them to keep the type orderings in nominal + // test outputs more similar to the orderings in the equirecursive + // outputs. FIXME + counts.note(super); } - counts.note(super); } } diff --git a/test/lit/forward-declared-types.wast b/test/lit/forward-declared-types.wast index 215838621..f7d3592cc 100644 --- a/test/lit/forward-declared-types.wast +++ b/test/lit/forward-declared-types.wast @@ -2,6 +2,7 @@ ;; Test that types can be used before they are defined ;; RUN: wasm-opt %s -all -S -o - | filecheck %s +;; RUN: wasm-opt %s -all --nominal -S -o - | filecheck %s (module ;; CHECK: (type $func (func)) diff --git a/test/lit/gc-eh.wast b/test/lit/gc-eh.wast index 808060df1..07e2f18b7 100644 --- a/test/lit/gc-eh.wast +++ b/test/lit/gc-eh.wast @@ -3,6 +3,7 @@ ;; 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 (module ;; CHECK: (type $A (struct (field (mut i32)))) diff --git a/test/lit/gc-read-write-effects.wast b/test/lit/gc-read-write-effects.wast index 6ebdd9b06..d22702b79 100644 --- a/test/lit/gc-read-write-effects.wast +++ b/test/lit/gc-read-write-effects.wast @@ -4,6 +4,7 @@ ;; 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 (module ;; CHECK: (type $A (struct (field (mut i32)))) diff --git a/test/lit/lub-bug-3843.wast b/test/lit/lub-bug-3843.wast index 897149502..67bcecb39 100644 --- a/test/lit/lub-bug-3843.wast +++ b/test/lit/lub-bug-3843.wast @@ -1,5 +1,6 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. ;; RUN: wasm-opt %s -all --precompute -S -o - | filecheck %s +;; RUN: wasm-opt %s -all --precompute --nominal -S -o - | filecheck %s --check-prefix NOMNL ;; Regression test for a bug (#3843) in which the LUB calculation done during ;; the refinalization of the select incorrectly produced a new type rather than @@ -7,16 +8,21 @@ (module ;; CHECK: (type $A (struct (field (ref null $C)))) + ;; NOMNL: (type $A (struct (field (ref null $C)))) (type $A (struct (field (ref null $C)))) ;; CHECK: (type $B (struct (field (ref null $D)))) - (type $B (struct (field (ref null $D)))) + ;; NOMNL: (type $B (struct (field (ref null $D))) (extends $A)) + (type $B (struct (field (ref null $D))) (extends $A)) ;; CHECK: (type $D (struct (field (mut (ref $A))) (field (mut (ref $A))))) + ;; NOMNL: (type $D (struct (field (mut (ref $A))) (field (mut (ref $A)))) (extends $C)) + (type $D (struct (field (mut (ref $A))) (field (mut (ref $A)))) (extends $C)) ;; CHECK: (type $C (struct (field (mut (ref $A))))) + ;; NOMNL: (type $C (struct (field (mut (ref $A))))) (type $C (struct (field (mut (ref $A))))) - (type $D (struct (field (mut (ref $A))) (field (mut (ref $A))))) + ;; CHECK: (func $foo (param $a (ref null $A)) (result (ref null $A)) ;; CHECK-NEXT: (select (result (ref null $A)) @@ -25,6 +31,13 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $foo (param $a (ref null $A)) (result (ref null $A)) + ;; NOMNL-NEXT: (select (result (ref null $A)) + ;; NOMNL-NEXT: (local.get $a) + ;; NOMNL-NEXT: (ref.null $B) + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $foo (param $a (ref null $A)) (result (ref null $A)) ;; the select should have type $A (select (result (ref null $A)) diff --git a/test/lit/nominal-chain.wast b/test/lit/nominal-chain.wast index bf190d878..7b9c96d9c 100644 --- a/test/lit/nominal-chain.wast +++ b/test/lit/nominal-chain.wast @@ -7,11 +7,11 @@ ;; types. (module - ;; CHECK: (type $root (struct )) - ;; CHECK: (type $leaf (struct (field i32) (field i64) (field f32) (field f64)) (extends $twig)) (type $leaf (struct i32 i64 f32 f64) (extends $twig)) + ;; CHECK: (type $root (struct )) + ;; CHECK: (type $twig (struct (field i32) (field i64) (field f32)) (extends $branch)) (type $twig (struct i32 i64 f32) (extends $branch)) diff --git a/test/lit/passes/O4_disable-bulk-memory.wast b/test/lit/passes/O4_disable-bulk-memory.wast index 279d4b531..aec1030bb 100644 --- a/test/lit/passes/O4_disable-bulk-memory.wast +++ b/test/lit/passes/O4_disable-bulk-memory.wast @@ -3025,4 +3025,3 @@ (func $null (; 27 ;) (type $0) ) ) - diff --git a/test/lit/passes/O_all-features.wast b/test/lit/passes/O_all-features.wast deleted file mode 100644 index dc538e952..000000000 --- a/test/lit/passes/O_all-features.wast +++ /dev/null @@ -1,33 +0,0 @@ -;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; NOTE: This test was ported using port_test.py and could be cleaned up. - -;; RUN: foreach %s %t wasm-opt -O --all-features -S -o - | filecheck %s - -;; Test that we can run GC types through the optimizer -(module - ;; CHECK: (type $struct.A (struct (field i32))) - (type $struct.A (struct i32)) - - (func "foo" (param $x (ref null $struct.A)) - ;; get a struct reference - (drop - (local.get $x) - ) - ;; get a struct field value - ;; (note that since this is a nullable reference, it may trap) - (drop - (struct.get $struct.A 0 (local.get $x)) - ) - ) -) -;; CHECK: (type $ref?|$struct.A|_=>_none (func (param (ref null $struct.A)))) - -;; CHECK: (export "foo" (func $0)) - -;; CHECK: (func $0 (; has Stack IR ;) (param $0 (ref null $struct.A)) -;; CHECK-NEXT: (drop -;; CHECK-NEXT: (struct.get $struct.A 0 -;; CHECK-NEXT: (local.get $0) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) -;; CHECK-NEXT: ) diff --git a/test/lit/passes/O_all-features_ignore-implicit-traps.wast b/test/lit/passes/O_all-features_ignore-implicit-traps.wast deleted file mode 100644 index 1a7d431f1..000000000 --- a/test/lit/passes/O_all-features_ignore-implicit-traps.wast +++ /dev/null @@ -1,30 +0,0 @@ -;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; NOTE: This test was ported using port_test.py and could be cleaned up. - -;; RUN: foreach %s %t wasm-opt -O --all-features --ignore-implicit-traps -S -o - | filecheck %s - -;; Test that we can run GC types through the optimizer -(module - ;; CHECK: (type $ref?|$struct.A|_=>_none (func (param (ref null $struct.A)))) - - ;; CHECK: (type $struct.A (struct (field i32))) - (type $struct.A (struct i32)) - - (func "foo" (param $x (ref null $struct.A)) - ;; get a struct reference - (drop - (local.get $x) - ) - ;; get a struct field value - ;; (note that since this is a nullable reference, it may trap, but we - ;; are ignoring implicit traps, so it has no side effects) - (drop - (struct.get $struct.A 0 (local.get $x)) - ) - ) -) -;; CHECK: (export "foo" (func $0)) - -;; CHECK: (func $0 (; has Stack IR ;) (param $0 (ref null $struct.A)) -;; CHECK-NEXT: (nop) -;; CHECK-NEXT: ) diff --git a/test/lit/passes/O_gc.wast b/test/lit/passes/O_gc.wast new file mode 100644 index 000000000..5e8541471 --- /dev/null +++ b/test/lit/passes/O_gc.wast @@ -0,0 +1,43 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt %s -O --all-features -S -o - | filecheck %s +;; RUN: wasm-opt %s -O --all-features --nominal -S -o - | filecheck %s +;; RUN: wasm-opt %s -O --all-features --ignore-implicit-traps -S -o - | filecheck %s --check-prefix=IGNORE-TRAPS +;; RUN: wasm-opt %s -O --all-features --ignore-implicit-traps --nominal -S -o - | filecheck %s --check-prefix=IGNORE-TRAPS + +;; Test that we can run GC types through the optimizer +(module + ;; CHECK: (type $struct.A (struct (field i32))) + ;; IGNORE-TRAPS: (type $ref?|$struct.A|_=>_none (func (param (ref null $struct.A)))) + + ;; IGNORE-TRAPS: (type $struct.A (struct (field i32))) + (type $struct.A (struct i32)) + + ;; CHECK: (type $ref?|$struct.A|_=>_none (func (param (ref null $struct.A)))) + + ;; CHECK: (export "foo" (func $foo)) + ;; IGNORE-TRAPS: (export "foo" (func $foo)) + (export "foo" (func $foo)) + + ;; CHECK: (func $foo (; has Stack IR ;) (param $0 (ref null $struct.A)) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $struct.A 0 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; IGNORE-TRAPS: (func $foo (; has Stack IR ;) (param $0 (ref null $struct.A)) + ;; IGNORE-TRAPS-NEXT: (nop) + ;; IGNORE-TRAPS-NEXT: ) + (func $foo (param $x (ref null $struct.A)) + ;; get a struct reference + (drop + (local.get $x) + ) + ;; get a struct field value + ;; (note that since this is a nullable reference, it may trap) + (drop + (struct.get $struct.A 0 (local.get $x)) + ) + ) +) diff --git a/test/lit/passes/dae-gc-refine-params.wast b/test/lit/passes/dae-gc-refine-params.wast index 47ae2d2e5..f4d4ab056 100644 --- a/test/lit/passes/dae-gc-refine-params.wast +++ b/test/lit/passes/dae-gc-refine-params.wast @@ -1,21 +1,27 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. ;; RUN: wasm-opt %s -all --dae -S -o - | filecheck %s +;; RUN: wasm-opt %s -all --dae --nominal -S -o - | filecheck %s --check-prefix NOMNL (module ;; CHECK: (type ${i32} (struct (field i32))) - (type ${i32} (struct (field i32))) + ;; NOMNL: (type ${i32} (struct (field i32)) (extends ${})) + (type ${i32} (struct (field i32)) (extends ${})) ;; CHECK: (type ${} (struct )) + ;; NOMNL: (type ${} (struct )) (type ${} (struct)) ;; CHECK: (type ${i32_i64} (struct (field i32) (field i64))) - (type ${i32_i64} (struct (field i32) (field i64))) + ;; NOMNL: (type ${i32_i64} (struct (field i32) (field i64)) (extends ${i32})) + (type ${i32_i64} (struct (field i32) (field i64)) (extends ${i32})) ;; CHECK: (type ${f64} (struct (field f64))) - (type ${f64} (struct (field f64))) + ;; NOMNL: (type ${f64} (struct (field f64)) (extends ${})) + (type ${f64} (struct (field f64)) (extends ${})) ;; CHECK: (type ${i32_f32} (struct (field i32) (field f32))) - (type ${i32_f32} (struct (field i32) (field f32))) + ;; NOMNL: (type ${i32_f32} (struct (field i32) (field f32)) (extends ${i32})) + (type ${i32_f32} (struct (field i32) (field f32)) (extends ${i32})) ;; CHECK: (func $call-various-params-no ;; CHECK-NEXT: (call $various-params-no @@ -27,6 +33,16 @@ ;; CHECK-NEXT: (ref.null ${f64}) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $call-various-params-no + ;; NOMNL-NEXT: (call $various-params-no + ;; NOMNL-NEXT: (ref.null ${}) + ;; NOMNL-NEXT: (ref.null ${i32}) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (call $various-params-no + ;; NOMNL-NEXT: (ref.null ${i32}) + ;; NOMNL-NEXT: (ref.null ${f64}) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $call-various-params-no ;; The first argument gets {} and {i32}; the second {i32} and {f64}; none of ;; those pairs can be optimized. @@ -49,6 +65,14 @@ ;; CHECK-NEXT: (local.get $y) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $various-params-no (param $x (ref null ${})) (param $y (ref null ${})) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (local.get $x) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (local.get $y) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $various-params-no (param $x (ref null ${})) (param $y (ref null ${})) ;; "Use" the locals to avoid other optimizations kicking in. (drop (local.get $x)) @@ -67,6 +91,18 @@ ;; CHECK-NEXT: (ref.null ${i32_i64}) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $call-various-params-yes + ;; NOMNL-NEXT: (call $various-params-yes + ;; NOMNL-NEXT: (ref.null ${i32}) + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: (ref.null ${i32}) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (call $various-params-yes + ;; NOMNL-NEXT: (ref.null ${i32}) + ;; NOMNL-NEXT: (i32.const 1) + ;; NOMNL-NEXT: (ref.null ${i32_i64}) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $call-various-params-yes ;; The first argument gets {i32} and {i32}; the second {i32} and {i32_i64}; ;; both of those pairs can be optimized to {i32}. @@ -95,6 +131,17 @@ ;; CHECK-NEXT: (local.get $y) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $various-params-yes (param $x (ref null ${i32})) (param $i i32) (param $y (ref null ${i32})) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (local.get $x) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (local.get $i) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (local.get $y) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $various-params-yes (param $x (ref null ${})) (param $i i32) (param $y (ref null ${})) ;; "Use" the locals to avoid other optimizations kicking in. (drop (local.get $x)) @@ -112,6 +159,16 @@ ;; CHECK-NEXT: (ref.null ${i32_i64}) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $call-various-params-set + ;; NOMNL-NEXT: (call $various-params-set + ;; NOMNL-NEXT: (ref.null ${i32}) + ;; NOMNL-NEXT: (ref.null ${i32}) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (call $various-params-set + ;; NOMNL-NEXT: (ref.null ${i32}) + ;; NOMNL-NEXT: (ref.null ${i32_i64}) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $call-various-params-set ;; The first argument gets {i32} and {i32}; the second {i32} and {i32_i64; ;; both of those pairs can be optimized to {i32} @@ -141,6 +198,20 @@ ;; CHECK-NEXT: (ref.null ${i32_i64}) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $various-params-set (param $x (ref null ${})) (param $y (ref null ${i32})) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (local.get $x) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (local.get $y) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $x + ;; NOMNL-NEXT: (ref.null ${}) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $y + ;; NOMNL-NEXT: (ref.null ${i32_i64}) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $various-params-set (param $x (ref null ${})) (param $y (ref null ${})) ;; "Use" the locals to avoid other optimizations kicking in. (drop (local.get $x)) @@ -156,6 +227,11 @@ ;; CHECK-NEXT: (ref.null ${i32}) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $call-various-params-tee + ;; NOMNL-NEXT: (call $various-params-tee + ;; NOMNL-NEXT: (ref.null ${i32}) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $call-various-params-tee ;; The argument gets {i32}, which allows us to refine. (call $various-params-tee @@ -174,6 +250,18 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $various-params-tee (param $x (ref null ${i32})) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (local.get $x) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block $block (result (ref null ${i32})) + ;; NOMNL-NEXT: (local.tee $x + ;; NOMNL-NEXT: (ref.null ${i32_i64}) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $various-params-tee (param $x (ref null ${})) ;; "Use" the locals to avoid other optimizations kicking in. (drop (local.get $x)) @@ -203,6 +291,22 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $call-various-params-null + ;; NOMNL-NEXT: (call $various-params-null + ;; NOMNL-NEXT: (ref.as_non_null + ;; NOMNL-NEXT: (ref.null ${i32}) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null ${i32}) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (call $various-params-null + ;; NOMNL-NEXT: (ref.as_non_null + ;; NOMNL-NEXT: (ref.null ${i32}) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.as_non_null + ;; NOMNL-NEXT: (ref.null ${i32}) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $call-various-params-null ;; The first argument gets non-null values, allowing us to refine it. The ;; second gets only one. @@ -229,6 +333,18 @@ ;; CHECK-NEXT: (local.get $temp) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $various-params-null (param $x (ref ${i32})) (param $y (ref null ${i32})) + ;; NOMNL-NEXT: (local $temp i32) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (local.get $x) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (local.get $y) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $temp + ;; NOMNL-NEXT: (local.get $temp) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $various-params-null (param $x (ref null ${})) (param $y (ref null ${})) (local $temp i32) ;; "Use" the locals to avoid other optimizations kicking in. @@ -249,6 +365,14 @@ ;; CHECK-NEXT: (ref.null ${i32_f32}) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $call-various-params-middle + ;; NOMNL-NEXT: (call $various-params-middle + ;; NOMNL-NEXT: (ref.null ${i32_i64}) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (call $various-params-middle + ;; NOMNL-NEXT: (ref.null ${i32_f32}) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $call-various-params-middle ;; The argument gets {i32_i64} and {i32_f32}. This allows us to refine from ;; {} to {i32}, a type "in the middle". @@ -264,6 +388,11 @@ ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $various-params-middle (param $x (ref null ${i32})) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (local.get $x) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $various-params-middle (param $x (ref null ${})) ;; "Use" the local to avoid other optimizations kicking in. (drop (local.get $x)) diff --git a/test/lit/passes/dae-gc-refine-return.wast b/test/lit/passes/dae-gc-refine-return.wast index 128b5fbcf..73f1d040f 100644 --- a/test/lit/passes/dae-gc-refine-return.wast +++ b/test/lit/passes/dae-gc-refine-return.wast @@ -1,20 +1,26 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. ;; RUN: wasm-opt %s -all --dae -S -o - | filecheck %s +;; RUN: wasm-opt %s -all --dae --nominal -S -o - | filecheck %s --check-prefix NOMNL (module ;; CHECK: (type $return_{} (func (result (ref ${})))) + ;; NOMNL: (type $return_{} (func (result (ref ${})))) (type $return_{} (func (result (ref ${})))) ;; CHECK: (type ${i32_f32} (struct (field i32) (field f32))) - (type ${i32_f32} (struct (field i32) (field f32))) + ;; NOMNL: (type ${i32_f32} (struct (field i32) (field f32)) (extends ${i32})) + (type ${i32_f32} (struct (field i32) (field f32)) (extends ${i32})) ;; CHECK: (type ${i32_i64} (struct (field i32) (field i64))) - (type ${i32_i64} (struct (field i32) (field i64))) + ;; NOMNL: (type ${i32_i64} (struct (field i32) (field i64)) (extends ${i32})) + (type ${i32_i64} (struct (field i32) (field i64)) (extends ${i32})) ;; CHECK: (type ${i32} (struct (field i32))) - (type ${i32} (struct (field i32))) + ;; NOMNL: (type ${i32} (struct (field i32)) (extends ${})) + (type ${i32} (struct (field i32)) (extends ${})) ;; CHECK: (type ${} (struct )) + ;; NOMNL: (type ${} (struct )) (type ${} (struct)) (table 1 1 funcref) @@ -27,6 +33,13 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) + ;; NOMNL: (func $refine-return-no-return (result anyref) + ;; NOMNL-NEXT: (local $temp anyref) + ;; NOMNL-NEXT: (local.set $temp + ;; NOMNL-NEXT: (call $refine-return-no-return) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (unreachable) + ;; NOMNL-NEXT: ) (func $refine-return-no-return (result anyref) ;; Call this function, so that we attempt to optimize it. Note that we do not ;; just drop the result, as that would cause the drop optimizations to kick @@ -45,6 +58,13 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (ref.null any) ;; CHECK-NEXT: ) + ;; NOMNL: (func $refine-return-no-refining (result anyref) + ;; NOMNL-NEXT: (local $temp anyref) + ;; NOMNL-NEXT: (local.set $temp + ;; NOMNL-NEXT: (call $refine-return-no-refining) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null any) + ;; NOMNL-NEXT: ) (func $refine-return-no-refining (result anyref) (local $temp anyref) (local.set $temp (call $refine-return-no-refining)) @@ -60,6 +80,13 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (ref.null func) ;; CHECK-NEXT: ) + ;; NOMNL: (func $refine-return-flow (result funcref) + ;; NOMNL-NEXT: (local $temp anyref) + ;; NOMNL-NEXT: (local.set $temp + ;; NOMNL-NEXT: (call $refine-return-flow) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null func) + ;; NOMNL-NEXT: ) (func $refine-return-flow (result anyref) (local $temp anyref) (local.set $temp (call $refine-return-flow)) @@ -77,6 +104,17 @@ ;; CHECK-NEXT: (call $refine-return-flow) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $call-refine-return-flow (result funcref) + ;; NOMNL-NEXT: (local $temp anyref) + ;; NOMNL-NEXT: (local.set $temp + ;; NOMNL-NEXT: (call $call-refine-return-flow) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (if (result funcref) + ;; NOMNL-NEXT: (i32.const 1) + ;; NOMNL-NEXT: (call $refine-return-flow) + ;; NOMNL-NEXT: (call $refine-return-flow) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $call-refine-return-flow (result anyref) (local $temp anyref) (local.set $temp (call $call-refine-return-flow)) @@ -101,6 +139,15 @@ ;; CHECK-NEXT: (ref.null func) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $refine-return-return (result funcref) + ;; NOMNL-NEXT: (local $temp anyref) + ;; NOMNL-NEXT: (local.set $temp + ;; NOMNL-NEXT: (call $refine-return-return) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (return + ;; NOMNL-NEXT: (ref.null func) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $refine-return-return (result anyref) (local $temp anyref) (local.set $temp (call $refine-return-return)) @@ -128,6 +175,25 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (ref.null func) ;; CHECK-NEXT: ) + ;; NOMNL: (func $refine-return-many (result funcref) + ;; NOMNL-NEXT: (local $temp anyref) + ;; NOMNL-NEXT: (local.set $temp + ;; NOMNL-NEXT: (call $refine-return-many) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (if + ;; NOMNL-NEXT: (i32.const 1) + ;; NOMNL-NEXT: (return + ;; NOMNL-NEXT: (ref.null func) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (if + ;; NOMNL-NEXT: (i32.const 2) + ;; NOMNL-NEXT: (return + ;; NOMNL-NEXT: (ref.null func) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null func) + ;; NOMNL-NEXT: ) (func $refine-return-many (result anyref) (local $temp anyref) (local.set $temp (call $refine-return-many)) @@ -162,6 +228,25 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (ref.null func) ;; CHECK-NEXT: ) + ;; NOMNL: (func $refine-return-many-blocked (result anyref) + ;; NOMNL-NEXT: (local $temp anyref) + ;; NOMNL-NEXT: (local.set $temp + ;; NOMNL-NEXT: (call $refine-return-many-blocked) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (if + ;; NOMNL-NEXT: (i32.const 1) + ;; NOMNL-NEXT: (return + ;; NOMNL-NEXT: (ref.null func) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (if + ;; NOMNL-NEXT: (i32.const 2) + ;; NOMNL-NEXT: (return + ;; NOMNL-NEXT: (ref.null data) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null func) + ;; NOMNL-NEXT: ) (func $refine-return-many-blocked (result anyref) (local $temp anyref) (local.set $temp (call $refine-return-many-blocked)) @@ -197,6 +282,25 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (ref.null data) ;; CHECK-NEXT: ) + ;; NOMNL: (func $refine-return-many-blocked-2 (result anyref) + ;; NOMNL-NEXT: (local $temp anyref) + ;; NOMNL-NEXT: (local.set $temp + ;; NOMNL-NEXT: (call $refine-return-many-blocked-2) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (if + ;; NOMNL-NEXT: (i32.const 1) + ;; NOMNL-NEXT: (return + ;; NOMNL-NEXT: (ref.null func) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (if + ;; NOMNL-NEXT: (i32.const 2) + ;; NOMNL-NEXT: (return + ;; NOMNL-NEXT: (ref.null func) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null data) + ;; NOMNL-NEXT: ) (func $refine-return-many-blocked-2 (result anyref) (local $temp anyref) (local.set $temp (call $refine-return-many-blocked-2)) @@ -226,6 +330,19 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (ref.null ${i32_f32}) ;; CHECK-NEXT: ) + ;; NOMNL: (func $refine-return-many-middle (result (ref null ${i32})) + ;; NOMNL-NEXT: (local $temp anyref) + ;; NOMNL-NEXT: (local.set $temp + ;; NOMNL-NEXT: (call $refine-return-many-middle) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (if + ;; NOMNL-NEXT: (i32.const 1) + ;; NOMNL-NEXT: (return + ;; NOMNL-NEXT: (ref.null ${i32_i64}) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null ${i32_f32}) + ;; NOMNL-NEXT: ) (func $refine-return-many-middle (result anyref) (local $temp anyref) (local.set $temp (call $refine-return-many-middle)) @@ -252,6 +369,18 @@ ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $refine-return-tuple (result funcref i32) + ;; NOMNL-NEXT: (local $temp anyref) + ;; NOMNL-NEXT: (local.set $temp + ;; NOMNL-NEXT: (tuple.extract 0 + ;; NOMNL-NEXT: (call $refine-return-tuple) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (tuple.make + ;; NOMNL-NEXT: (ref.null func) + ;; NOMNL-NEXT: (i32.const 1) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $refine-return-tuple (result anyref i32) (local $temp anyref) (local.set $temp @@ -273,12 +402,18 @@ ;; CHECK: (func $do-return-call (result funcref) ;; CHECK-NEXT: (return_call $return-ref-func) ;; CHECK-NEXT: ) + ;; NOMNL: (func $do-return-call (result funcref) + ;; NOMNL-NEXT: (return_call $return-ref-func) + ;; NOMNL-NEXT: ) (func $do-return-call (result funcref) (return_call $return-ref-func) ) ;; CHECK: (func $return-ref-func (result (ref $none_=>_funcref)) ;; CHECK-NEXT: (ref.func $do-return-call) ;; CHECK-NEXT: ) + ;; NOMNL: (func $return-ref-func (result (ref $none_=>_funcref)) + ;; NOMNL-NEXT: (ref.func $do-return-call) + ;; NOMNL-NEXT: ) (func $return-ref-func (result funcref) (ref.func $do-return-call) ) @@ -288,12 +423,18 @@ ;; CHECK: (func $tail-callee (result (ref ${})) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) + ;; NOMNL: (func $tail-callee (result (ref ${})) + ;; NOMNL-NEXT: (unreachable) + ;; NOMNL-NEXT: ) (func $tail-callee (result (ref ${})) (unreachable) ) ;; CHECK: (func $tail-caller-yes (result (ref ${})) ;; CHECK-NEXT: (return_call $tail-callee) ;; CHECK-NEXT: ) + ;; NOMNL: (func $tail-caller-yes (result (ref ${})) + ;; NOMNL-NEXT: (return_call $tail-callee) + ;; NOMNL-NEXT: ) (func $tail-caller-yes (result anyref) ;; This function's return type can be refined because of this call, whose ;; target's return type is more specific than anyref. @@ -308,6 +449,15 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (return_call $tail-callee) ;; CHECK-NEXT: ) + ;; NOMNL: (func $tail-caller-no (result anyref) + ;; NOMNL-NEXT: (if + ;; NOMNL-NEXT: (i32.const 1) + ;; NOMNL-NEXT: (return + ;; NOMNL-NEXT: (ref.null any) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (return_call $tail-callee) + ;; NOMNL-NEXT: ) (func $tail-caller-no (result anyref) ;; This function's return type cannot be refined because of another return ;; whose type prevents it. @@ -324,6 +474,14 @@ ;; CHECK-NEXT: (call $tail-caller-no) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $tail-call-caller + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (call $tail-caller-yes) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (call $tail-caller-no) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $tail-call-caller ;; Call the functions to cause optimization to happen. (drop @@ -338,6 +496,9 @@ ;; CHECK: (func $tail-callee-indirect (result (ref ${})) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) + ;; NOMNL: (func $tail-callee-indirect (result (ref ${})) + ;; NOMNL-NEXT: (unreachable) + ;; NOMNL-NEXT: ) (func $tail-callee-indirect (result (ref ${})) (unreachable) ) @@ -346,6 +507,11 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $tail-caller-indirect-yes (result (ref ${})) + ;; NOMNL-NEXT: (return_call_indirect $0 (type $return_{}) + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $tail-caller-indirect-yes (result anyref) (return_call_indirect (type $return_{}) (i32.const 0)) ) @@ -360,6 +526,17 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $tail-caller-indirect-no (result anyref) + ;; NOMNL-NEXT: (if + ;; NOMNL-NEXT: (i32.const 1) + ;; NOMNL-NEXT: (return + ;; NOMNL-NEXT: (ref.null any) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (return_call_indirect $0 (type $return_{}) + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $tail-caller-indirect-no (result anyref) (if (i32.const 1) (return (ref.null any)) @@ -374,6 +551,14 @@ ;; CHECK-NEXT: (call $tail-caller-indirect-no) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $tail-call-caller-indirect + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (call $tail-caller-indirect-yes) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (call $tail-caller-indirect-no) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $tail-call-caller-indirect (drop (call $tail-caller-indirect-yes) @@ -387,6 +572,9 @@ ;; CHECK: (func $tail-callee-call_ref (result (ref ${})) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) + ;; NOMNL: (func $tail-callee-call_ref (result (ref ${})) + ;; NOMNL-NEXT: (unreachable) + ;; NOMNL-NEXT: ) (func $tail-callee-call_ref (result (ref ${})) (unreachable) ) @@ -395,6 +583,11 @@ ;; CHECK-NEXT: (ref.null $return_{}) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $tail-caller-call_ref-yes (result (ref ${})) + ;; NOMNL-NEXT: (return_call_ref + ;; NOMNL-NEXT: (ref.null $return_{}) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $tail-caller-call_ref-yes (result anyref) (return_call_ref (ref.null $return_{})) ) @@ -409,6 +602,17 @@ ;; CHECK-NEXT: (ref.null $return_{}) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $tail-caller-call_ref-no (result anyref) + ;; NOMNL-NEXT: (if + ;; NOMNL-NEXT: (i32.const 1) + ;; NOMNL-NEXT: (return + ;; NOMNL-NEXT: (ref.null any) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (return_call_ref + ;; NOMNL-NEXT: (ref.null $return_{}) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $tail-caller-call_ref-no (result anyref) (if (i32.const 1) (return (ref.null any)) @@ -418,6 +622,9 @@ ;; CHECK: (func $tail-caller-call_ref-unreachable ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) + ;; NOMNL: (func $tail-caller-call_ref-unreachable + ;; NOMNL-NEXT: (unreachable) + ;; NOMNL-NEXT: ) (func $tail-caller-call_ref-unreachable (result anyref) ;; An unreachable means there is no function signature to even look at. We ;; should not hit an assertion on such things. @@ -432,6 +639,15 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (call $tail-caller-call_ref-unreachable) ;; CHECK-NEXT: ) + ;; NOMNL: (func $tail-call-caller-call_ref + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (call $tail-caller-call_ref-yes) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (call $tail-caller-call_ref-no) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (call $tail-caller-call_ref-unreachable) + ;; NOMNL-NEXT: ) (func $tail-call-caller-call_ref (drop (call $tail-caller-call_ref-yes) diff --git a/test/lit/passes/dae-gc.wast b/test/lit/passes/dae-gc.wast index 65d65d4c9..899087e7f 100644 --- a/test/lit/passes/dae-gc.wast +++ b/test/lit/passes/dae-gc.wast @@ -1,5 +1,6 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. ;; RUN: wasm-opt %s -all --dae -S -o - | filecheck %s +;; RUN: wasm-opt %s -all --dae --nominal -S -o - | filecheck %s (module ;; CHECK: (type ${} (struct )) diff --git a/test/lit/passes/heap2local.wast b/test/lit/passes/heap2local.wast index 61b18f0c4..d49836b99 100644 --- a/test/lit/passes/heap2local.wast +++ b/test/lit/passes/heap2local.wast @@ -1,6 +1,8 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. + ;; (remove-unused-names allows the pass to see that blocks flow values) ;; RUN: wasm-opt %s -all --remove-unused-names --heap2local -S -o - | filecheck %s +;; RUN: wasm-opt %s -all --remove-unused-names --heap2local --nominal -S -o - | filecheck %s (module ;; CHECK: (type $struct.A (struct (field (mut i32)) (field (mut f64)))) diff --git a/test/lit/passes/inlining_all-features.wast b/test/lit/passes/inlining_all-features.wast index f48d72409..b3089baeb 100644 --- a/test/lit/passes/inlining_all-features.wast +++ b/test/lit/passes/inlining_all-features.wast @@ -1,7 +1,7 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; NOTE: This test was ported using port_test.py and could be cleaned up. ;; RUN: foreach %s %t wasm-opt --inlining --all-features -S -o - | filecheck %s +;; RUN: foreach %s %t wasm-opt --inlining --all-features --nominal -S -o - | filecheck %s (module ;; CHECK: (type $none_=>_none (func)) @@ -12,12 +12,14 @@ ;; CHECK: (export "ref_func_test" (func $ref_func_test)) (export "ref_func_test" (func $ref_func_test)) + ;; $foo should not be removed after being inlined, because there is 'ref.func' ;; instruction that refers to it ;; CHECK: (func $foo ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $foo) + ;; CHECK: (func $ref_func_test (result funcref) ;; CHECK-NEXT: (block ;; CHECK-NEXT: (block $__inlined_func$foo @@ -31,6 +33,7 @@ (ref.func $foo) ) ) + (module ;; a function reference in a global's init should be noticed, and prevent us ;; from removing an inlined function @@ -38,12 +41,14 @@ ;; CHECK: (global $global$0 (mut funcref) (ref.func $0)) (global $global$0 (mut funcref) (ref.func $0)) + ;; CHECK: (func $0 (result i32) ;; CHECK-NEXT: (i32.const 1337) ;; CHECK-NEXT: ) (func $0 (result i32) (i32.const 1337) ) + ;; CHECK: (func $1 (result i32) ;; CHECK-NEXT: (block $__inlined_func$0 (result i32) ;; CHECK-NEXT: (i32.const 1337) @@ -53,6 +58,7 @@ (call $0) ) ) + (module ;; a function reference in the start should be noticed, and prevent us ;; from removing an inlined function @@ -60,12 +66,14 @@ ;; CHECK: (start $0) (start $0) + ;; CHECK: (func $0 ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $0 (nop) ) + ;; CHECK: (func $1 ;; CHECK-NEXT: (block $__inlined_func$0 ;; CHECK-NEXT: (nop) @@ -75,12 +83,15 @@ (call $0) ) ) + ;; inline a return_call_ref (module ;; CHECK: (type $none_=>_none (func)) (type $none_=>_none (func)) + ;; CHECK: (export "func_36_invoker" (func $1)) (export "func_36_invoker" (func $1)) + (func $0 (return_call_ref (ref.null $none_=>_none) @@ -101,6 +112,7 @@ (call $0) ) ) + ;; handle non-nullable parameter types (which turn into local types after ;; inlining) (module @@ -128,6 +140,7 @@ ) ) ) + ;; never inline an rtt parameter, as those cannot be handled as locals (module ;; CHECK: (type $struct (struct )) diff --git a/test/lit/passes/instrument-memory-gc.wast b/test/lit/passes/instrument-memory-gc.wast index 6e4192d16..1866bdcb8 100644 --- a/test/lit/passes/instrument-memory-gc.wast +++ b/test/lit/passes/instrument-memory-gc.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 --instrument-memory -all -S -o - | filecheck %s +;; RUN: foreach %s %t wasm-opt --instrument-memory --nominal -all -S -o - | filecheck %s (module ;; CHECK: (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) @@ -159,4 +161,3 @@ (array.set $array (local.get $x) (i32.const 42) (f64.const 3.14159)) ) ) - diff --git a/test/lit/passes/local-subtyping-nn.wast b/test/lit/passes/local-subtyping-nn.wast index 2a1a368e6..bcf13f7c2 100644 --- a/test/lit/passes/local-subtyping-nn.wast +++ b/test/lit/passes/local-subtyping-nn.wast @@ -1,6 +1,8 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. ;; RUN: wasm-opt %s --local-subtyping -all --enable-gc-nn-locals -S -o - \ ;; RUN: | filecheck %s +;; RUN: wasm-opt %s --local-subtyping -all --enable-gc-nn-locals --nominal -S -o - \ +;; RUN: | filecheck %s (module ;; CHECK: (type $struct (struct )) diff --git a/test/lit/passes/name-types.wast b/test/lit/passes/name-types.wast index 197a55226..39cc00423 100644 --- a/test/lit/passes/name-types.wast +++ b/test/lit/passes/name-types.wast @@ -1,5 +1,6 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. ;; RUN: wasm-opt %s -all --name-types -S -o - | filecheck %s +;; RUN: wasm-opt %s -all --name-types --nominal -S -o - | filecheck %s (module ;; An obnoxious name that will be renamed. diff --git a/test/lit/passes/optimize-instructions-gc-iit.wast b/test/lit/passes/optimize-instructions-gc-iit.wast index c0d84ab1c..e30fac8a8 100644 --- a/test/lit/passes/optimize-instructions-gc-iit.wast +++ b/test/lit/passes/optimize-instructions-gc-iit.wast @@ -1,18 +1,26 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. ;; RUN: wasm-opt %s --optimize-instructions --ignore-implicit-traps --enable-reference-types --enable-gc -S -o - \ ;; RUN: | filecheck %s +;; RUN: wasm-opt %s --optimize-instructions --ignore-implicit-traps --enable-reference-types --enable-gc --nominal -S -o - \ +;; RUN: | filecheck %s --check-prefix NOMNL (module ;; CHECK: (type $parent (struct (field i32))) + ;; NOMNL: (type $parent (struct (field i32))) (type $parent (struct (field i32))) ;; CHECK: (type $child (struct (field i32) (field f64))) - (type $child (struct (field i32) (field f64))) + ;; NOMNL: (type $child (struct (field i32) (field f64)) (extends $parent)) + (type $child (struct (field i32) (field f64)) (extends $parent)) ;; CHECK: (type $other (struct (field i64) (field f32))) + ;; NOMNL: (type $other (struct (field i64) (field f32))) (type $other (struct (field i64) (field f32))) ;; CHECK: (func $foo ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) + ;; NOMNL: (func $foo + ;; NOMNL-NEXT: (nop) + ;; NOMNL-NEXT: ) (func $foo) @@ -46,6 +54,36 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $ref-cast-iit (param $parent (ref $parent)) (param $child (ref $child)) (param $other (ref $other)) (param $parent-rtt (rtt $parent)) (param $child-rtt (rtt $child)) (param $other-rtt (rtt $other)) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref $parent)) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (local.get $parent-rtt) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $parent) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref $child)) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (local.get $parent-rtt) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $child) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.cast + ;; NOMNL-NEXT: (local.get $parent) + ;; NOMNL-NEXT: (local.get $child-rtt) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.cast + ;; NOMNL-NEXT: (local.get $child) + ;; NOMNL-NEXT: (local.get $other-rtt) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $ref-cast-iit (param $parent (ref $parent)) (param $child (ref $child)) @@ -111,6 +149,32 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $ref-cast-iit-bad (param $parent (ref $parent)) (param $parent-rtt (rtt $parent)) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.cast + ;; NOMNL-NEXT: (block $block (result (ref $parent)) + ;; NOMNL-NEXT: (call $foo) + ;; NOMNL-NEXT: (local.get $parent) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (block $block0 (result (rtt $parent)) + ;; NOMNL-NEXT: (call $foo) + ;; NOMNL-NEXT: (local.get $parent-rtt) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.cast + ;; NOMNL-NEXT: (local.get $parent) + ;; NOMNL-NEXT: (unreachable) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.cast + ;; NOMNL-NEXT: (unreachable) + ;; NOMNL-NEXT: (local.get $parent-rtt) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $ref-cast-iit-bad (param $parent (ref $parent)) (param $parent-rtt (rtt $parent)) @@ -149,6 +213,11 @@ ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $ref-eq-ref-cast (param $x eqref) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (i32.const 1) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $ref-eq-ref-cast (param $x eqref) ;; we can look through a ref.cast if we ignore traps (drop diff --git a/test/lit/passes/optimize-instructions-gc.wast b/test/lit/passes/optimize-instructions-gc.wast index 12eec8f41..5e40c781f 100644 --- a/test/lit/passes/optimize-instructions-gc.wast +++ b/test/lit/passes/optimize-instructions-gc.wast @@ -1,6 +1,8 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. ;; RUN: wasm-opt %s --remove-unused-names --optimize-instructions --enable-reference-types --enable-gc -S -o - \ ;; RUN: | filecheck %s +;; RUN: wasm-opt %s --remove-unused-names --optimize-instructions --enable-reference-types --enable-gc --nominal -S -o - \ +;; RUN: | filecheck %s (module ;; CHECK: (type $struct (struct (field $i8 (mut i8)) (field $i16 (mut i16)) (field $i32 (mut i32)) (field $i64 (mut i64)))) diff --git a/test/lit/passes/precompute-gc.wast b/test/lit/passes/precompute-gc.wast index c27433e98..0a08c02c0 100644 --- a/test/lit/passes/precompute-gc.wast +++ b/test/lit/passes/precompute-gc.wast @@ -1,6 +1,8 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. ;; RUN: wasm-opt %s --remove-unused-names --precompute-propagate --fuzz-exec -all -S -o - \ ;; RUN: | filecheck %s +;; RUN: wasm-opt %s --remove-unused-names --precompute-propagate --fuzz-exec -all --nominal -S -o - \ +;; RUN: | filecheck %s (module ;; CHECK: (type $struct (struct (field (mut i32)))) diff --git a/test/lit/passes/roundtrip-gc-types.wast b/test/lit/passes/roundtrip-gc-types.wast index 6a96fd915..c5ed84d54 100644 --- a/test/lit/passes/roundtrip-gc-types.wast +++ b/test/lit/passes/roundtrip-gc-types.wast @@ -1,26 +1,35 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. ;; RUN: wasm-opt %s -all --roundtrip -S -o - | filecheck %s +;; RUN: wasm-opt %s -all --roundtrip --nominal -S -o - | filecheck %s --check-prefix NOMNL ;; Regression test for an issue in which roundtripping failed to reproduce the ;; original types because type canonicalization was incorrect when the canonical ;; types already existed in the store. - (module ;; CHECK: (type $A (struct (field (ref $C)))) + ;; NOMNL: (type $A (struct (field (ref $C)))) (type $A (struct (field (ref $C)))) ;; CHECK: (type $C (struct (field (mut (ref $B))))) ;; CHECK: (type $B (func (param (ref $A)) (result (ref $B)))) + ;; NOMNL: (type $C (struct (field (mut (ref $B))))) + + ;; NOMNL: (type $B (func (param (ref $A)) (result (ref $B)))) (type $B (func (param (ref $A)) (result (ref $B)))) (type $C (struct (field (mut (ref $B))))) ;; CHECK: (type $D (struct (field (ref $C)) (field (ref $A)))) - (type $D (struct (field (ref $C)) (field (ref $A)))) + ;; NOMNL: (type $D (struct (field (ref $C)) (field (ref $A))) (extends $A)) + (type $D (struct (field (ref $C)) (field (ref $A))) (extends $A)) ;; CHECK: (global $g0 (rtt 0 $A) (rtt.canon $A)) + ;; NOMNL: (global $g0 (rtt 0 $A) (rtt.canon $A)) (global $g0 (rtt 0 $A) (rtt.canon $A)) ;; CHECK: (global $g1 (rtt 1 $D) (rtt.sub $D ;; CHECK-NEXT: (global.get $g0) ;; CHECK-NEXT: )) + ;; NOMNL: (global $g1 (rtt 1 $D) (rtt.sub $D + ;; NOMNL-NEXT: (global.get $g0) + ;; NOMNL-NEXT: )) (global $g1 (rtt 1 $D) (rtt.sub $D (global.get $g0) )) diff --git a/test/lit/passes/roundtrip-gc.wast b/test/lit/passes/roundtrip-gc.wast index b26f32f8c..9b73f1181 100644 --- a/test/lit/passes/roundtrip-gc.wast +++ b/test/lit/passes/roundtrip-gc.wast @@ -1,5 +1,6 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. ;; RUN: wasm-opt %s -all --generate-stack-ir --optimize-stack-ir --roundtrip -S -o - | filecheck %s +;; RUN: wasm-opt %s -all --generate-stack-ir --optimize-stack-ir --roundtrip --nominal -S -o - | filecheck %s (module (type ${i32} (struct (field i32))) diff --git a/test/lit/passes/simplify-locals-gc.wast b/test/lit/passes/simplify-locals-gc.wast index 89e696d8f..912c3a688 100644 --- a/test/lit/passes/simplify-locals-gc.wast +++ b/test/lit/passes/simplify-locals-gc.wast @@ -1,6 +1,8 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. ;; RUN: wasm-opt %s --simplify-locals -all -S -o - \ ;; RUN: | filecheck %s +;; RUN: wasm-opt %s --simplify-locals -all --nominal -S -o - \ +;; RUN: | filecheck %s (module ;; CHECK: (type $struct (struct (field (mut i32)))) diff --git a/test/lit/recursive-type-sort.wast b/test/lit/recursive-type-sort.wast index 087cb7fe6..40ae14dfd 100644 --- a/test/lit/recursive-type-sort.wast +++ b/test/lit/recursive-type-sort.wast @@ -3,6 +3,7 @@ ;; implement the C++ Compare requirements. See #3648. ;; RUN: wasm-opt %s -all --roundtrip -S -o - | filecheck %s +;; RUN: wasm-opt %s -all --roundtrip --nominal -S -o - | filecheck %s ;; Check that there's no crash. ;; CHECK: module diff --git a/test/lit/tail-call.wast b/test/lit/tail-call.wast index 92dfdbb4e..f65ecf165 100644 --- a/test/lit/tail-call.wast +++ b/test/lit/tail-call.wast @@ -3,22 +3,28 @@ ;; Check that tail calls are parsed, validated, and printed correctly ;; RUN: foreach %s %t wasm-opt -all -S -o - | filecheck %s -;; TODO: --nominal as well +;; RUN: foreach %s %t wasm-opt -all -S --nominal -o - | filecheck %s --check-prefix NOMNL (module ;; CHECK: (type $void (func)) + ;; NOMNL: (type $void (func)) (type $void (func)) ;; CHECK: (table $t 1 1 funcref) + ;; NOMNL: (table $t 1 1 funcref) (table $t 1 1 funcref) ;; CHECK: (elem $e (i32.const 0) $foo) + ;; NOMNL: (elem $e (i32.const 0) $foo) (elem $e (i32.const 0) $foo) ;; CHECK: (func $foo ;; CHECK-NEXT: (return_call $bar) ;; CHECK-NEXT: ) + ;; NOMNL: (func $foo + ;; NOMNL-NEXT: (return_call $bar) + ;; NOMNL-NEXT: ) (func $foo (return_call $bar) ) @@ -28,6 +34,11 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $bar + ;; NOMNL-NEXT: (return_call_indirect $t (type $void) + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $bar (return_call_indirect (type $void) (i32.const 0)) ) @@ -36,26 +47,35 @@ ;; Check GC types and subtyping (module ;; CHECK: (type $return-B (func (result (ref $B)))) + ;; NOMNL: (type $return-B (func (result (ref $B)))) (type $return-B (func (result (ref $B)))) ;; CHECK: (type $return-A (func (result (ref null $A)))) + ;; NOMNL: (type $return-A (func (result (ref null $A)))) (type $return-A (func (result (ref null $A)))) ;; CHECK: (type $A (struct (field i32))) + ;; NOMNL: (type $A (struct (field i32))) (type $A (struct i32)) ;; CHECK: (type $B (struct (field i32) (field i32))) - (type $B (struct i32 i32) (supertype $A)) + ;; NOMNL: (type $B (struct (field i32) (field i32)) (extends $A)) + (type $B (struct i32 i32) (extends $A)) ;; CHECK: (table $t 1 1 funcref) + ;; NOMNL: (table $t 1 1 funcref) (table $t 1 1 funcref) ;; CHECK: (elem $e (i32.const 0) $callee) + ;; NOMNL: (elem $e (i32.const 0) $callee) (elem $e (i32.const 0) $callee) ;; CHECK: (func $caller (result (ref null $A)) ;; CHECK-NEXT: (return_call $callee) ;; CHECK-NEXT: ) + ;; NOMNL: (func $caller (result (ref null $A)) + ;; NOMNL-NEXT: (return_call $callee) + ;; NOMNL-NEXT: ) (func $caller (type $return-A) (return_call $callee) ) @@ -65,6 +85,11 @@ ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $caller-indirect (result (ref $B)) + ;; NOMNL-NEXT: (return_call_indirect $t (type $return-B) + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $caller-indirect (type $return-B) (return_call_indirect $t (type $return-B) (i32.const 0)) ) @@ -72,6 +97,9 @@ ;; CHECK: (func $callee (result (ref $B)) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) + ;; NOMNL: (func $callee (result (ref $B)) + ;; NOMNL-NEXT: (unreachable) + ;; NOMNL-NEXT: ) (func $callee (type $return-B) (unreachable) ) |