diff options
-rw-r--r-- | test/lit/passes/global-refining.wast | 4 | ||||
-rw-r--r-- | test/lit/passes/gsi.wast | 59 | ||||
-rw-r--r-- | test/lit/passes/gsi_vacuum_precompute.wast | 19 | ||||
-rw-r--r-- | test/lit/passes/gto-mutability.wast | 86 | ||||
-rw-r--r-- | test/lit/passes/gto-removals.wast | 137 | ||||
-rw-r--r-- | test/lit/passes/gto_and_cfp_in_O.wast | 5 | ||||
-rw-r--r-- | test/lit/passes/gufa-extern.wast | 2 | ||||
-rw-r--r-- | test/lit/passes/gufa-refs.wast | 162 |
8 files changed, 271 insertions, 203 deletions
diff --git a/test/lit/passes/global-refining.wast b/test/lit/passes/global-refining.wast index 980194c91..a04924ece 100644 --- a/test/lit/passes/global-refining.wast +++ b/test/lit/passes/global-refining.wast @@ -1,7 +1,7 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; RUN: foreach %s %t wasm-opt --nominal --global-refining -all -S -o - | filecheck %s -;; RUN: foreach %s %t wasm-opt --nominal --global-refining --closed-world -all -S -o - | filecheck %s --check-prefix=CLOSD +;; RUN: foreach %s %t wasm-opt --global-refining -all -S -o - | filecheck %s +;; RUN: foreach %s %t wasm-opt --global-refining --closed-world -all -S -o - | filecheck %s --check-prefix=CLOSD (module ;; Globals with no assignments aside from their initial values. The first is a diff --git a/test/lit/passes/gsi.wast b/test/lit/passes/gsi.wast index 8803f66e6..466594ba5 100644 --- a/test/lit/passes/gsi.wast +++ b/test/lit/passes/gsi.wast @@ -1,5 +1,5 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; RUN: foreach %s %t wasm-opt --nominal --gsi -all --closed-world -S -o - | filecheck %s +;; RUN: foreach %s %t wasm-opt --gsi -all --closed-world -S -o - | filecheck %s (module ;; CHECK: (type $struct (struct (field i32))) @@ -90,11 +90,13 @@ ;; Just one global. (module - ;; CHECK: (type $struct1 (struct (field i32))) - (type $struct1 (struct i32)) - - ;; CHECK: (type $struct2 (struct (field i32))) - (type $struct2 (struct i32)) + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $struct1 (struct (field i32))) + (type $struct1 (struct i32)) + ;; CHECK: (type $struct2 (struct (field i32))) + (type $struct2 (struct i32)) + ) ;; CHECK: (type $ref?|$struct1|_ref?|$struct2|_=>_none (func (param (ref null $struct1) (ref null $struct2)))) @@ -1224,14 +1226,17 @@ ;; Two subtypes, each with a global. A get of the parent can be optimized into ;; a select, as it must read one of the children. (module - ;; CHECK: (type $struct (struct (field i32))) - (type $struct (struct_subtype i32 data)) + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $struct (struct (field i32))) + (type $struct (struct_subtype i32 data)) - ;; CHECK: (type $sub-struct1 (struct_subtype (field i32) $struct)) - (type $sub-struct1 (struct_subtype i32 $struct)) + ;; CHECK: (type $sub-struct1 (struct_subtype (field i32) $struct)) + (type $sub-struct1 (struct_subtype i32 $struct)) - ;; CHECK: (type $sub-struct2 (struct_subtype (field i32) $struct)) - (type $sub-struct2 (struct_subtype i32 $struct)) + ;; CHECK: (type $sub-struct2 (struct_subtype (field i32) $struct)) + (type $sub-struct2 (struct_subtype i32 $struct)) + ) ;; CHECK: (type $ref?|$struct|_=>_none (func (param (ref null $struct)))) @@ -1275,14 +1280,17 @@ ;; As above, but now the parent is unoptimizable due to a struct.new in a ;; function. We must not optimize here to a select. (module - ;; CHECK: (type $struct (struct (field i32))) - (type $struct (struct_subtype i32 data)) + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $struct (struct (field i32))) + (type $struct (struct_subtype i32 data)) - ;; CHECK: (type $sub-struct1 (struct_subtype (field i32) $struct)) - (type $sub-struct1 (struct_subtype i32 $struct)) + ;; CHECK: (type $sub-struct1 (struct_subtype (field i32) $struct)) + (type $sub-struct1 (struct_subtype i32 $struct)) - ;; CHECK: (type $sub-struct2 (struct_subtype (field i32) $struct)) - (type $sub-struct2 (struct_subtype i32 $struct)) + ;; CHECK: (type $sub-struct2 (struct_subtype (field i32) $struct)) + (type $sub-struct2 (struct_subtype i32 $struct)) + ) ;; CHECK: (type $ref?|$struct|_=>_none (func (param (ref null $struct)))) @@ -1329,14 +1337,17 @@ ;; As above, the struct.new in a function is of a subtype. Again, we cannot ;; optimize, as unoptimizability spreads to supertypes. (module - ;; CHECK: (type $struct (struct (field i32))) - (type $struct (struct_subtype i32 data)) + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $struct (struct (field i32))) + (type $struct (struct_subtype i32 data)) - ;; CHECK: (type $sub-struct1 (struct_subtype (field i32) $struct)) - (type $sub-struct1 (struct_subtype i32 $struct)) + ;; CHECK: (type $sub-struct1 (struct_subtype (field i32) $struct)) + (type $sub-struct1 (struct_subtype i32 $struct)) - ;; CHECK: (type $sub-struct2 (struct_subtype (field i32) $struct)) - (type $sub-struct2 (struct_subtype i32 $struct)) + ;; CHECK: (type $sub-struct2 (struct_subtype (field i32) $struct)) + (type $sub-struct2 (struct_subtype i32 $struct)) + ) ;; CHECK: (type $ref?|$struct|_=>_none (func (param (ref null $struct)))) diff --git a/test/lit/passes/gsi_vacuum_precompute.wast b/test/lit/passes/gsi_vacuum_precompute.wast index 7f7371b6a..2658961ac 100644 --- a/test/lit/passes/gsi_vacuum_precompute.wast +++ b/test/lit/passes/gsi_vacuum_precompute.wast @@ -1,5 +1,5 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; RUN: foreach %s %t wasm-opt --nominal --gsi --vacuum --precompute -tnh --closed-world -all -S -o - | filecheck %s +;; RUN: foreach %s %t wasm-opt --gsi --vacuum --precompute -tnh --closed-world -all -S -o - | filecheck %s ;; Test a common pattern in j2wasm where itables are differentiated by type, but ;; vtables are not. For example, the vtable might be "hashable" and provide a @@ -20,13 +20,15 @@ ;; that could prevent later opts. (module - ;; CHECK: (type $vtable (struct (field funcref))) - - ;; CHECK: (type $itable1 (struct (field (ref $vtable)))) - (type $itable1 (struct_subtype (field (ref $vtable)) data)) - ;; CHECK: (type $itable2 (struct (field (ref $vtable)))) - (type $itable2 (struct_subtype (field (ref $vtable)) data)) - (type $vtable (struct_subtype (field funcref) data)) + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $vtable (struct (field funcref))) + (type $vtable (struct_subtype (field funcref) data)) + ;; CHECK: (type $itable1 (struct (field (ref $vtable)))) + (type $itable1 (struct_subtype (field (ref $vtable)) data)) + ;; CHECK: (type $itable2 (struct (field (ref $vtable)))) + (type $itable2 (struct_subtype (field (ref $vtable)) data)) + ) ;; Two $vtable instances are created, in separate enclosing objects. @@ -98,4 +100,3 @@ ;; CHECK-NEXT: ) (func $func2) ) - diff --git a/test/lit/passes/gto-mutability.wast b/test/lit/passes/gto-mutability.wast index 32d20b450..93276bad0 100644 --- a/test/lit/passes/gto-mutability.wast +++ b/test/lit/passes/gto-mutability.wast @@ -1,5 +1,5 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; RUN: foreach %s %t wasm-opt --nominal --gto --closed-world -all -S -o - | filecheck %s +;; RUN: foreach %s %t wasm-opt --gto --closed-world -all -S -o - | filecheck %s ;; (remove-unused-names is added to test fallthrough values without a block ;; name getting in the way) @@ -7,20 +7,24 @@ ;; The struct here has three fields, and the second of them has no struct.set ;; which means we can make it immutable. - ;; CHECK: (type $struct (struct (field (mut funcref)) (field funcref) (field (mut funcref)))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $ref?|$struct|_=>_none (func (param (ref null $struct)))) + + ;; CHECK: (type $two-params (func (param (ref $struct) (ref $struct)))) + + ;; CHECK: (type $none_=>_ref?|$struct| (func (result (ref null $struct)))) + + ;; CHECK: (type $struct (struct (field (mut funcref)) (field funcref) (field (mut funcref)))) (type $struct (struct (field (mut funcref)) (field (mut funcref)) (field (mut funcref)))) - ;; CHECK: (type $two-params (func (param (ref $struct) (ref $struct)))) (type $two-params (func (param (ref $struct)) (param (ref $struct)))) ;; Test that we update tag types properly. (table 0 funcref) - ;; CHECK: (type $ref|$struct|_=>_none (func (param (ref $struct)))) - - ;; CHECK: (type $none_=>_ref?|$struct| (func (result (ref null $struct)))) + ;; CHECK: (type $ref|$struct|_=>_none (func (param (ref $struct)))) - ;; CHECK: (type $ref?|$struct|_=>_none (func (param (ref null $struct)))) + ;; CHECK: (type $ref|$struct|_=>_none (func (param (ref $struct)))) ;; CHECK: (table $0 0 funcref) @@ -171,14 +175,18 @@ ;; Test recursion between structs where we only modify one. Specifically $B ;; has no writes to either of its fields. - ;; CHECK: (type $A (struct (field (mut (ref null $B))) (field (mut i32)))) - (type $A (struct (field (mut (ref null $B))) (field (mut i32)) )) - ;; CHECK: (type $B (struct (field (ref null $A)) (field f64))) - (type $B (struct (field (mut (ref null $A))) (field (mut f64)) )) + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $B (struct (field (ref null $A)) (field f64))) + + ;; CHECK: (type $ref?|$A|_ref?|$B|_=>_none (func (param (ref null $A) (ref null $B)))) - ;; CHECK: (type $ref|$A|_=>_none (func (param (ref $A)))) + ;; CHECK: (type $A (struct (field (mut (ref null $B))) (field (mut i32)))) + (type $A (struct (field (mut (ref null $B))) (field (mut i32)) )) + (type $B (struct (field (mut (ref null $A))) (field (mut f64)) )) + ) - ;; CHECK: (type $ref?|$A|_ref?|$B|_=>_none (func (param (ref null $A) (ref null $B)))) + ;; CHECK: (type $ref|$A|_=>_none (func (param (ref $A)))) ;; CHECK: (func $func (type $ref|$A|_=>_none) (param $x (ref $A)) ;; CHECK-NEXT: (struct.set $A 0 @@ -234,15 +242,19 @@ (module ;; As before, but flipped so that $A's fields can become immutable. - ;; CHECK: (type $B (struct (field (mut (ref null $A))) (field (mut f64)))) - (type $B (struct (field (mut (ref null $A))) (field (mut f64)) )) + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $A (struct (field (ref null $B)) (field i32))) + + ;; CHECK: (type $ref?|$A|_ref?|$B|_=>_none (func (param (ref null $A) (ref null $B)))) - ;; CHECK: (type $A (struct (field (ref null $B)) (field i32))) - (type $A (struct (field (mut (ref null $B))) (field (mut i32)) )) + ;; CHECK: (type $B (struct (field (mut (ref null $A))) (field (mut f64)))) + (type $B (struct (field (mut (ref null $A))) (field (mut f64)) )) - ;; CHECK: (type $ref|$B|_=>_none (func (param (ref $B)))) + (type $A (struct (field (mut (ref null $B))) (field (mut i32)) )) + ) - ;; CHECK: (type $ref?|$A|_ref?|$B|_=>_none (func (param (ref null $A) (ref null $B)))) + ;; CHECK: (type $ref|$B|_=>_none (func (param (ref $B)))) ;; CHECK: (func $func (type $ref|$B|_=>_none) (param $x (ref $B)) ;; CHECK-NEXT: (struct.set $B 0 @@ -298,16 +310,18 @@ (module ;; As before, but now one field in each can become immutable. - ;; CHECK: (type $A (struct (field (mut (ref null $B))) (field i32))) - - ;; CHECK: (type $B (struct (field (ref null $A)) (field (mut f64)))) - (type $B (struct (field (mut (ref null $A))) (field (mut f64)) )) + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $ref?|$A|_ref?|$B|_=>_none (func (param (ref null $A) (ref null $B)))) - (type $A (struct (field (mut (ref null $B))) (field (mut i32)) )) + ;; CHECK: (type $B (struct (field (ref null $A)) (field (mut f64)))) + (type $B (struct (field (mut (ref null $A))) (field (mut f64)) )) - ;; CHECK: (type $ref|$A|_ref|$B|_=>_none (func (param (ref $A) (ref $B)))) + ;; CHECK: (type $A (struct (field (mut (ref null $B))) (field i32))) + (type $A (struct (field (mut (ref null $B))) (field (mut i32)) )) + ) - ;; CHECK: (type $ref?|$A|_ref?|$B|_=>_none (func (param (ref null $A) (ref null $B)))) + ;; CHECK: (type $ref|$A|_ref|$B|_=>_none (func (param (ref $A) (ref $B)))) ;; CHECK: (func $func (type $ref|$A|_ref|$B|_=>_none) (param $x (ref $A)) (param $y (ref $B)) ;; CHECK-NEXT: (struct.set $A 0 @@ -365,12 +379,13 @@ ;; Field #1 is mutable and can become so. ;; Field #2 is mutable and must remain so. - ;; CHECK: (type $struct (struct (field i32) (field i32) (field (mut i32)))) - (type $struct (struct (field i32) (field (mut i32)) (field (mut i32)))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $ref?|$struct|_=>_none (func (param (ref null $struct)))) - ;; CHECK: (type $ref|$struct|_=>_none (func (param (ref $struct)))) + ;; CHECK: (type $struct (struct (field i32) (field i32) (field (mut i32)))) + (type $struct (struct (field i32) (field (mut i32)) (field (mut i32)))) - ;; CHECK: (type $ref?|$struct|_=>_none (func (param (ref null $struct)))) + ;; CHECK: (type $ref|$struct|_=>_none (func (param (ref $struct)))) ;; CHECK: (func $func (type $ref|$struct|_=>_none) (param $x (ref $struct)) ;; CHECK-NEXT: (struct.set $struct 2 @@ -413,14 +428,15 @@ ;; Subtyping. Without a write in either supertype or subtype, we can ;; optimize the field to be immutable. - ;; CHECK: (type $super (struct (field i32))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $ref?|$super|_ref?|$sub|_=>_none (func (param (ref null $super) (ref null $sub)))) + + ;; CHECK: (type $super (struct (field i32))) (type $super (struct (field (mut i32)))) - ;; CHECK: (type $sub (struct_subtype (field i32) $super)) + ;; CHECK: (type $sub (struct_subtype (field i32) $super)) (type $sub (struct_subtype (field (mut i32)) $super)) - ;; CHECK: (type $none_=>_none (func)) - - ;; CHECK: (type $ref?|$super|_ref?|$sub|_=>_none (func (param (ref null $super) (ref null $sub)))) + ;; CHECK: (type $none_=>_none (func)) ;; CHECK: (func $func (type $none_=>_none) ;; CHECK-NEXT: (drop diff --git a/test/lit/passes/gto-removals.wast b/test/lit/passes/gto-removals.wast index c2895cf32..f422cc542 100644 --- a/test/lit/passes/gto-removals.wast +++ b/test/lit/passes/gto-removals.wast @@ -1,15 +1,16 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; RUN: foreach %s %t wasm-opt --nominal --gto --closed-world -all -S -o - | filecheck %s +;; RUN: foreach %s %t wasm-opt --gto --closed-world -all -S -o - | filecheck %s (module ;; A struct with a field that is never read or written, so it can be ;; removed. - ;; CHECK: (type $ref|$struct|_=>_none (func (param (ref $struct)))) - - ;; CHECK: (type $struct (struct )) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $struct (struct )) (type $struct (struct_subtype (field (mut funcref)) data)) + ;; CHECK: (type $ref|$struct|_=>_none (func (param (ref $struct)))) + ;; CHECK: (func $func (type $ref|$struct|_=>_none) (param $x (ref $struct)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) @@ -20,10 +21,11 @@ (module ;; A write does not keep a field from being removed. - ;; CHECK: (type $struct (struct )) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $struct (struct )) (type $struct (struct_subtype (field (mut funcref)) data)) - ;; CHECK: (type $ref|$struct|_=>_none (func (param (ref $struct)))) + ;; CHECK: (type $ref|$struct|_=>_none (func (param (ref $struct)))) ;; CHECK: (func $func (type $ref|$struct|_=>_none) (param $x (ref $struct)) ;; CHECK-NEXT: (drop @@ -50,10 +52,11 @@ (module ;; A new does not keep a field from being removed. - ;; CHECK: (type $struct (struct )) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $struct (struct )) (type $struct (struct_subtype (field (mut funcref)) data)) - ;; CHECK: (type $ref|$struct|_=>_none (func (param (ref $struct)))) + ;; CHECK: (type $ref|$struct|_=>_none (func (param (ref $struct)))) ;; CHECK: (func $func (type $ref|$struct|_=>_none) (param $x (ref $struct)) ;; CHECK-NEXT: (drop @@ -73,10 +76,11 @@ (module ;; A new_default does not keep a field from being removed. - ;; CHECK: (type $struct (struct )) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $struct (struct )) (type $struct (struct_subtype (field (mut funcref)) data)) - ;; CHECK: (type $ref|$struct|_=>_none (func (param (ref $struct)))) + ;; CHECK: (type $ref|$struct|_=>_none (func (param (ref $struct)))) ;; CHECK: (func $func (type $ref|$struct|_=>_none) (param $x (ref $struct)) ;; CHECK-NEXT: (drop @@ -95,10 +99,11 @@ (module ;; A read *does* keep a field from being removed. - ;; CHECK: (type $struct (struct (field funcref))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $struct (struct (field funcref))) (type $struct (struct_subtype (field (mut funcref)) data)) - ;; CHECK: (type $ref|$struct|_=>_none (func (param (ref $struct)))) + ;; CHECK: (type $ref|$struct|_=>_none (func (param (ref $struct)))) ;; CHECK: (func $func (type $ref|$struct|_=>_none) (param $x (ref $struct)) ;; CHECK-NEXT: (drop @@ -122,17 +127,19 @@ ;; of removing with the immutability inference that --gto does.) ;; A struct with all fields marked mutable. - ;; CHECK: (type $mut-struct (struct (field $r i32) (field $rw (mut i32)) (field $r-2 i32) (field $rw-2 (mut i32)))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $imm-struct (struct (field $rw i32) (field $rw-2 i32))) + + ;; CHECK: (type $ref|$imm-struct|_=>_none (func (param (ref $imm-struct)))) + + ;; CHECK: (type $mut-struct (struct (field $r i32) (field $rw (mut i32)) (field $r-2 i32) (field $rw-2 (mut i32)))) (type $mut-struct (struct_subtype (field $r (mut i32)) (field $w (mut i32)) (field $rw (mut i32)) (field $r-2 (mut i32)) (field $w-2 (mut i32)) (field $rw-2 (mut i32)) data)) ;; A similar struct but with all fields marked immutable, and the only ;; writes are from during creation (so all fields are at least writeable). - ;; CHECK: (type $imm-struct (struct (field $rw i32) (field $rw-2 i32))) (type $imm-struct (struct_subtype (field $w i32) (field $rw i32) (field $w-2 i32) (field $rw-2 i32) data)) - ;; CHECK: (type $ref|$mut-struct|_=>_none (func (param (ref $mut-struct)))) - - ;; CHECK: (type $ref|$imm-struct|_=>_none (func (param (ref $imm-struct)))) + ;; CHECK: (type $ref|$mut-struct|_=>_none (func (param (ref $mut-struct)))) ;; CHECK: (func $func-mut (type $ref|$mut-struct|_=>_none) (param $x (ref $mut-struct)) ;; CHECK-NEXT: (drop @@ -273,9 +280,10 @@ ;; A vtable-like structure created in a global location. Only some of the ;; fields are accessed. - ;; CHECK: (type $none_=>_none (func)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $none_=>_none (func)) - ;; CHECK: (type $vtable (struct (field $v1 funcref) (field $v2 funcref))) + ;; CHECK: (type $vtable (struct (field $v1 funcref) (field $v2 funcref))) (type $vtable (struct_subtype (field $v0 funcref) (field $v1 funcref) (field $v2 funcref) (field $v3 funcref) (field $v4 funcref) data)) ;; CHECK: (global $vtable (ref $vtable) (struct.new $vtable @@ -347,10 +355,11 @@ ;; by coincidence. - ;; CHECK: (type $vtable (struct (field $v1 i64) (field $v2 f32))) - (type $vtable (struct_subtype (field $v0 i32) (field $v1 i64) (field $v2 f32) (field $v3 f64) (field $v4 anyref) data)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $none_=>_none (func)) - ;; CHECK: (type $none_=>_none (func)) + ;; CHECK: (type $vtable (struct (field $v1 i64) (field $v2 f32))) + (type $vtable (struct_subtype (field $v0 i32) (field $v1 i64) (field $v2 f32) (field $v3 f64) (field $v4 anyref) data)) ;; CHECK: (global $vtable (ref $vtable) (struct.new $vtable ;; CHECK-NEXT: (i64.const 1) @@ -397,21 +406,22 @@ (module ;; A new with side effects - ;; CHECK: (type $struct (struct (field i32))) - (type $struct (struct i32 f64 (ref any))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $i32_=>_ref|any| (func (param i32) (result (ref any)))) + ;; CHECK: (type $i32_=>_f64 (func (param i32) (result f64))) - ;; CHECK: (type $none_=>_none (func)) + ;; CHECK: (type $i32_=>_i32 (func (param i32) (result i32))) - ;; CHECK: (type $ref|any|_ref?|$struct|_=>_none (func (param (ref any) (ref null $struct)))) + ;; CHECK: (type $ref|any|_=>_none (func (param (ref any)))) - ;; CHECK: (type $ref|any|_=>_none (func (param (ref any)))) + ;; CHECK: (type $none_=>_none (func)) - ;; CHECK: (type $i32_=>_i32 (func (param i32) (result i32))) + ;; CHECK: (type $struct (struct (field i32))) + (type $struct (struct i32 f64 (ref any))) - ;; CHECK: (type $i32_=>_f64 (func (param i32) (result f64))) - ;; CHECK: (type $i32_=>_ref|any| (func (param i32) (result (ref any)))) + ;; CHECK: (type $ref|any|_ref?|$struct|_=>_none (func (param (ref any) (ref null $struct)))) ;; CHECK: (global $imm-i32 i32 (i32.const 1234)) (global $imm-i32 i32 (i32.const 1234)) @@ -624,14 +634,14 @@ ;; We can remove fields from the end if they are only used in subtypes, because ;; the subtypes can always add fields at the end (and only at the end). (module - ;; CHECK: (type $parent (struct (field i32) (field i64))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $parent (struct (field i32) (field i64))) + (type $parent (struct_subtype (field i32) (field i64) (field f32) (field f64) data)) - ;; CHECK: (type $child (struct_subtype (field i32) (field i64) (field f32) (field f64) (field anyref) $parent)) + ;; CHECK: (type $child (struct_subtype (field i32) (field i64) (field f32) (field f64) (field anyref) $parent)) (type $child (struct_subtype (field i32) (field i64) (field f32) (field f64) (field anyref) $parent)) - (type $parent (struct_subtype (field i32) (field i64) (field f32) (field f64) data)) - - ;; CHECK: (type $ref|$parent|_ref|$child|_=>_none (func (param (ref $parent) (ref $child)))) + ;; CHECK: (type $ref|$parent|_ref|$child|_=>_none (func (param (ref $parent) (ref $child)))) ;; CHECK: (func $func (type $ref|$parent|_ref|$child|_=>_none) (param $x (ref $parent)) (param $y (ref $child)) ;; CHECK-NEXT: (drop @@ -674,14 +684,14 @@ ) (module - ;; CHECK: (type $parent (struct (field i32) (field i64) (field (mut f32)))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $parent (struct (field i32) (field i64) (field (mut f32)))) + (type $parent (struct_subtype (field (mut i32)) (field (mut i64)) (field (mut f32)) (field (mut f64)) data)) - ;; CHECK: (type $child (struct_subtype (field i32) (field i64) (field (mut f32)) (field f64) (field anyref) $parent)) + ;; CHECK: (type $child (struct_subtype (field i32) (field i64) (field (mut f32)) (field f64) (field anyref) $parent)) (type $child (struct_subtype (field (mut i32)) (field (mut i64)) (field (mut f32)) (field (mut f64)) (field (mut anyref)) $parent)) - (type $parent (struct_subtype (field (mut i32)) (field (mut i64)) (field (mut f32)) (field (mut f64)) data)) - - ;; CHECK: (type $ref|$parent|_ref|$child|_=>_none (func (param (ref $parent) (ref $child)))) + ;; CHECK: (type $ref|$parent|_ref|$child|_=>_none (func (param (ref $parent) (ref $child)))) ;; CHECK: (func $func (type $ref|$parent|_ref|$child|_=>_none) (param $x (ref $parent)) (param $y (ref $child)) ;; CHECK-NEXT: (struct.set $parent 2 @@ -731,14 +741,17 @@ ;; reads might be of data of either child, of course (as a refernce to the ;; parent might point to them), so we cannot optimize here. (module - ;; CHECK: (type $parent (struct (field i32))) - (type $parent (struct_subtype (field i32) data)) - ;; CHECK: (type $ref|$parent|_ref|$child1|_ref|$child2|_=>_none (func (param (ref $parent) (ref $child1) (ref $child2)))) + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $parent (struct (field i32))) + (type $parent (struct_subtype (field i32) data)) + ;; CHECK: (type $child1 (struct_subtype (field i32) $parent)) + (type $child1 (struct_subtype (field i32) $parent)) + ;; CHECK: (type $child2 (struct_subtype (field i32) $parent)) + (type $child2 (struct_subtype (field i32) $parent)) + ) - ;; CHECK: (type $child1 (struct_subtype (field i32) $parent)) - (type $child1 (struct_subtype (field i32) $parent)) - ;; CHECK: (type $child2 (struct_subtype (field i32) $parent)) - (type $child2 (struct_subtype (field i32) $parent)) + ;; CHECK: (type $ref|$parent|_ref|$child1|_ref|$child2|_=>_none (func (param (ref $parent) (ref $child1) (ref $child2)))) ;; CHECK: (func $func (type $ref|$parent|_ref|$child1|_ref|$child2|_=>_none) (param $parent (ref $parent)) (param $child1 (ref $child1)) (param $child2 (ref $child2)) ;; CHECK-NEXT: (drop @@ -755,16 +768,19 @@ ;; As above, but now the read is just of one child. We can remove the field ;; from the parent and the other child. (module - ;; CHECK: (type $parent (struct )) + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $parent (struct )) + (type $parent (struct_subtype (field i32) data)) - ;; CHECK: (type $child1 (struct_subtype (field i32) $parent)) - (type $child1 (struct_subtype (field i32) $parent)) + ;; CHECK: (type $child2 (struct_subtype $parent)) - (type $parent (struct_subtype (field i32) data)) - ;; CHECK: (type $ref|$parent|_ref|$child1|_ref|$child2|_=>_none (func (param (ref $parent) (ref $child1) (ref $child2)))) + ;; CHECK: (type $child1 (struct_subtype (field i32) $parent)) + (type $child1 (struct_subtype (field i32) $parent)) + (type $child2 (struct_subtype (field i32) $parent)) + ) - ;; CHECK: (type $child2 (struct_subtype $parent)) - (type $child2 (struct_subtype (field i32) $parent)) + ;; CHECK: (type $ref|$parent|_ref|$child1|_ref|$child2|_=>_none (func (param (ref $parent) (ref $child1) (ref $child2)))) ;; CHECK: (func $func (type $ref|$parent|_ref|$child1|_ref|$child2|_=>_none) (param $parent (ref $parent)) (param $child1 (ref $child1)) (param $child2 (ref $child2)) ;; CHECK-NEXT: (drop @@ -779,16 +795,17 @@ ) (module - ;; CHECK: (type ${mut:i8} (struct )) - (type ${mut:i8} (struct_subtype (field (mut i8)) data)) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $none_=>_ref|${mut:i8}| (func (result (ref ${mut:i8})))) - ;; CHECK: (type $ref?|${mut:i8}|_=>_none (func (param (ref null ${mut:i8})))) + ;; CHECK: (type $none_=>_i32 (func (result i32))) - ;; CHECK: (type $none_=>_none (func)) + ;; CHECK: (type $none_=>_none (func)) - ;; CHECK: (type $none_=>_i32 (func (result i32))) + ;; CHECK: (type ${mut:i8} (struct )) + (type ${mut:i8} (struct_subtype (field (mut i8)) data)) - ;; CHECK: (type $none_=>_ref|${mut:i8}| (func (result (ref ${mut:i8})))) + ;; CHECK: (type $ref?|${mut:i8}|_=>_none (func (param (ref null ${mut:i8})))) ;; CHECK: (func $unreachable-set (type $ref?|${mut:i8}|_=>_none) (param ${mut:i8} (ref null ${mut:i8})) ;; CHECK-NEXT: (drop diff --git a/test/lit/passes/gto_and_cfp_in_O.wast b/test/lit/passes/gto_and_cfp_in_O.wast index 9d385d0f9..83c2af71f 100644 --- a/test/lit/passes/gto_and_cfp_in_O.wast +++ b/test/lit/passes/gto_and_cfp_in_O.wast @@ -1,7 +1,7 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; RUN: foreach %s %t wasm-opt -O -all --nominal --closed-world -S -o - | filecheck %s -;; RUN: foreach %s %t wasm-opt -O -all --nominal -S -o - | filecheck %s --check-prefix OPEN_WORLD +;; RUN: foreach %s %t wasm-opt -O -all --closed-world -S -o - | filecheck %s +;; RUN: foreach %s %t wasm-opt -O -all -S -o - | filecheck %s --check-prefix OPEN_WORLD ;; Test that -O, with nominal typing + GC enabled, will run global type ;; optimization in conjunction with constant field propagation etc. But, in an @@ -65,4 +65,3 @@ ) ) ) - diff --git a/test/lit/passes/gufa-extern.wast b/test/lit/passes/gufa-extern.wast index c8b593e4b..5f293409f 100644 --- a/test/lit/passes/gufa-extern.wast +++ b/test/lit/passes/gufa-extern.wast @@ -1,5 +1,5 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; RUN: foreach %s %t wasm-opt -all --gufa --nominal -S -o - | filecheck %s +;; RUN: foreach %s %t wasm-opt -all --gufa -S -o - | filecheck %s (module ;; CHECK: (type $externref_anyref_=>_none (func (param externref anyref))) diff --git a/test/lit/passes/gufa-refs.wast b/test/lit/passes/gufa-refs.wast index a1652c7d3..aac20e9fe 100644 --- a/test/lit/passes/gufa-refs.wast +++ b/test/lit/passes/gufa-refs.wast @@ -1,5 +1,5 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; RUN: foreach %s %t wasm-opt -all --gufa --nominal -S -o - | filecheck %s +;; RUN: foreach %s %t wasm-opt -all --gufa -S -o - | filecheck %s (module ;; CHECK: (type $struct (struct )) @@ -680,6 +680,7 @@ ;; As above, but using indirect calls. (module ;; CHECK: (type $struct (struct )) + (type $struct (struct)) ;; CHECK: (type $two-params (func (param (ref $struct) (ref $struct)))) (type $two-params (func (param (ref $struct)) (param (ref $struct)))) @@ -687,8 +688,6 @@ ;; CHECK: (type $three-params (func (param (ref $struct) (ref $struct) (ref $struct)))) (type $three-params (func (param (ref $struct)) (param (ref $struct)) (param (ref $struct)))) - (type $struct (struct)) - (table 10 funcref) (elem (i32.const 0) funcref @@ -813,12 +812,11 @@ ;; As above, but using call_ref. (module ;; CHECK: (type $struct (struct )) + (type $struct (struct)) ;; CHECK: (type $two-params (func (param (ref $struct) (ref $struct)))) (type $two-params (func (param (ref $struct)) (param (ref $struct)))) - (type $struct (struct)) - ;; CHECK: (elem declare func $func-2params-a) ;; CHECK: (func $func-2params-a (type $two-params) (param $x (ref $struct)) (param $y (ref $struct)) @@ -923,21 +921,22 @@ ;; Struct fields. (module - ;; CHECK: (type $parent (struct (field (mut (ref null $struct))))) - - ;; CHECK: (type $child (struct_subtype (field (mut (ref null $struct))) (field (mut (ref null $struct))) $parent)) - - ;; CHECK: (type $struct (struct )) - (type $struct (struct_subtype data)) - - (type $parent (struct_subtype (field (mut (ref null $struct))) data)) - (type $child (struct_subtype (field (mut (ref null $struct))) (field (mut (ref null $struct))) $parent)) + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $struct (struct )) + (type $struct (struct_subtype data)) + + ;; CHECK: (type $parent (struct (field (mut (ref null $struct))))) + (type $parent (struct_subtype (field (mut (ref null $struct))) data)) + ;; CHECK: (type $child (struct_subtype (field (mut (ref null $struct))) (field (mut (ref null $struct))) $parent)) + (type $child (struct_subtype (field (mut (ref null $struct))) (field (mut (ref null $struct))) $parent)) + + ;; CHECK: (type $unrelated (struct )) + (type $unrelated (struct)) + ) ;; CHECK: (type $none_=>_none (func)) - ;; CHECK: (type $unrelated (struct )) - (type $unrelated (struct)) - ;; CHECK: (func $func (type $none_=>_none) ;; CHECK-NEXT: (local $child (ref null $child)) ;; CHECK-NEXT: (local $parent (ref null $parent)) @@ -1166,9 +1165,11 @@ ;; Default values in struct fields. (module - (type $A (struct_subtype (field i32) data)) - (type $B (struct_subtype (field i32) data)) - (type $C (struct_subtype (field i32) data)) + (rec + (type $A (struct_subtype (field i32) data)) + (type $B (struct_subtype (field i32) data)) + (type $C (struct_subtype (field i32) data)) + ) ;; CHECK: (type $none_=>_none (func)) @@ -1200,13 +1201,11 @@ ;; Exact types: Writes to the parent class do not confuse us. (module - ;; CHECK: (type $parent (struct (field (mut (ref null $struct))))) - - ;; CHECK: (type $child (struct_subtype (field (mut (ref null $struct))) (field i32) $parent)) - ;; CHECK: (type $struct (struct )) (type $struct (struct_subtype data)) + ;; CHECK: (type $parent (struct (field (mut (ref null $struct))))) (type $parent (struct_subtype (field (mut (ref null $struct))) data)) + ;; CHECK: (type $child (struct_subtype (field (mut (ref null $struct))) (field i32) $parent)) (type $child (struct_subtype (field (mut (ref null $struct))) (field i32) $parent)) ;; CHECK: (type $none_=>_none (func)) @@ -1537,15 +1536,20 @@ ;; Arrays get/set (module - (type $nothing (array_subtype (mut (ref null any)) data)) + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $nothing (array (mut anyref))) + (type $nothing (array_subtype (mut (ref null any)) data)) - ;; CHECK: (type $null (array (mut anyref))) - (type $null (array_subtype (mut (ref null any)) data)) + ;; CHECK: (type $null (array (mut anyref))) + (type $null (array_subtype (mut (ref null any)) data)) - ;; CHECK: (type $something (array (mut anyref))) - (type $something (array_subtype (mut (ref null any)) data)) + ;; CHECK: (type $something (array (mut anyref))) + (type $something (array_subtype (mut (ref null any)) data)) - (type $something-child (array_subtype (mut (ref null any)) $something)) + ;; CHECK: (type $something-child (array_subtype (mut anyref) $something)) + (type $something-child (array_subtype (mut (ref null any)) $something)) + ) ;; CHECK: (type $none_=>_none (func)) @@ -2199,11 +2203,11 @@ ) (module - ;; CHECK: (type $none_=>_ref|${}| (func (result (ref ${})))) - ;; CHECK: (type ${} (struct )) (type ${} (struct_subtype data)) + ;; CHECK: (type $none_=>_ref|${}| (func (result (ref ${})))) + ;; CHECK: (func $func (type $none_=>_ref|${}|) (result (ref ${})) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block $block (result (ref none)) @@ -3654,10 +3658,13 @@ ;; array.copy between types. (module - ;; CHECK: (type $bytes (array (mut anyref))) - (type $bytes (array (mut anyref))) - ;; CHECK: (type $chars (array (mut anyref))) - (type $chars (array (mut anyref))) + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $bytes (array (mut anyref))) + (type $bytes (array (mut anyref))) + ;; CHECK: (type $chars (array (mut anyref))) + (type $chars (array (mut anyref))) + ) ;; CHECK: (type $none_=>_none (func)) @@ -3739,10 +3746,13 @@ ;; value (a null) which we can optimize, but $bytes has two values and we ;; cannot optimize there. (module - ;; CHECK: (type $bytes (array (mut anyref))) - (type $bytes (array (mut anyref))) - ;; CHECK: (type $chars (array (mut anyref))) - (type $chars (array (mut anyref))) + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $bytes (array (mut anyref))) + (type $bytes (array (mut anyref))) + ;; CHECK: (type $chars (array (mut anyref))) + (type $chars (array (mut anyref))) + ) ;; CHECK: (type $none_=>_none (func)) @@ -4434,10 +4444,13 @@ ;; call_ref types (module - ;; CHECK: (type $i1 (func (param i32))) - (type $i1 (func (param i32))) - ;; CHECK: (type $i2 (func (param i32))) - (type $i2 (func (param i32))) + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $i1 (func (param i32))) + (type $i1 (func (param i32))) + ;; CHECK: (type $i2 (func (param i32))) + (type $i2 (func (param i32))) + ) ;; CHECK: (type $none_=>_none (func)) @@ -4568,14 +4581,15 @@ ;; Limited cone reads. (module - ;; CHECK: (type $A (struct (field (mut i32)))) - (type $A (struct_subtype (field (mut i32)) data)) - ;; CHECK: (type $B (struct_subtype (field (mut i32)) $A)) - (type $B (struct_subtype (field (mut i32)) $A)) - ;; CHECK: (type $C (struct_subtype (field (mut i32)) $B)) - (type $C (struct_subtype (field (mut i32)) $B)) - - + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $A (struct (field (mut i32)))) + (type $A (struct_subtype (field (mut i32)) data)) + ;; CHECK: (type $B (struct_subtype (field (mut i32)) $A)) + (type $B (struct_subtype (field (mut i32)) $A)) + ;; CHECK: (type $C (struct_subtype (field (mut i32)) $B)) + (type $C (struct_subtype (field (mut i32)) $B)) + ) ;; CHECK: (type $i32_=>_none (func (param i32))) @@ -4675,12 +4689,15 @@ ;; As above, but now A and B agree on the value and not B and C. (module - ;; CHECK: (type $A (struct (field (mut i32)))) - (type $A (struct_subtype (field (mut i32)) data)) - ;; CHECK: (type $B (struct_subtype (field (mut i32)) $A)) - (type $B (struct_subtype (field (mut i32)) $A)) - ;; CHECK: (type $C (struct_subtype (field (mut i32)) $B)) - (type $C (struct_subtype (field (mut i32)) $B)) + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $A (struct (field (mut i32)))) + (type $A (struct_subtype (field (mut i32)) data)) + ;; CHECK: (type $B (struct_subtype (field (mut i32)) $A)) + (type $B (struct_subtype (field (mut i32)) $A)) + ;; CHECK: (type $C (struct_subtype (field (mut i32)) $B)) + (type $C (struct_subtype (field (mut i32)) $B)) + ) ;; CHECK: (type $i32_=>_none (func (param i32))) @@ -4780,12 +4797,15 @@ ;; As above but now A has two subtypes, instead of a chain A->B->C (module - ;; CHECK: (type $A (struct (field (mut i32)))) - (type $A (struct_subtype (field (mut i32)) data)) - ;; CHECK: (type $B (struct_subtype (field (mut i32)) $A)) - (type $B (struct_subtype (field (mut i32)) $A)) - ;; CHECK: (type $C (struct_subtype (field (mut i32)) $A)) - (type $C (struct_subtype (field (mut i32)) $A)) ;; This line changed. + (rec + ;; CHECK: (rec + ;; CHECK-NEXT: (type $A (struct (field (mut i32)))) + (type $A (struct_subtype (field (mut i32)) data)) + ;; CHECK: (type $B (struct_subtype (field (mut i32)) $A)) + (type $B (struct_subtype (field (mut i32)) $A)) + ;; CHECK: (type $C (struct_subtype (field (mut i32)) $A)) + (type $C (struct_subtype (field (mut i32)) $A)) ;; This line changed. + ) ;; CHECK: (type $i32_=>_none (func (param i32))) @@ -5528,11 +5548,15 @@ ;; Packed field combination. (module - ;; CHECK: (type $A (struct (field i8))) - (type $A (struct (field i8))) - (type $B (struct (field i8))) - - ;; CHECK: (type $none_=>_none (func)) + (rec + ;; CHECK: (type $none_=>_none (func)) + + ;; CHECK: (rec + ;; CHECK-NEXT: (type $A (struct (field i8))) + (type $A (struct (field i8))) + ;; CHECK: (type $B (struct (field i8))) + (type $B (struct (field i8))) + ) ;; CHECK: (func $A (type $none_=>_none) ;; CHECK-NEXT: (drop |