;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. ;; Enable both full and partial inlining, and show how we filter out functions ;; using --no-*-inline. The functions with "yes" in their names will always be ;; inlined, while the ones with "maybe" will be filtered out in some modes. ;; RUN: foreach %s %t wasm-opt --inlining --optimize-level=3 --partial-inlining-ifs=1 -S -o - | filecheck %s --check-prefix YES_ALL ;; RUN: foreach %s %t wasm-opt --no-partial-inline=*maybe* --inlining --optimize-level=3 --partial-inlining-ifs=1 -S -o - | filecheck %s --check-prefix NO_PART ;; RUN: foreach %s %t wasm-opt --no-full-inline=*maybe* --inlining --optimize-level=3 --partial-inlining-ifs=1 -S -o - | filecheck %s --check-prefix NO_FULL ;; RUN: foreach %s %t wasm-opt --no-inline=*maybe* --inlining --optimize-level=3 --partial-inlining-ifs=1 -S -o - | filecheck %s --check-prefix NO_BOTH (module ;; YES_ALL: (type $0 (func)) ;; YES_ALL: (type $1 (func (param i32))) ;; YES_ALL: (import "a" "b" (func $import)) ;; NO_PART: (type $0 (func)) ;; NO_PART: (type $1 (func (param i32))) ;; NO_PART: (import "a" "b" (func $import)) ;; NO_FULL: (type $0 (func)) ;; NO_FULL: (type $1 (func (param i32))) ;; NO_FULL: (import "a" "b" (func $import)) ;; NO_BOTH: (type $0 (func)) ;; NO_BOTH: (type $1 (func (param i32))) ;; NO_BOTH: (import "a" "b" (func $import)) (import "a" "b" (func $import)) (func $full-yes-inline (param $x i32) (call $import) ) ;; NO_FULL: (func $full-maybe-inline (param $x i32) ;; NO_FULL-NEXT: (call $import) ;; NO_FULL-NEXT: ) ;; NO_BOTH: (func $full-maybe-inline (param $x i32) ;; NO_BOTH-NEXT: (call $import) ;; NO_BOTH-NEXT: ) (func $full-maybe-inline (param $x i32) (call $import) ) (func $partial-yes-inline (param $x i32) (if (local.get $x) (then (return) ) ) (loop $l (call $import) (br $l) ) ) ;; NO_PART: (func $partial-maybe-inline (param $x i32) ;; NO_PART-NEXT: (if ;; NO_PART-NEXT: (local.get $x) ;; NO_PART-NEXT: (then ;; NO_PART-NEXT: (return) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (loop $l ;; NO_PART-NEXT: (call $import) ;; NO_PART-NEXT: (br $l) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_BOTH: (func $partial-maybe-inline (param $x i32) ;; NO_BOTH-NEXT: (if ;; NO_BOTH-NEXT: (local.get $x) ;; NO_BOTH-NEXT: (then ;; NO_BOTH-NEXT: (return) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (loop $l ;; NO_BOTH-NEXT: (call $import) ;; NO_BOTH-NEXT: (br $l) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) (func $partial-maybe-inline (param $x i32) (if (local.get $x) (then (return) ) ) (loop $l (call $import) (br $l) ) ) ;; YES_ALL: (func $caller ;; YES_ALL-NEXT: (local $0 i32) ;; YES_ALL-NEXT: (local $1 i32) ;; YES_ALL-NEXT: (local $2 i32) ;; YES_ALL-NEXT: (local $3 i32) ;; YES_ALL-NEXT: (block ;; YES_ALL-NEXT: (block $__inlined_func$full-yes-inline ;; YES_ALL-NEXT: (local.set $0 ;; YES_ALL-NEXT: (i32.const 0) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (call $import) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (block ;; YES_ALL-NEXT: (block $__inlined_func$full-maybe-inline$1 ;; YES_ALL-NEXT: (local.set $1 ;; YES_ALL-NEXT: (i32.const 1) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (call $import) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (block ;; YES_ALL-NEXT: (block $__inlined_func$byn-split-inlineable-A$partial-yes-inline$2 ;; YES_ALL-NEXT: (local.set $2 ;; YES_ALL-NEXT: (i32.const 2) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (if ;; YES_ALL-NEXT: (i32.eqz ;; YES_ALL-NEXT: (local.get $2) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (then ;; YES_ALL-NEXT: (call $byn-split-outlined-A$partial-yes-inline ;; YES_ALL-NEXT: (local.get $2) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (block ;; YES_ALL-NEXT: (block $__inlined_func$byn-split-inlineable-A$partial-maybe-inline$3 ;; YES_ALL-NEXT: (local.set $3 ;; YES_ALL-NEXT: (i32.const 3) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (if ;; YES_ALL-NEXT: (i32.eqz ;; YES_ALL-NEXT: (local.get $3) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (then ;; YES_ALL-NEXT: (call $byn-split-outlined-A$partial-maybe-inline ;; YES_ALL-NEXT: (local.get $3) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; NO_PART: (func $caller ;; NO_PART-NEXT: (local $0 i32) ;; NO_PART-NEXT: (local $1 i32) ;; NO_PART-NEXT: (local $2 i32) ;; NO_PART-NEXT: (block ;; NO_PART-NEXT: (block $__inlined_func$full-yes-inline ;; NO_PART-NEXT: (local.set $0 ;; NO_PART-NEXT: (i32.const 0) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (call $import) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (block ;; NO_PART-NEXT: (block $__inlined_func$full-maybe-inline$1 ;; NO_PART-NEXT: (local.set $1 ;; NO_PART-NEXT: (i32.const 1) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (call $import) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (block ;; NO_PART-NEXT: (block $__inlined_func$byn-split-inlineable-A$partial-yes-inline$2 ;; NO_PART-NEXT: (local.set $2 ;; NO_PART-NEXT: (i32.const 2) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (if ;; NO_PART-NEXT: (i32.eqz ;; NO_PART-NEXT: (local.get $2) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (then ;; NO_PART-NEXT: (call $byn-split-outlined-A$partial-yes-inline ;; NO_PART-NEXT: (local.get $2) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (call $partial-maybe-inline ;; NO_PART-NEXT: (i32.const 3) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_FULL: (func $caller ;; NO_FULL-NEXT: (local $0 i32) ;; NO_FULL-NEXT: (local $1 i32) ;; NO_FULL-NEXT: (local $2 i32) ;; NO_FULL-NEXT: (block ;; NO_FULL-NEXT: (block $__inlined_func$full-yes-inline ;; NO_FULL-NEXT: (local.set $0 ;; NO_FULL-NEXT: (i32.const 0) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (call $import) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (call $full-maybe-inline ;; NO_FULL-NEXT: (i32.const 1) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (block ;; NO_FULL-NEXT: (block $__inlined_func$byn-split-inlineable-A$partial-yes-inline$1 ;; NO_FULL-NEXT: (local.set $1 ;; NO_FULL-NEXT: (i32.const 2) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (if ;; NO_FULL-NEXT: (i32.eqz ;; NO_FULL-NEXT: (local.get $1) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (then ;; NO_FULL-NEXT: (call $byn-split-outlined-A$partial-yes-inline ;; NO_FULL-NEXT: (local.get $1) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (block ;; NO_FULL-NEXT: (block $__inlined_func$byn-split-inlineable-A$partial-maybe-inline$2 ;; NO_FULL-NEXT: (local.set $2 ;; NO_FULL-NEXT: (i32.const 3) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (if ;; NO_FULL-NEXT: (i32.eqz ;; NO_FULL-NEXT: (local.get $2) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (then ;; NO_FULL-NEXT: (call $byn-split-outlined-A$partial-maybe-inline ;; NO_FULL-NEXT: (local.get $2) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_BOTH: (func $caller ;; NO_BOTH-NEXT: (local $0 i32) ;; NO_BOTH-NEXT: (local $1 i32) ;; NO_BOTH-NEXT: (block ;; NO_BOTH-NEXT: (block $__inlined_func$full-yes-inline ;; NO_BOTH-NEXT: (local.set $0 ;; NO_BOTH-NEXT: (i32.const 0) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (call $import) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (call $full-maybe-inline ;; NO_BOTH-NEXT: (i32.const 1) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (block ;; NO_BOTH-NEXT: (block $__inlined_func$byn-split-inlineable-A$partial-yes-inline$1 ;; NO_BOTH-NEXT: (local.set $1 ;; NO_BOTH-NEXT: (i32.const 2) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (if ;; NO_BOTH-NEXT: (i32.eqz ;; NO_BOTH-NEXT: (local.get $1) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (then ;; NO_BOTH-NEXT: (call $byn-split-outlined-A$partial-yes-inline ;; NO_BOTH-NEXT: (local.get $1) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (call $partial-maybe-inline ;; NO_BOTH-NEXT: (i32.const 3) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) (func $caller (call $full-yes-inline (i32.const 0) ) (call $full-maybe-inline (i32.const 1) ) (call $partial-yes-inline (i32.const 2) ) (call $partial-maybe-inline (i32.const 3) ) ) ;; YES_ALL: (func $caller-2 ;; YES_ALL-NEXT: (local $0 i32) ;; YES_ALL-NEXT: (local $1 i32) ;; YES_ALL-NEXT: (local $2 i32) ;; YES_ALL-NEXT: (local $3 i32) ;; YES_ALL-NEXT: (block ;; YES_ALL-NEXT: (block $__inlined_func$full-yes-inline$4 ;; YES_ALL-NEXT: (local.set $0 ;; YES_ALL-NEXT: (i32.const 0) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (call $import) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (block ;; YES_ALL-NEXT: (block $__inlined_func$full-maybe-inline$5 ;; YES_ALL-NEXT: (local.set $1 ;; YES_ALL-NEXT: (i32.const 1) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (call $import) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (block ;; YES_ALL-NEXT: (block $__inlined_func$byn-split-inlineable-A$partial-yes-inline$6 ;; YES_ALL-NEXT: (local.set $2 ;; YES_ALL-NEXT: (i32.const 2) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (if ;; YES_ALL-NEXT: (i32.eqz ;; YES_ALL-NEXT: (local.get $2) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (then ;; YES_ALL-NEXT: (call $byn-split-outlined-A$partial-yes-inline ;; YES_ALL-NEXT: (local.get $2) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (block ;; YES_ALL-NEXT: (block $__inlined_func$byn-split-inlineable-A$partial-maybe-inline$7 ;; YES_ALL-NEXT: (local.set $3 ;; YES_ALL-NEXT: (i32.const 3) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (if ;; YES_ALL-NEXT: (i32.eqz ;; YES_ALL-NEXT: (local.get $3) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (then ;; YES_ALL-NEXT: (call $byn-split-outlined-A$partial-maybe-inline ;; YES_ALL-NEXT: (local.get $3) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; NO_PART: (func $caller-2 ;; NO_PART-NEXT: (local $0 i32) ;; NO_PART-NEXT: (local $1 i32) ;; NO_PART-NEXT: (local $2 i32) ;; NO_PART-NEXT: (block ;; NO_PART-NEXT: (block $__inlined_func$full-yes-inline$3 ;; NO_PART-NEXT: (local.set $0 ;; NO_PART-NEXT: (i32.const 0) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (call $import) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (block ;; NO_PART-NEXT: (block $__inlined_func$full-maybe-inline$4 ;; NO_PART-NEXT: (local.set $1 ;; NO_PART-NEXT: (i32.const 1) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (call $import) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (block ;; NO_PART-NEXT: (block $__inlined_func$byn-split-inlineable-A$partial-yes-inline$5 ;; NO_PART-NEXT: (local.set $2 ;; NO_PART-NEXT: (i32.const 2) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (if ;; NO_PART-NEXT: (i32.eqz ;; NO_PART-NEXT: (local.get $2) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (then ;; NO_PART-NEXT: (call $byn-split-outlined-A$partial-yes-inline ;; NO_PART-NEXT: (local.get $2) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (call $partial-maybe-inline ;; NO_PART-NEXT: (i32.const 3) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_FULL: (func $caller-2 ;; NO_FULL-NEXT: (local $0 i32) ;; NO_FULL-NEXT: (local $1 i32) ;; NO_FULL-NEXT: (local $2 i32) ;; NO_FULL-NEXT: (block ;; NO_FULL-NEXT: (block $__inlined_func$full-yes-inline$3 ;; NO_FULL-NEXT: (local.set $0 ;; NO_FULL-NEXT: (i32.const 0) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (call $import) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (call $full-maybe-inline ;; NO_FULL-NEXT: (i32.const 1) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (block ;; NO_FULL-NEXT: (block $__inlined_func$byn-split-inlineable-A$partial-yes-inline$4 ;; NO_FULL-NEXT: (local.set $1 ;; NO_FULL-NEXT: (i32.const 2) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (if ;; NO_FULL-NEXT: (i32.eqz ;; NO_FULL-NEXT: (local.get $1) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (then ;; NO_FULL-NEXT: (call $byn-split-outlined-A$partial-yes-inline ;; NO_FULL-NEXT: (local.get $1) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (block ;; NO_FULL-NEXT: (block $__inlined_func$byn-split-inlineable-A$partial-maybe-inline$5 ;; NO_FULL-NEXT: (local.set $2 ;; NO_FULL-NEXT: (i32.const 3) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (if ;; NO_FULL-NEXT: (i32.eqz ;; NO_FULL-NEXT: (local.get $2) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (then ;; NO_FULL-NEXT: (call $byn-split-outlined-A$partial-maybe-inline ;; NO_FULL-NEXT: (local.get $2) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_BOTH: (func $caller-2 ;; NO_BOTH-NEXT: (local $0 i32) ;; NO_BOTH-NEXT: (local $1 i32) ;; NO_BOTH-NEXT: (block ;; NO_BOTH-NEXT: (block $__inlined_func$full-yes-inline$2 ;; NO_BOTH-NEXT: (local.set $0 ;; NO_BOTH-NEXT: (i32.const 0) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (call $import) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (call $full-maybe-inline ;; NO_BOTH-NEXT: (i32.const 1) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (block ;; NO_BOTH-NEXT: (block $__inlined_func$byn-split-inlineable-A$partial-yes-inline$3 ;; NO_BOTH-NEXT: (local.set $1 ;; NO_BOTH-NEXT: (i32.const 2) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (if ;; NO_BOTH-NEXT: (i32.eqz ;; NO_BOTH-NEXT: (local.get $1) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (then ;; NO_BOTH-NEXT: (call $byn-split-outlined-A$partial-yes-inline ;; NO_BOTH-NEXT: (local.get $1) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (call $partial-maybe-inline ;; NO_BOTH-NEXT: (i32.const 3) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) (func $caller-2 ;; Same as $caller, to prevent the functions from having a single use (which ;; is always inlined). (call $full-yes-inline (i32.const 0) ) (call $full-maybe-inline (i32.const 1) ) (call $partial-yes-inline (i32.const 2) ) (call $partial-maybe-inline (i32.const 3) ) ) ) ;; YES_ALL: (func $byn-split-outlined-A$partial-yes-inline (param $x i32) ;; YES_ALL-NEXT: (loop $l ;; YES_ALL-NEXT: (call $import) ;; YES_ALL-NEXT: (br $l) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL: (func $byn-split-outlined-A$partial-maybe-inline (param $x i32) ;; YES_ALL-NEXT: (loop $l ;; YES_ALL-NEXT: (call $import) ;; YES_ALL-NEXT: (br $l) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; NO_PART: (func $byn-split-outlined-A$partial-yes-inline (param $x i32) ;; NO_PART-NEXT: (loop $l ;; NO_PART-NEXT: (call $import) ;; NO_PART-NEXT: (br $l) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_FULL: (func $byn-split-outlined-A$partial-yes-inline (param $x i32) ;; NO_FULL-NEXT: (loop $l ;; NO_FULL-NEXT: (call $import) ;; NO_FULL-NEXT: (br $l) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL: (func $byn-split-outlined-A$partial-maybe-inline (param $x i32) ;; NO_FULL-NEXT: (loop $l ;; NO_FULL-NEXT: (call $import) ;; NO_FULL-NEXT: (br $l) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_BOTH: (func $byn-split-outlined-A$partial-yes-inline (param $x i32) ;; NO_BOTH-NEXT: (loop $l ;; NO_BOTH-NEXT: (call $import) ;; NO_BOTH-NEXT: (br $l) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) (module ;; YES_ALL: (type $0 (func)) ;; YES_ALL: (import "out" "func" (func $import)) ;; NO_PART: (type $0 (func)) ;; NO_PART: (type $1 (func (param i32))) ;; NO_PART: (import "out" "func" (func $import)) ;; NO_FULL: (type $0 (func)) ;; NO_FULL: (type $1 (func (param i32))) ;; NO_FULL: (import "out" "func" (func $import)) ;; NO_BOTH: (type $0 (func)) ;; NO_BOTH: (type $1 (func (param i32))) ;; NO_BOTH: (import "out" "func" (func $import)) (import "out" "func" (func $import)) ;; NO_PART: (func $maybe-partial-or-full-1 (param $x i32) ;; NO_PART-NEXT: (if ;; NO_PART-NEXT: (local.get $x) ;; NO_PART-NEXT: (then ;; NO_PART-NEXT: (call $import) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_BOTH: (func $maybe-partial-or-full-1 (param $x i32) ;; NO_BOTH-NEXT: (if ;; NO_BOTH-NEXT: (local.get $x) ;; NO_BOTH-NEXT: (then ;; NO_BOTH-NEXT: (call $import) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) (func $maybe-partial-or-full-1 (param $x i32) ;; This function can be partially inlined, but after doing so we want to ;; inline the remainder as well, so instead we fully inline it. When full ;; inlining is disabled but partial inlining is enabled, we should only ;; partially inline it. (if (local.get $x) (then (call $import) ) ) ) ;; NO_PART: (func $maybe-partial-or-full-2 (param $x i32) ;; NO_PART-NEXT: (if ;; NO_PART-NEXT: (local.get $x) ;; NO_PART-NEXT: (then ;; NO_PART-NEXT: (return) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (nop) ;; NO_PART-NEXT: (drop ;; NO_PART-NEXT: (i32.const 0) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (drop ;; NO_PART-NEXT: (i32.const 0) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (drop ;; NO_PART-NEXT: (i32.const 0) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (drop ;; NO_PART-NEXT: (i32.const 0) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (drop ;; NO_PART-NEXT: (i32.const 0) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (drop ;; NO_PART-NEXT: (i32.const 0) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (drop ;; NO_PART-NEXT: (i32.const 0) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (drop ;; NO_PART-NEXT: (i32.const 0) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_BOTH: (func $maybe-partial-or-full-2 (param $x i32) ;; NO_BOTH-NEXT: (if ;; NO_BOTH-NEXT: (local.get $x) ;; NO_BOTH-NEXT: (then ;; NO_BOTH-NEXT: (return) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (nop) ;; NO_BOTH-NEXT: (drop ;; NO_BOTH-NEXT: (i32.const 0) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (drop ;; NO_BOTH-NEXT: (i32.const 0) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (drop ;; NO_BOTH-NEXT: (i32.const 0) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (drop ;; NO_BOTH-NEXT: (i32.const 0) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (drop ;; NO_BOTH-NEXT: (i32.const 0) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (drop ;; NO_BOTH-NEXT: (i32.const 0) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (drop ;; NO_BOTH-NEXT: (i32.const 0) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (drop ;; NO_BOTH-NEXT: (i32.const 0) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) (func $maybe-partial-or-full-2 (param $x i32) ;; As above, but for another form of partial inlining. Here we need to add ;; some extra things to the function size for partial inlining to kick in. (if (local.get $x) (then (return) ) ) (nop) (drop (i32.const 0) ) (drop (i32.const 0) ) (drop (i32.const 0) ) (drop (i32.const 0) ) (drop (i32.const 0) ) (drop (i32.const 0) ) (drop (i32.const 0) ) (drop (i32.const 0) ) ) ;; YES_ALL: (func $caller ;; YES_ALL-NEXT: (local $0 i32) ;; YES_ALL-NEXT: (local $1 i32) ;; YES_ALL-NEXT: (local $2 i32) ;; YES_ALL-NEXT: (local $3 i32) ;; YES_ALL-NEXT: (block ;; YES_ALL-NEXT: (block $__inlined_func$maybe-partial-or-full-1 ;; YES_ALL-NEXT: (local.set $0 ;; YES_ALL-NEXT: (i32.const 0) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (if ;; YES_ALL-NEXT: (local.get $0) ;; YES_ALL-NEXT: (then ;; YES_ALL-NEXT: (call $import) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (block ;; YES_ALL-NEXT: (block $__inlined_func$maybe-partial-or-full-1$1 ;; YES_ALL-NEXT: (local.set $1 ;; YES_ALL-NEXT: (i32.const 1) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (if ;; YES_ALL-NEXT: (local.get $1) ;; YES_ALL-NEXT: (then ;; YES_ALL-NEXT: (call $import) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (block ;; YES_ALL-NEXT: (block $__inlined_func$maybe-partial-or-full-2$2 ;; YES_ALL-NEXT: (local.set $2 ;; YES_ALL-NEXT: (i32.const 0) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (block ;; YES_ALL-NEXT: (if ;; YES_ALL-NEXT: (local.get $2) ;; YES_ALL-NEXT: (then ;; YES_ALL-NEXT: (br $__inlined_func$maybe-partial-or-full-2$2) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (nop) ;; YES_ALL-NEXT: (drop ;; YES_ALL-NEXT: (i32.const 0) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (drop ;; YES_ALL-NEXT: (i32.const 0) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (drop ;; YES_ALL-NEXT: (i32.const 0) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (drop ;; YES_ALL-NEXT: (i32.const 0) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (drop ;; YES_ALL-NEXT: (i32.const 0) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (drop ;; YES_ALL-NEXT: (i32.const 0) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (drop ;; YES_ALL-NEXT: (i32.const 0) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (drop ;; YES_ALL-NEXT: (i32.const 0) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (block ;; YES_ALL-NEXT: (block $__inlined_func$maybe-partial-or-full-2$3 ;; YES_ALL-NEXT: (local.set $3 ;; YES_ALL-NEXT: (i32.const 1) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (block ;; YES_ALL-NEXT: (if ;; YES_ALL-NEXT: (local.get $3) ;; YES_ALL-NEXT: (then ;; YES_ALL-NEXT: (br $__inlined_func$maybe-partial-or-full-2$3) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (nop) ;; YES_ALL-NEXT: (drop ;; YES_ALL-NEXT: (i32.const 0) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (drop ;; YES_ALL-NEXT: (i32.const 0) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (drop ;; YES_ALL-NEXT: (i32.const 0) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (drop ;; YES_ALL-NEXT: (i32.const 0) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (drop ;; YES_ALL-NEXT: (i32.const 0) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (drop ;; YES_ALL-NEXT: (i32.const 0) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (drop ;; YES_ALL-NEXT: (i32.const 0) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: (drop ;; YES_ALL-NEXT: (i32.const 0) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; YES_ALL-NEXT: ) ;; NO_PART: (func $caller ;; NO_PART-NEXT: (call $maybe-partial-or-full-1 ;; NO_PART-NEXT: (i32.const 0) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (call $maybe-partial-or-full-1 ;; NO_PART-NEXT: (i32.const 1) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (call $maybe-partial-or-full-2 ;; NO_PART-NEXT: (i32.const 0) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: (call $maybe-partial-or-full-2 ;; NO_PART-NEXT: (i32.const 1) ;; NO_PART-NEXT: ) ;; NO_PART-NEXT: ) ;; NO_FULL: (func $caller ;; NO_FULL-NEXT: (local $0 i32) ;; NO_FULL-NEXT: (local $1 i32) ;; NO_FULL-NEXT: (local $2 i32) ;; NO_FULL-NEXT: (local $3 i32) ;; NO_FULL-NEXT: (block ;; NO_FULL-NEXT: (block $__inlined_func$byn-split-inlineable-B$maybe-partial-or-full-1 ;; NO_FULL-NEXT: (local.set $0 ;; NO_FULL-NEXT: (i32.const 0) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (if ;; NO_FULL-NEXT: (local.get $0) ;; NO_FULL-NEXT: (then ;; NO_FULL-NEXT: (call $byn-split-outlined-B$maybe-partial-or-full-1 ;; NO_FULL-NEXT: (local.get $0) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (block ;; NO_FULL-NEXT: (block $__inlined_func$byn-split-inlineable-B$maybe-partial-or-full-1$1 ;; NO_FULL-NEXT: (local.set $1 ;; NO_FULL-NEXT: (i32.const 1) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (if ;; NO_FULL-NEXT: (local.get $1) ;; NO_FULL-NEXT: (then ;; NO_FULL-NEXT: (call $byn-split-outlined-B$maybe-partial-or-full-1 ;; NO_FULL-NEXT: (local.get $1) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (block ;; NO_FULL-NEXT: (block $__inlined_func$byn-split-inlineable-A$maybe-partial-or-full-2$2 ;; NO_FULL-NEXT: (local.set $2 ;; NO_FULL-NEXT: (i32.const 0) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (if ;; NO_FULL-NEXT: (i32.eqz ;; NO_FULL-NEXT: (local.get $2) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (then ;; NO_FULL-NEXT: (call $byn-split-outlined-A$maybe-partial-or-full-2 ;; NO_FULL-NEXT: (local.get $2) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (block ;; NO_FULL-NEXT: (block $__inlined_func$byn-split-inlineable-A$maybe-partial-or-full-2$3 ;; NO_FULL-NEXT: (local.set $3 ;; NO_FULL-NEXT: (i32.const 1) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (if ;; NO_FULL-NEXT: (i32.eqz ;; NO_FULL-NEXT: (local.get $3) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (then ;; NO_FULL-NEXT: (call $byn-split-outlined-A$maybe-partial-or-full-2 ;; NO_FULL-NEXT: (local.get $3) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: ) ;; NO_BOTH: (func $caller ;; NO_BOTH-NEXT: (call $maybe-partial-or-full-1 ;; NO_BOTH-NEXT: (i32.const 0) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (call $maybe-partial-or-full-1 ;; NO_BOTH-NEXT: (i32.const 1) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (call $maybe-partial-or-full-2 ;; NO_BOTH-NEXT: (i32.const 0) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: (call $maybe-partial-or-full-2 ;; NO_BOTH-NEXT: (i32.const 1) ;; NO_BOTH-NEXT: ) ;; NO_BOTH-NEXT: ) (func $caller ;; In YES_ALL we will fully inline all of these. In NO_FULL we will partially ;; inline. In NO_PART and NO_BOTH we will not inline at all (in theory we ;; could do full inlining when only partial inlining is disabled, but we only ;; see that full inlining is possible as a result of partial inlining, so if ;; partial is disabled we don't get there, and full inlining is not ;; justified). (call $maybe-partial-or-full-1 (i32.const 0) ) (call $maybe-partial-or-full-1 (i32.const 1) ) (call $maybe-partial-or-full-2 (i32.const 0) ) (call $maybe-partial-or-full-2 (i32.const 1) ) ) ) ;; NO_FULL: (func $byn-split-outlined-B$maybe-partial-or-full-1 (param $x i32) ;; NO_FULL-NEXT: (call $import) ;; NO_FULL-NEXT: ) ;; NO_FULL: (func $byn-split-outlined-A$maybe-partial-or-full-2 (param $x i32) ;; NO_FULL-NEXT: (nop) ;; NO_FULL-NEXT: (drop ;; NO_FULL-NEXT: (i32.const 0) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (drop ;; NO_FULL-NEXT: (i32.const 0) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (drop ;; NO_FULL-NEXT: (i32.const 0) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (drop ;; NO_FULL-NEXT: (i32.const 0) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (drop ;; NO_FULL-NEXT: (i32.const 0) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (drop ;; NO_FULL-NEXT: (i32.const 0) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (drop ;; NO_FULL-NEXT: (i32.const 0) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: (drop ;; NO_FULL-NEXT: (i32.const 0) ;; NO_FULL-NEXT: ) ;; NO_FULL-NEXT: )