;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. ;; RUN: foreach %s %t wasm-opt --signature-refining -all -S -o - | filecheck %s (module ;; The signature should be refined to a single self-referential type. ;; CHECK: (type $refined (func (param (ref $refined)) (result (ref $refined)))) (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 $1 (func (param f32 (ref $1)) (result (ref $0)))) ;; CHECK: (type $0 (func (param i32 (ref $0)) (result (ref $1)))) (type $0 (func (param i32 funcref) (result funcref))) (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 $1 (func (param (ref $0)))) ;; CHECK: (type $0 (func (param (ref $0)))) (type $0 (func (param funcref))) (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 $2 (func (param (ref $0)) (result (ref $1)))) ;; CHECK: (type $1 (func (param f32 (ref $1)) (result (ref $0)))) ;; CHECK: (type $0 (func (param i32 (ref $0)) (result (ref $1)))) (type $0 (func (param i32 funcref) (result funcref))) (type $1 (func (param f32 funcref) (result funcref))) (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) ) )