blob: d1fef1c2996b803112086cc18613b18ed52dc5ea [file] [log] [blame] [edit]
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
;; RUN: foreach %s %t wasm-opt --hybrid --signature-refining -all -S -o - | filecheck %s
(module
;; The signature should be refined to a single self-referential type.
;; CHECK: (type $refined (func_subtype (param (ref $refined)) (result (ref $refined)) func))
(type $refined (func (param (ref $refined)) (result (ref $refined))))
;; CHECK: (elem declare func $foo)
;; CHECK: (func $foo (type $refined) (param $0 (ref $refined)) (result (ref $refined))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $foo
;; CHECK-NEXT: (ref.func $foo)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.func $foo)
;; CHECK-NEXT: )
(func $foo (param funcref) (result funcref)
(drop
(call $foo
(ref.func $foo)
)
)
(ref.func $foo)
)
)
(module
;; The signatures should be refined to a pair of mutually self-referential types.
;; CHECK: (rec
;; CHECK-NEXT: (type $0 (func_subtype (param i32 (ref $0)) (result (ref $1)) func))
(type $0 (func (param i32 funcref) (result funcref)))
;; CHECK: (type $1 (func_subtype (param f32 (ref $1)) (result (ref $0)) func))
(type $1 (func (param f32 funcref) (result funcref)))
;; CHECK: (elem declare func $bar $foo)
;; CHECK: (func $foo (type $0) (param $0 i32) (param $1 (ref $0)) (result (ref $1))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $foo
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (ref.func $foo)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.func $bar)
;; CHECK-NEXT: )
(func $foo (type $0) (param i32 funcref) (result funcref)
(drop
(call $foo
(i32.const 0)
(ref.func $foo)
)
)
(ref.func $bar)
)
;; CHECK: (func $bar (type $1) (param $0 f32) (param $1 (ref $1)) (result (ref $0))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $bar
;; CHECK-NEXT: (f32.const 0)
;; CHECK-NEXT: (ref.func $bar)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.func $foo)
;; CHECK-NEXT: )
(func $bar (type $1) (param f32 funcref) (result funcref)
(drop
(call $bar
(f32.const 0)
(ref.func $bar)
)
)
(ref.func $foo)
)
)
(module
;; The signatures start out as separate types, so they must remain separate
;; even though they are refined to the same structure.
(rec
;; CHECK: (rec
;; CHECK-NEXT: (type $0 (func_subtype (param (ref $0)) func))
(type $0 (func (param funcref)))
;; CHECK: (type $1 (func_subtype (param (ref $0)) func))
(type $1 (func (param funcref)))
)
;; CHECK: (elem declare func $foo)
;; CHECK: (func $foo (type $0) (param $0 (ref $0))
;; CHECK-NEXT: (call $foo
;; CHECK-NEXT: (ref.func $foo)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $foo (type $0) (param funcref)
(call $foo
(ref.func $foo)
)
)
;; CHECK: (func $bar (type $1) (param $0 (ref $0))
;; CHECK-NEXT: (call $bar
;; CHECK-NEXT: (ref.func $foo)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $bar (type $1) (param funcref)
(call $bar
(ref.func $foo)
)
)
)
(module
;; The signatures should be refined to a pair of mutually recursive types and
;; another type that refers to them.
;; CHECK: (rec
;; CHECK-NEXT: (type $1 (func_subtype (param f32 (ref $1)) (result (ref $0)) func))
;; CHECK: (type $0 (func_subtype (param i32 (ref $0)) (result (ref $1)) func))
(type $0 (func (param i32 funcref) (result funcref)))
(type $1 (func (param f32 funcref) (result funcref)))
;; CHECK: (type $2 (func_subtype (param (ref $0)) (result (ref $1)) func))
(type $2 (func (param funcref) (result funcref)))
;; CHECK: (elem declare func $bar $foo)
;; CHECK: (func $foo (type $0) (param $0 i32) (param $1 (ref $0)) (result (ref $1))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $foo
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (ref.func $foo)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.func $bar)
;; CHECK-NEXT: )
(func $foo (param i32 funcref) (result funcref)
(drop
(call $foo
(i32.const 0)
(ref.func $foo)
)
)
(ref.func $bar)
)
;; CHECK: (func $baz (type $2) (param $0 (ref $0)) (result (ref $1))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $quux
;; CHECK-NEXT: (ref.func $foo)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.func $bar)
;; CHECK-NEXT: )
(func $baz (param funcref) (result funcref)
(drop
(call $quux
(ref.func $foo)
)
)
(ref.func $bar)
)
;; CHECK: (func $bar (type $1) (param $0 f32) (param $1 (ref $1)) (result (ref $0))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $bar
;; CHECK-NEXT: (f32.const 0)
;; CHECK-NEXT: (ref.func $bar)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.func $foo)
;; CHECK-NEXT: )
(func $bar (param f32 funcref) (result funcref)
(drop
(call $bar
(f32.const 0)
(ref.func $bar)
)
)
(ref.func $foo)
)
;; CHECK: (func $quux (type $2) (param $0 (ref $0)) (result (ref $1))
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $baz
;; CHECK-NEXT: (ref.func $foo)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.func $bar)
;; CHECK-NEXT: )
(func $quux (param funcref) (result funcref)
(drop
(call $baz
(ref.func $foo)
)
)
(ref.func $bar)
)
)