diff options
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) ) |