;; 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 $__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:  (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:  (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:  (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: )
  ;; 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 $__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:  (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:  (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:  (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 $__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:  (call $full-maybe-inline
  ;; NO_FULL-NEXT:   (i32.const 1)
  ;; NO_FULL-NEXT:  )
  ;; 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:  (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_BOTH:      (func $caller
  ;; NO_BOTH-NEXT:  (local $0 i32)
  ;; NO_BOTH-NEXT:  (local $1 i32)
  ;; 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:  (call $full-maybe-inline
  ;; NO_BOTH-NEXT:   (i32.const 1)
  ;; NO_BOTH-NEXT:  )
  ;; 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:  (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 $__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:  (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:  (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:  (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: )
  ;; 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 $__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:  (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:  (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:  (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 $__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:  (call $full-maybe-inline
  ;; NO_FULL-NEXT:   (i32.const 1)
  ;; NO_FULL-NEXT:  )
  ;; 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:  (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_BOTH:      (func $caller-2
  ;; NO_BOTH-NEXT:  (local $0 i32)
  ;; NO_BOTH-NEXT:  (local $1 i32)
  ;; 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:  (call $full-maybe-inline
  ;; NO_BOTH-NEXT:   (i32.const 1)
  ;; NO_BOTH-NEXT:  )
  ;; 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:  (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 $__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:  (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:  (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:  (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: )
 ;; 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 $__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:  (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:  (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:  (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_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: )
