| ;; 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) |
| ) |
| ) |