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