blob: 50586275a0475e86a98b932369e194c70f8b3d76 [file] [edit]
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
;; RUN: foreach %s %t wasm-opt -all --closed-world --gto --preserve-type-order -S -o - | filecheck %s
(module
(rec
;; CHECK: (rec
;; CHECK-NEXT: (type $struct (descriptor $desc) (struct (field i32)))
(type $struct (descriptor $desc) (struct (field i32)))
;; CHECK: (type $desc (describes $struct) (struct))
(type $desc (describes $struct) (struct))
;; CHECK: (type $pair (struct))
(type $pair (struct (field (ref $struct)) (field (ref $struct))))
;; CHECK: (type $used-pair (struct (field (ref $struct)) (field (ref $struct))))
(type $used-pair (struct (field (ref $struct)) (field (ref $struct))))
)
;; CHECK: (type $4 (func (param (ref $struct) (ref $used-pair))))
;; CHECK: (global $nullable-desc (ref null (exact $desc)) (struct.new_default $desc))
(global $nullable-desc (ref null (exact $desc)) (struct.new $desc))
;; Check that we generate fresh names for added globals.
;; CHECK: (global $gto-removed-1 nullref (ref.null none))
(global $gto-removed-1 nullref (ref.null none))
;; CHECK: (global $second-traps (ref $pair) (struct.new_default $pair))
(global $second-traps (ref $pair)
;; Both fields will be removed, but only the second can trap, so only the
;; second will be moved to a new global.
(struct.new $pair
(struct.new_desc $struct
(i32.const 0)
(struct.new $desc)
)
(struct.new_desc $struct
(i32.const 1)
(ref.null none)
)
)
)
;; CHECK: (global $first-traps (ref $pair) (struct.new_default $pair))
(global $first-traps (ref $pair)
;; Same as above, but now the first traps (or at least we assume it can
;; based on its type).
(struct.new $pair
(struct.new_desc $struct
(i32.const 2)
(global.get $nullable-desc)
)
(struct.new_desc $struct
(i32.const 3)
(struct.new $desc)
)
)
)
;; CHECK: (global $used-traps (ref $used-pair) (struct.new $used-pair
;; CHECK-NEXT: (struct.new_desc $struct
;; CHECK-NEXT: (i32.const 4)
;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.new_desc $struct
;; CHECK-NEXT: (i32.const 5)
;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: )
;; CHECK-NEXT: ))
(global $used-traps (ref $used-pair)
;; Now both trap, but they are also used, so they will not be removed and no
;; globals will be created.
(struct.new $used-pair
(struct.new_desc $struct
(i32.const 4)
(ref.null none)
)
(struct.new_desc $struct
(i32.const 5)
(ref.null none)
)
)
)
;; CHECK: (global $gto-removed-0 (ref (exact $struct)) (struct.new_desc $struct
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: (ref.null none)
;; CHECK-NEXT: ))
;; CHECK: (global $gto-removed-1_6 (ref (exact $struct)) (struct.new_desc $struct
;; CHECK-NEXT: (i32.const 2)
;; CHECK-NEXT: (global.get $nullable-desc)
;; CHECK-NEXT: ))
;; CHECK: (func $use-struct-fields (type $4) (param $0 (ref $struct)) (param $1 (ref $used-pair))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $struct 0
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $used-pair 0
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get $used-pair 1
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $use-struct-fields (param (ref $struct)) (param (ref $used-pair))
;; Prevent the i32s in the initializers from being removed.
(drop
(struct.get $struct 0
(local.get 0)
)
)
;; Prevent the fields in used-pair from being removed.
(drop
(struct.get $used-pair 0
(local.get 1)
)
)
(drop
(struct.get $used-pair 1
(local.get 1)
)
)
)
)
;; The descriptor here is not needed, but we now optimize descriptors in
;; Unsubtyping, so we do nothing here.
(module
(rec
;; CHECK: (rec
;; CHECK-NEXT: (type $A (descriptor $B) (struct))
(type $A (descriptor $B) (struct))
;; CHECK: (type $B (describes $A) (struct))
(type $B (describes $A) (struct))
)
;; CHECK: (type $2 (func))
;; CHECK: (func $test (type $2)
;; CHECK-NEXT: (local $A (ref $A))
;; CHECK-NEXT: (local $B (ref $B))
;; CHECK-NEXT: )
(func $test
(local $A (ref $A))
(local $B (ref $B))
)
)