blob: 860f5b8f75f398635137533742ecdf1e06c90dc5 [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 --inlining --all-features -S -o - | filecheck %s
(module
;; CHECK: (type $0 (func))
;; CHECK: (type $1 (func (result funcref)))
;; CHECK: (elem declare func $foo)
;; CHECK: (export "ref_func_test" (func $ref_func_test))
(export "ref_func_test" (func $ref_func_test))
;; $foo should not be removed after being inlined, because there is 'ref.func'
;; instruction that refers to it
;; CHECK: (func $foo (type $0)
;; CHECK-NEXT: )
(func $foo)
;; CHECK: (func $ref_func_test (type $1) (result funcref)
;; CHECK-NEXT: (block $__inlined_func$foo
;; CHECK-NEXT: (block
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.func $foo)
;; CHECK-NEXT: )
(func $ref_func_test (result funcref)
(call $foo)
(ref.func $foo)
)
)
(module
;; a function reference in a global's init should be noticed, and prevent us
;; from removing an inlined function
;; CHECK: (type $0 (func (result i32)))
;; CHECK: (global $global$0 (mut funcref) (ref.func $0))
(global $global$0 (mut funcref) (ref.func $0))
;; CHECK: (func $0 (type $0) (result i32)
;; CHECK-NEXT: (i32.const 1337)
;; CHECK-NEXT: )
(func $0 (result i32)
(i32.const 1337)
)
;; CHECK: (func $1 (type $0) (result i32)
;; CHECK-NEXT: (block $__inlined_func$0 (result i32)
;; CHECK-NEXT: (i32.const 1337)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $1 (result i32)
(call $0)
)
)
(module
;; a function reference in the start should be noticed, and prevent us
;; from removing an inlined function
;; CHECK: (type $0 (func))
;; CHECK: (start $0)
(start $0)
;; CHECK: (func $0 (type $0)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
(func $0
(nop)
)
;; CHECK: (func $1 (type $0)
;; CHECK-NEXT: (block $__inlined_func$0
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $1
(call $0)
)
)
;; inline a return_call_ref
(module
;; CHECK: (type $none_=>_none (func))
(type $none_=>_none (func))
;; CHECK: (export "func_36_invoker" (func $1))
(export "func_36_invoker" (func $1))
(func $0
(return_call_ref $none_=>_none
(ref.null $none_=>_none)
)
)
;; CHECK: (func $1 (type $none_=>_none)
;; CHECK-NEXT: (block $__inlined_func$0
;; CHECK-NEXT: (block ;; (replaces unreachable CallRef we can't emit)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.null nofunc)
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $1
(call $0)
)
)
;; handle non-nullable parameter types (which turn into local types after
;; inlining)
(module
(func $0 (param $non-null (ref func)) (result (ref func))
(local.get $non-null)
)
;; CHECK: (type $0 (func (result (ref func))))
;; CHECK: (elem declare func $1)
;; CHECK: (func $1 (type $0) (result (ref func))
;; CHECK-NEXT: (local $0 (ref func))
;; CHECK-NEXT: (block $__inlined_func$0 (result (ref func))
;; CHECK-NEXT: (local.set $0
;; CHECK-NEXT: (ref.func $1)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $1 (result (ref func))
(call $0
(ref.func $1)
)
)
)
;; Test handling of nested inlined calls.
(module
(func $callee-a (param i32))
(func $callee-b (param $x i32) (result i32)
(local.get $x)
)
;; CHECK: (type $0 (func))
;; CHECK: (func $caller-with-pop-twice (type $0)
;; CHECK-NEXT: (local $0 i32)
;; CHECK-NEXT: (local $1 i32)
;; CHECK-NEXT: (block $__inlined_func$callee-a$1
;; CHECK-NEXT: (local.set $1
;; CHECK-NEXT: (block $__inlined_func$callee-b (result i32)
;; CHECK-NEXT: (local.set $0
;; CHECK-NEXT: (i32.const 42)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (block
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $caller-with-pop-twice
;; Both these calls should be inlined.
(call $callee-a
(call $callee-b
(i32.const 42)
)
)
)
)