blob: 21103089dbb122b105ca45e82cf88e84c271a002 [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 --gufa-cast-all -S -o - | filecheck %s
(module
;; CHECK: (type $none_=>_none (func))
(type $none_=>_none (func))
;; CHECK: (type $A (sub (struct )))
(type $A (sub (struct)))
;; CHECK: (type $B (sub $A (struct )))
(type $B (sub $A (struct)))
;; CHECK: (type $3 (func (result i32)))
;; CHECK: (import "a" "b" (func $import (type $3) (result i32)))
(import "a" "b" (func $import (result i32)))
;; CHECK: (elem declare func $func $funcs)
;; CHECK: (export "export1" (func $ref))
;; CHECK: (export "export2" (func $int))
;; CHECK: (export "export3" (func $func))
;; CHECK: (export "export4" (func $funcs))
;; CHECK: (export "export5" (func $unreachable))
;; CHECK: (func $ref (type $none_=>_none)
;; CHECK-NEXT: (local $a (ref $A))
;; CHECK-NEXT: (local.set $a
;; CHECK-NEXT: (struct.new_default $B)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.cast (ref $B)
;; CHECK-NEXT: (local.get $a)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $ref (export "export1")
(local $a (ref $A))
(local.set $a
(struct.new $B)
)
(drop
;; We can infer that this contains B, and add a cast to that type.
(local.get $a)
)
)
;; CHECK: (func $int (type $none_=>_none)
;; CHECK-NEXT: (local $a i32)
;; CHECK-NEXT: (local.set $a
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $int (export "export2")
(local $a i32)
(local.set $a
(i32.const 1)
)
(drop
;; We can infer that this contains 1, but there is nothing to do regarding
;; the type, which is not a reference.
(local.get $a)
)
)
;; CHECK: (func $func (type $none_=>_none)
;; CHECK-NEXT: (local $a funcref)
;; CHECK-NEXT: (local.set $a
;; CHECK-NEXT: (ref.func $func)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.func $func)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $func (export "export3") (type $none_=>_none)
(local $a funcref)
(local.set $a
(ref.func $func)
)
(drop
;; We can infer that this contains a ref to $func, which we can apply
;; here. We don't need to add a cast in addition to that, as the ref.func
;; we add has the refined type already.
(local.get $a)
)
)
;; CHECK: (func $funcs (type $none_=>_none)
;; CHECK-NEXT: (local $a funcref)
;; CHECK-NEXT: (local.set $a
;; CHECK-NEXT: (select (result (ref $none_=>_none))
;; CHECK-NEXT: (ref.func $func)
;; CHECK-NEXT: (ref.func $funcs)
;; CHECK-NEXT: (call $import)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.cast (ref $none_=>_none)
;; CHECK-NEXT: (local.get $a)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $funcs (export "export4") (type $none_=>_none)
(local $a funcref)
(local.set $a
(select
(ref.func $func)
(ref.func $funcs)
(call $import)
)
)
(drop
;; We can infer that this contains a ref to $func or $funcs, so all we
;; can infer is the type, and we add a cast to $none_=>_none.
(local.get $a)
)
)
;; CHECK: (func $unreachable (type $none_=>_none)
;; CHECK-NEXT: (local $a (ref $A))
;; CHECK-NEXT: (local.tee $a
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $unreachable (export "export5")
(local $a (ref $A))
(local.set $a
(unreachable)
)
(drop
;; We can infer that the type here is unreachable, and emit that in the
;; IR. This checks we don't error on the inferred type not being a ref.
(local.get $a)
)
)
)