;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.

;; RUN: foreach %s %t wasm-opt --inlining --optimize-level=3 --partial-inlining-ifs=4 --all-features -S -o - | filecheck %s

(module
  ;; CHECK:      (type $0 (func))

  ;; CHECK:      (type $1 (func (param i32)))

  ;; CHECK:      (type $2 (func (param anyref) (result anyref)))

  ;; CHECK:      (type $3 (func (param anyref)))

  ;; CHECK:      (type $struct (struct))
  (type $struct (struct))

  ;; CHECK:      (type $5 (func (param i64 i32 f64)))

  ;; CHECK:      (import "out" "func" (func $import (type $0)))
  (import "out" "func" (func $import))

  ;; CHECK:      (global $glob i32 (i32.const 1))
  (global $glob i32 (i32.const 1))

  ;; CHECK:      (start $start-used-globally)
  (start $start-used-globally)

  ;; Pattern A: functions beginning with
  ;;
  ;;   if (simple) return;

  (func $maybe-work-hard (param $x i32)
    ;; A function that does a quick check before any heavy work. We can outline
    ;; the heavy work, so that the condition can be inlined.
    ;;
    ;; This function (and others lower down that we also optimize) will vanish
    ;; in the output. Part of it will be inlined into its caller, below, and
    ;; the rest will be outlined into a new function with suffix "outlined".
    (if
      (local.get $x)
      (then
        (return)
      )
    )
    (loop $l
      (call $import)
      (br $l)
    )
  )

  ;; CHECK:      (func $call-maybe-work-hard (type $0)
  ;; CHECK-NEXT:  (local $0 i32)
  ;; CHECK-NEXT:  (local $1 i32)
  ;; CHECK-NEXT:  (local $2 i32)
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-A$maybe-work-hard
  ;; CHECK-NEXT:   (local.set $0
  ;; CHECK-NEXT:    (i32.const 1)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (i32.eqz
  ;; CHECK-NEXT:     (local.get $0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-A$maybe-work-hard
  ;; CHECK-NEXT:      (local.get $0)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-A$maybe-work-hard$1
  ;; CHECK-NEXT:   (local.set $1
  ;; CHECK-NEXT:    (i32.const 2)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (i32.eqz
  ;; CHECK-NEXT:     (local.get $1)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-A$maybe-work-hard
  ;; CHECK-NEXT:      (local.get $1)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-A$maybe-work-hard$2
  ;; CHECK-NEXT:   (local.set $2
  ;; CHECK-NEXT:    (i32.const 3)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (i32.eqz
  ;; CHECK-NEXT:     (local.get $2)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-A$maybe-work-hard
  ;; CHECK-NEXT:      (local.get $2)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-maybe-work-hard
    ;; Call the above function to verify that we can in fact inline it after
    ;; splitting. We should see each of these three calls replaced by inlined
    ;; code performing the if from $maybe-work-hard, and depending on that
    ;; result they each call the outlined code that must *not* be inlined.
    ;;
    ;; Note that we must call more than once, otherwise given a single use we
    ;; will always inline the entire thing.
    (call $maybe-work-hard (i32.const 1))
    (call $maybe-work-hard (i32.const 2))
    (call $maybe-work-hard (i32.const 3))
  )

  (func $just-if (param $x i32)
    ;; As above, but all we have is an if.
    (if
      (local.get $x)
      (then
        (loop $l
          (call $import)
          (br_if $l
            (local.get $x)
          )
        )
      )
    )
  )

  ;; CHECK:      (func $call-just-if (type $0)
  ;; CHECK-NEXT:  (local $0 i32)
  ;; CHECK-NEXT:  (local $1 i32)
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-B$just-if$3
  ;; CHECK-NEXT:   (local.set $0
  ;; CHECK-NEXT:    (i32.const 1)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (local.get $0)
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-B$just-if
  ;; CHECK-NEXT:      (local.get $0)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-B$just-if$4
  ;; CHECK-NEXT:   (local.set $1
  ;; CHECK-NEXT:    (i32.const 2)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (local.get $1)
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-B$just-if
  ;; CHECK-NEXT:      (local.get $1)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-just-if
    (call $just-if (i32.const 1))
    (call $just-if (i32.const 2))
  )

  ;; CHECK:      (func $br-to-toplevel (type $1) (param $x i32)
  ;; CHECK-NEXT:  (block $toplevel
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (if
  ;; CHECK-NEXT:      (local.get $x)
  ;; CHECK-NEXT:      (then
  ;; CHECK-NEXT:       (br $toplevel)
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:      (else
  ;; CHECK-NEXT:       (call $import)
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $br-to-toplevel (param $x i32)
    (block $toplevel
      (if
        (local.get $x)
        (then
          (block
            (if
              (local.get $x)
              ;; A br to the toplevel block prevents us from outlining this code,
              ;; as we can't outline a br without its target.
              (then
                (br $toplevel)
              )
              (else
                (call $import)
              )
            )
          )
        )
      )
    )
  )

  ;; CHECK:      (func $call-br-to-toplevel (type $0)
  ;; CHECK-NEXT:  (call $br-to-toplevel
  ;; CHECK-NEXT:   (i32.const 1)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (call $br-to-toplevel
  ;; CHECK-NEXT:   (i32.const 2)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-br-to-toplevel
    (call $br-to-toplevel (i32.const 1))
    (call $br-to-toplevel (i32.const 2))
  )

  (func $nondefaultable-param (param $x i32) (param $y (ref $struct))
    ;; We can inline despite the non-initial, non-defaultable param.
    (if
      (local.get $x)
      (then
        (return)
      )
    )
    (loop $l
      (call $import)
      (br $l)
    )
  )

  ;; CHECK:      (func $call-nondefaultable-param (type $0)
  ;; CHECK-NEXT:  (local $0 i32)
  ;; CHECK-NEXT:  (local $1 (ref $struct))
  ;; CHECK-NEXT:  (block $__inlined_func$nondefaultable-param$5
  ;; CHECK-NEXT:   (local.set $0
  ;; CHECK-NEXT:    (i32.const 0)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (local.set $1
  ;; CHECK-NEXT:    (struct.new_default $struct)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (block
  ;; CHECK-NEXT:    (if
  ;; CHECK-NEXT:     (local.get $0)
  ;; CHECK-NEXT:     (then
  ;; CHECK-NEXT:      (br $__inlined_func$nondefaultable-param$5)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (loop $l
  ;; CHECK-NEXT:     (call $import)
  ;; CHECK-NEXT:     (br $l)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-nondefaultable-param
    (call $nondefaultable-param (i32.const 0) (struct.new $struct))
  )

  (func $many-params (param $x i64) (param $y i32) (param $z f64)
    ;; Test that we can optimize this function even though it has multiple
    ;; parameters, and it is not the very first one that we use in the
    ;; condition.
    (if
      (local.get $y)
      (then
        (return)
      )
    )
    (loop $l
      (call $import)
      (br $l)
    )
  )

  ;; CHECK:      (func $call-many-params (type $0)
  ;; CHECK-NEXT:  (local $0 i64)
  ;; CHECK-NEXT:  (local $1 i32)
  ;; CHECK-NEXT:  (local $2 f64)
  ;; CHECK-NEXT:  (local $3 i64)
  ;; CHECK-NEXT:  (local $4 i32)
  ;; CHECK-NEXT:  (local $5 f64)
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-A$many-params$6
  ;; CHECK-NEXT:   (local.set $0
  ;; CHECK-NEXT:    (i64.const 0)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (local.set $1
  ;; CHECK-NEXT:    (i32.const 1)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (local.set $2
  ;; CHECK-NEXT:    (f64.const 3.14159)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (i32.eqz
  ;; CHECK-NEXT:     (local.get $1)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-A$many-params
  ;; CHECK-NEXT:      (local.get $0)
  ;; CHECK-NEXT:      (local.get $1)
  ;; CHECK-NEXT:      (local.get $2)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-A$many-params$7
  ;; CHECK-NEXT:   (local.set $3
  ;; CHECK-NEXT:    (i64.const 0)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (local.set $4
  ;; CHECK-NEXT:    (i32.const 1)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (local.set $5
  ;; CHECK-NEXT:    (f64.const 3.14159)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (i32.eqz
  ;; CHECK-NEXT:     (local.get $4)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-A$many-params
  ;; CHECK-NEXT:      (local.get $3)
  ;; CHECK-NEXT:      (local.get $4)
  ;; CHECK-NEXT:      (local.get $5)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-many-params
    ;; Call the above function to verify that we can in fact inline it after
    ;; splitting. We should see each of these three calls replaced by inlined
    ;; code performing the if from $maybe-work-hard, and depending on that
    ;; result they each call the outlined code that must *not* be inlined.
    (call $many-params (i64.const 0) (i32.const 1) (f64.const 3.14159))
    (call $many-params (i64.const 0) (i32.const 1) (f64.const 3.14159))
  )

  (func $condition-eqz (param $x i32)
    (if
      ;; More work in the condition, but work that we still consider worth
      ;; optimizing: a unary op.
      (i32.eqz
        (local.get $x)
      )
      (then
        (return)
      )
    )
    (loop $l
      (call $import)
      (br $l)
    )
  )

  ;; CHECK:      (func $call-condition-eqz (type $0)
  ;; CHECK-NEXT:  (local $0 i32)
  ;; CHECK-NEXT:  (local $1 i32)
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-A$condition-eqz$8
  ;; CHECK-NEXT:   (local.set $0
  ;; CHECK-NEXT:    (i32.const 0)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (i32.eqz
  ;; CHECK-NEXT:     (i32.eqz
  ;; CHECK-NEXT:      (local.get $0)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-A$condition-eqz
  ;; CHECK-NEXT:      (local.get $0)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-A$condition-eqz$9
  ;; CHECK-NEXT:   (local.set $1
  ;; CHECK-NEXT:    (i32.const 1)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (i32.eqz
  ;; CHECK-NEXT:     (i32.eqz
  ;; CHECK-NEXT:      (local.get $1)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-A$condition-eqz
  ;; CHECK-NEXT:      (local.get $1)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-condition-eqz
    (call $condition-eqz (i32.const 0))
    (call $condition-eqz (i32.const 1))
  )

  (func $condition-global
    (if
      ;; A global read, also worth splitting.
      (global.get $glob)
      (then
        (return)
      )
    )
    (loop $l
      (call $import)
      (br $l)
    )
  )

  ;; CHECK:      (func $call-condition-global (type $0)
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-A$condition-global$10
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (i32.eqz
  ;; CHECK-NEXT:     (global.get $glob)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-A$condition-global)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-A$condition-global$11
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (i32.eqz
  ;; CHECK-NEXT:     (global.get $glob)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-A$condition-global)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-condition-global
    (call $condition-global)
    (call $condition-global)
  )

  (func $condition-ref.is (param $x anyref)
    (if
      ;; A ref.is operation.
      (ref.is_null
        (local.get $x)
      )
      (then
        (return)
      )
    )
    (loop $l
      (call $import)
      (br $l)
    )
  )

  ;; CHECK:      (func $call-condition-ref.is (type $0)
  ;; CHECK-NEXT:  (local $0 anyref)
  ;; CHECK-NEXT:  (local $1 anyref)
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-A$condition-ref.is$12
  ;; CHECK-NEXT:   (local.set $0
  ;; CHECK-NEXT:    (ref.null none)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (i32.eqz
  ;; CHECK-NEXT:     (ref.is_null
  ;; CHECK-NEXT:      (local.get $0)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-A$condition-ref.is
  ;; CHECK-NEXT:      (local.get $0)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-A$condition-ref.is$13
  ;; CHECK-NEXT:   (local.set $1
  ;; CHECK-NEXT:    (ref.null none)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (i32.eqz
  ;; CHECK-NEXT:     (ref.is_null
  ;; CHECK-NEXT:      (local.get $1)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-A$condition-ref.is
  ;; CHECK-NEXT:      (local.get $1)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-condition-ref.is
    (call $condition-ref.is (ref.null any))
    (call $condition-ref.is (ref.null any))
  )

  ;; CHECK:      (func $condition-disallow-binary (type $1) (param $x i32)
  ;; CHECK-NEXT:  (if
  ;; CHECK-NEXT:   (i32.add
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (then
  ;; CHECK-NEXT:    (return)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (loop $l
  ;; CHECK-NEXT:   (call $import)
  ;; CHECK-NEXT:   (br $l)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $condition-disallow-binary (param $x i32)
    (if
      ;; Work we do *not* allow (at least for now), a binary.
      (i32.add
        (local.get $x)
        (local.get $x)
      )
      (then
        (return)
      )
    )
    (loop $l
      (call $import)
      (br $l)
    )
  )

  ;; CHECK:      (func $call-condition-disallow-binary (type $0)
  ;; CHECK-NEXT:  (call $condition-disallow-binary
  ;; CHECK-NEXT:   (i32.const 0)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (call $condition-disallow-binary
  ;; CHECK-NEXT:   (i32.const 1)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-condition-disallow-binary
    (call $condition-disallow-binary (i32.const 0))
    (call $condition-disallow-binary (i32.const 1))
  )

  ;; CHECK:      (func $condition-disallow-unreachable (type $1) (param $x i32)
  ;; CHECK-NEXT:  (if
  ;; CHECK-NEXT:   (i32.eqz
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (then
  ;; CHECK-NEXT:    (return)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (loop $l
  ;; CHECK-NEXT:   (call $import)
  ;; CHECK-NEXT:   (br $l)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $condition-disallow-unreachable (param $x i32)
    (if
      ;; Work we do *not* allow (at least for now), an unreachable.
      (i32.eqz
        (unreachable)
      )
      (then
        (return)
      )
    )
    (loop $l
      (call $import)
      (br $l)
    )
  )

  ;; CHECK:      (func $call-condition-disallow-unreachable (type $0)
  ;; CHECK-NEXT:  (call $condition-disallow-unreachable
  ;; CHECK-NEXT:   (i32.const 0)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (call $condition-disallow-unreachable
  ;; CHECK-NEXT:   (i32.const 1)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-condition-disallow-unreachable
    (call $condition-disallow-unreachable (i32.const 0))
    (call $condition-disallow-unreachable (i32.const 1))
  )

  ;; CHECK:      (func $start-used-globally (type $0)
  ;; CHECK-NEXT:  (if
  ;; CHECK-NEXT:   (global.get $glob)
  ;; CHECK-NEXT:   (then
  ;; CHECK-NEXT:    (return)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (loop $l
  ;; CHECK-NEXT:   (call $import)
  ;; CHECK-NEXT:   (br $l)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $start-used-globally
    ;; This is optimizable even though it is the start function, that is is,
    ;; having global uses of a function are not a problem for partial inlining
    ;; (since we do not modify this function - we create new split pieces of
    ;; it).
    (if
      (global.get $glob)
      (then
        (return)
      )
    )
    (loop $l
      (call $import)
      (br $l)
    )
  )

  ;; CHECK:      (func $call-start-used-globally (type $0)
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-A$start-used-globally$14
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (i32.eqz
  ;; CHECK-NEXT:     (global.get $glob)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-A$start-used-globally)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-A$start-used-globally$15
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (i32.eqz
  ;; CHECK-NEXT:     (global.get $glob)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-A$start-used-globally)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-start-used-globally
    (call $start-used-globally)
    (call $start-used-globally)
  )

  (func $inlineable
    ;; This looks optimizable, but it is also inlineable - so we do not need to
    ;; split it. It will just be inlined directly, without any $outlined part
    ;; that is split out.
    (if
      (global.get $glob)
      (then
        (return)
      )
    )
  )

  ;; CHECK:      (func $call-inlineable (type $0)
  ;; CHECK-NEXT:  (block $__inlined_func$inlineable$16
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (global.get $glob)
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (br $__inlined_func$inlineable$16)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (block $__inlined_func$inlineable$17
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (global.get $glob)
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (br $__inlined_func$inlineable$17)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-inlineable
    (call $inlineable)
    (call $inlineable)
  )

  ;; CHECK:      (func $if-not-first (type $1) (param $x i32)
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT:  (if
  ;; CHECK-NEXT:   (local.get $x)
  ;; CHECK-NEXT:   (then
  ;; CHECK-NEXT:    (return)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (loop $l
  ;; CHECK-NEXT:   (call $import)
  ;; CHECK-NEXT:   (br $l)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $if-not-first (param $x i32)
    ;; Except for the initial nop, we should outline this. As the if is not
    ;; first any more, we ignore it.
    (nop)
    (if
      (local.get $x)
      (then
        (return)
      )
    )
    (loop $l
      (call $import)
      (br $l)
    )
  )

  ;; CHECK:      (func $call-if-not-first (type $0)
  ;; CHECK-NEXT:  (call $if-not-first
  ;; CHECK-NEXT:   (i32.const 0)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (call $if-not-first
  ;; CHECK-NEXT:   (i32.const 1)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-if-not-first
    (call $if-not-first (i32.const 0))
    (call $if-not-first (i32.const 1))
  )

  ;; CHECK:      (func $if-else (type $1) (param $x i32)
  ;; CHECK-NEXT:  (if
  ;; CHECK-NEXT:   (local.get $x)
  ;; CHECK-NEXT:   (then
  ;; CHECK-NEXT:    (return)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (else
  ;; CHECK-NEXT:    (nop)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (loop $l
  ;; CHECK-NEXT:   (call $import)
  ;; CHECK-NEXT:   (br $l)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $if-else (param $x i32)
    ;; An else in the if prevents us from recognizing the pattern we want.
    (if
      (local.get $x)
      (then
        (return)
      )
      (else
        (nop)
      )
    )
    (loop $l
      (call $import)
      (br $l)
    )
  )

  ;; CHECK:      (func $call-if-else (type $0)
  ;; CHECK-NEXT:  (call $if-else
  ;; CHECK-NEXT:   (i32.const 0)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (call $if-else
  ;; CHECK-NEXT:   (i32.const 1)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-if-else
    (call $if-else (i32.const 0))
    (call $if-else (i32.const 1))
  )

  ;; CHECK:      (func $if-non-return (type $1) (param $x i32)
  ;; CHECK-NEXT:  (if
  ;; CHECK-NEXT:   (local.get $x)
  ;; CHECK-NEXT:   (then
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (loop $l
  ;; CHECK-NEXT:   (call $import)
  ;; CHECK-NEXT:   (br $l)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $if-non-return (param $x i32)
    ;; Something other than a return in the if body prevents us from outlining.
    (if
      (local.get $x)
      (then
        (unreachable)
      )
    )
    (loop $l
      (call $import)
      (br $l)
    )
  )

  ;; CHECK:      (func $call-if-non-return (type $0)
  ;; CHECK-NEXT:  (call $if-non-return
  ;; CHECK-NEXT:   (i32.const 0)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (call $if-non-return
  ;; CHECK-NEXT:   (i32.const 1)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-if-non-return
    (call $if-non-return (i32.const 0))
    (call $if-non-return (i32.const 1))
  )

  (func $colliding-name (param $x i32)
    ;; When we outline this, the name should not collide with that of the
    ;; function after us.
    (if
      (local.get $x)
      (then
        (return)
      )
    )
    (loop $l
      (call $import)
      (br $l)
    )
  )

  ;; CHECK:      (func $call-colliding-name (type $0)
  ;; CHECK-NEXT:  (local $0 i32)
  ;; CHECK-NEXT:  (local $1 i32)
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-A$colliding-name$18
  ;; CHECK-NEXT:   (local.set $0
  ;; CHECK-NEXT:    (i32.const 0)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (i32.eqz
  ;; CHECK-NEXT:     (local.get $0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-A$colliding-name_67
  ;; CHECK-NEXT:      (local.get $0)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-A$colliding-name$19
  ;; CHECK-NEXT:   (local.set $1
  ;; CHECK-NEXT:    (i32.const 1)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (i32.eqz
  ;; CHECK-NEXT:     (local.get $1)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-A$colliding-name_67
  ;; CHECK-NEXT:      (local.get $1)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-colliding-name
    (call $colliding-name (i32.const 0))
    (call $colliding-name (i32.const 1))
  )

  ;; CHECK:      (func $byn-split-outlined-A$colliding-name (type $0)
  ;; CHECK-NEXT: )
  (func $byn-split-outlined-A$colliding-name
    ;; This function's name might collide with the split function we create for
    ;; the above function; the split function's name must be fixed up.
  )

  ;; Pattern B: functions containing
  ;;
  ;;   if (simple1) heavy-work-that-is-unreachable;
  ;;   if (simple..) heavy-work-that-is-unreachable;
  ;;   simplek

  (func $error-if-null (param $x anyref) (result anyref)
    ;; A "as non null" function: If the input is null, issue an error somehow
    ;; (here, by calling an import, but could also be a throwing of an
    ;; exception). If not null, return the value.
    (if
      (ref.is_null
        (local.get $x)
      )
      (then
        (block
          (call $import)
          (unreachable)
        )
      )
    )
    (local.get $x)
  )

  ;; CHECK:      (func $call-error-if-null (type $0)
  ;; CHECK-NEXT:  (local $0 anyref)
  ;; CHECK-NEXT:  (local $1 anyref)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block $__inlined_func$byn-split-inlineable-B$error-if-null$20 (result anyref)
  ;; CHECK-NEXT:    (local.set $0
  ;; CHECK-NEXT:     (ref.null none)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (block (result anyref)
  ;; CHECK-NEXT:     (if
  ;; CHECK-NEXT:      (ref.is_null
  ;; CHECK-NEXT:       (local.get $0)
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:      (then
  ;; CHECK-NEXT:       (br $__inlined_func$byn-split-inlineable-B$error-if-null$20
  ;; CHECK-NEXT:        (call $byn-split-outlined-B$error-if-null
  ;; CHECK-NEXT:         (local.get $0)
  ;; CHECK-NEXT:        )
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:     (local.get $0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block $__inlined_func$byn-split-inlineable-B$error-if-null$21 (result anyref)
  ;; CHECK-NEXT:    (local.set $1
  ;; CHECK-NEXT:     (ref.null none)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (block (result anyref)
  ;; CHECK-NEXT:     (if
  ;; CHECK-NEXT:      (ref.is_null
  ;; CHECK-NEXT:       (local.get $1)
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:      (then
  ;; CHECK-NEXT:       (br $__inlined_func$byn-split-inlineable-B$error-if-null$21
  ;; CHECK-NEXT:        (call $byn-split-outlined-B$error-if-null
  ;; CHECK-NEXT:         (local.get $1)
  ;; CHECK-NEXT:        )
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:     (local.get $1)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-error-if-null
    (drop (call $error-if-null (ref.null any)))
    (drop (call $error-if-null (ref.null any)))
  )

  ;; CHECK:      (func $too-many (type $2) (param $x anyref) (result anyref)
  ;; CHECK-NEXT:  (if
  ;; CHECK-NEXT:   (ref.is_null
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (then
  ;; CHECK-NEXT:    (call $import)
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT:  (local.get $x)
  ;; CHECK-NEXT: )
  (func $too-many (param $x anyref) (result anyref)
    (if
      (ref.is_null
        (local.get $x)
      )
      (then
        (block
          (call $import)
          (unreachable)
        )
      )
    )
    (nop) ;; An extra operation here prevents us from identifying the pattern.
    (local.get $x)
  )

  ;; CHECK:      (func $call-too-many (type $0)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (call $too-many
  ;; CHECK-NEXT:    (ref.null none)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (call $too-many
  ;; CHECK-NEXT:    (ref.null none)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-too-many
    (drop (call $too-many (ref.null any)))
    (drop (call $too-many (ref.null any)))
  )

  ;; CHECK:      (func $tail-not-simple (type $2) (param $x anyref) (result anyref)
  ;; CHECK-NEXT:  (if
  ;; CHECK-NEXT:   (ref.is_null
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (then
  ;; CHECK-NEXT:    (call $import)
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (unreachable)
  ;; CHECK-NEXT: )
  (func $tail-not-simple (param $x anyref) (result anyref)
    (if
      (ref.is_null
        (local.get $x)
      )
      (then
        (block
          (call $import)
          (unreachable)
        )
      )
    )
    (unreachable) ;; This prevents us from optimizing
  )

  ;; CHECK:      (func $call-tail-not-simple (type $0)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (call $tail-not-simple
  ;; CHECK-NEXT:    (ref.null none)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (call $tail-not-simple
  ;; CHECK-NEXT:    (ref.null none)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-tail-not-simple
    (drop (call $tail-not-simple (ref.null any)))
    (drop (call $tail-not-simple (ref.null any)))
  )

  (func $reachable-if-body (param $x anyref) (result anyref)
    (if
      (ref.is_null
        (local.get $x)
      )
      ;; It is ok if the body is not unreachable (so long as it contains no
      ;; returns). We will optimize this, and just do a call to the outlined
      ;; code, without a return of a value here.
      (then
        (block
          ;; We need to have a loop here to avoid normal inlining from kicking in
          ;; on the outlined code.
          (loop $loop
            (call $import)
          )
        )
      )
    )
    (local.get $x)
  )

  ;; CHECK:      (func $call-reachable-if-body (type $0)
  ;; CHECK-NEXT:  (local $0 anyref)
  ;; CHECK-NEXT:  (local $1 anyref)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block $__inlined_func$byn-split-inlineable-B$reachable-if-body$22 (result anyref)
  ;; CHECK-NEXT:    (local.set $0
  ;; CHECK-NEXT:     (ref.null none)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (block (result anyref)
  ;; CHECK-NEXT:     (if
  ;; CHECK-NEXT:      (ref.is_null
  ;; CHECK-NEXT:       (local.get $0)
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:      (then
  ;; CHECK-NEXT:       (call $byn-split-outlined-B$reachable-if-body
  ;; CHECK-NEXT:        (local.get $0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:     (local.get $0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block $__inlined_func$byn-split-inlineable-B$reachable-if-body$23 (result anyref)
  ;; CHECK-NEXT:    (local.set $1
  ;; CHECK-NEXT:     (ref.null none)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (block (result anyref)
  ;; CHECK-NEXT:     (if
  ;; CHECK-NEXT:      (ref.is_null
  ;; CHECK-NEXT:       (local.get $1)
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:      (then
  ;; CHECK-NEXT:       (call $byn-split-outlined-B$reachable-if-body
  ;; CHECK-NEXT:        (local.get $1)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:     (local.get $1)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-reachable-if-body
    (drop (call $reachable-if-body (ref.null any)))
    (drop (call $reachable-if-body (ref.null any)))
  )

  (func $reachable-if-body-noloop (param $x anyref) (result anyref)
    ;; As above, but without a loop.
    (if
      (ref.is_null
        (local.get $x)
      )
      (then
        (call $import)
      )
    )
    (local.get $x)
  )

  ;; CHECK:      (func $call-reachable-if-body-noloop (type $0)
  ;; CHECK-NEXT:  (local $0 anyref)
  ;; CHECK-NEXT:  (local $1 anyref)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block $__inlined_func$reachable-if-body-noloop$24 (result anyref)
  ;; CHECK-NEXT:    (local.set $0
  ;; CHECK-NEXT:     (ref.null none)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (block (result anyref)
  ;; CHECK-NEXT:     (if
  ;; CHECK-NEXT:      (ref.is_null
  ;; CHECK-NEXT:       (local.get $0)
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:      (then
  ;; CHECK-NEXT:       (call $import)
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:     (local.get $0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block $__inlined_func$reachable-if-body-noloop$25 (result anyref)
  ;; CHECK-NEXT:    (local.set $1
  ;; CHECK-NEXT:     (ref.null none)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (block (result anyref)
  ;; CHECK-NEXT:     (if
  ;; CHECK-NEXT:      (ref.is_null
  ;; CHECK-NEXT:       (local.get $1)
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:      (then
  ;; CHECK-NEXT:       (call $import)
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:     (local.get $1)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-reachable-if-body-noloop
    ;; As above, but the called function has no loop. In that case, even though
    ;; it fits the pattern for partial inlining we can just inline the entire
    ;; thing normally.
    (drop (call $reachable-if-body-noloop (ref.null any)))
    (drop (call $reachable-if-body-noloop (ref.null any)))
  )

  ;; CHECK:      (func $reachable-if-body-return (type $2) (param $x anyref) (result anyref)
  ;; CHECK-NEXT:  (if
  ;; CHECK-NEXT:   (ref.is_null
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (then
  ;; CHECK-NEXT:    (if
  ;; CHECK-NEXT:     (i32.const 1)
  ;; CHECK-NEXT:     (then
  ;; CHECK-NEXT:      (return
  ;; CHECK-NEXT:       (local.get $x)
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:     (else
  ;; CHECK-NEXT:      (call $import)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (local.get $x)
  ;; CHECK-NEXT: )
  (func $reachable-if-body-return (param $x anyref) (result anyref)
    (if
      (ref.is_null
        (local.get $x)
      )
      (then
        (if
          (i32.const 1)
          ;; The return here prevents the optimization.
          (then
            (return
              (local.get $x)
            )
          )
          (else
            (call $import)
          )
        )
      )
    )
    (local.get $x)
  )

  ;; CHECK:      (func $call-reachable-if-body-return (type $0)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (call $reachable-if-body-return
  ;; CHECK-NEXT:    (ref.null none)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (call $reachable-if-body-return
  ;; CHECK-NEXT:    (ref.null none)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-reachable-if-body-return
    (drop (call $reachable-if-body-return (ref.null any)))
    (drop (call $reachable-if-body-return (ref.null any)))
  )

  (func $unreachable-if-body-no-result (param $x anyref)
    (if
      (ref.is_null
        (local.get $x)
      )
      ;; The if body is unreachable, but the function has no returned value.
      ;; When we outline this code, we should not try to return a value.
      (then
        (block
          (call $import)
          (unreachable)
        )
      )
    )
  )

  ;; CHECK:      (func $call-unreachable-if-body-no-result (type $0)
  ;; CHECK-NEXT:  (local $0 anyref)
  ;; CHECK-NEXT:  (local $1 anyref)
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-B$unreachable-if-body-no-result$26
  ;; CHECK-NEXT:   (local.set $0
  ;; CHECK-NEXT:    (ref.null none)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (ref.is_null
  ;; CHECK-NEXT:     (local.get $0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-B$unreachable-if-body-no-result
  ;; CHECK-NEXT:      (local.get $0)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-B$unreachable-if-body-no-result$27
  ;; CHECK-NEXT:   (local.set $1
  ;; CHECK-NEXT:    (ref.null none)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (ref.is_null
  ;; CHECK-NEXT:     (local.get $1)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-B$unreachable-if-body-no-result
  ;; CHECK-NEXT:      (local.get $1)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-unreachable-if-body-no-result
    (call $unreachable-if-body-no-result (ref.null any))
    (call $unreachable-if-body-no-result (ref.null any))
  )

  (func $multi-if (param $x anyref) (result anyref)
    (if
      (ref.is_null
        (local.get $x)
      )
      (then
        (call $import)
      )
    )
    ;; A second if. We can outline both if bodies.
    (if
      (ref.is_null
        (local.get $x)
      )
      (then
        (loop $x
          (call $import)
          (br_if $x
            (global.get $glob)
          )
        )
      )
    )
    (local.get $x)
  )

  ;; CHECK:      (func $call-multi-if (type $0)
  ;; CHECK-NEXT:  (local $0 anyref)
  ;; CHECK-NEXT:  (local $1 anyref)
  ;; CHECK-NEXT:  (local $2 anyref)
  ;; CHECK-NEXT:  (local $3 anyref)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block $__inlined_func$byn-split-inlineable-B$multi-if$28 (result anyref)
  ;; CHECK-NEXT:    (local.set $0
  ;; CHECK-NEXT:     (ref.null none)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (block (result anyref)
  ;; CHECK-NEXT:     (if
  ;; CHECK-NEXT:      (ref.is_null
  ;; CHECK-NEXT:       (local.get $0)
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:      (then
  ;; CHECK-NEXT:       (block $__inlined_func$byn-split-outlined-B$multi-if$30
  ;; CHECK-NEXT:        (local.set $2
  ;; CHECK-NEXT:         (local.get $0)
  ;; CHECK-NEXT:        )
  ;; CHECK-NEXT:        (call $import)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:     (if
  ;; CHECK-NEXT:      (ref.is_null
  ;; CHECK-NEXT:       (local.get $0)
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:      (then
  ;; CHECK-NEXT:       (call $byn-split-outlined-B$multi-if_76
  ;; CHECK-NEXT:        (local.get $0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:     (local.get $0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block $__inlined_func$byn-split-inlineable-B$multi-if$29 (result anyref)
  ;; CHECK-NEXT:    (local.set $1
  ;; CHECK-NEXT:     (ref.null none)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (block (result anyref)
  ;; CHECK-NEXT:     (if
  ;; CHECK-NEXT:      (ref.is_null
  ;; CHECK-NEXT:       (local.get $1)
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:      (then
  ;; CHECK-NEXT:       (block $__inlined_func$byn-split-outlined-B$multi-if$31
  ;; CHECK-NEXT:        (local.set $3
  ;; CHECK-NEXT:         (local.get $1)
  ;; CHECK-NEXT:        )
  ;; CHECK-NEXT:        (call $import)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:     (if
  ;; CHECK-NEXT:      (ref.is_null
  ;; CHECK-NEXT:       (local.get $1)
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:      (then
  ;; CHECK-NEXT:       (call $byn-split-outlined-B$multi-if_76
  ;; CHECK-NEXT:        (local.get $1)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:     (local.get $1)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-multi-if
    (drop (call $multi-if (ref.null none)))
    (drop (call $multi-if (ref.null none)))
  )

  ;; CHECK:      (func $too-many-ifs (type $2) (param $x anyref) (result anyref)
  ;; CHECK-NEXT:  (if
  ;; CHECK-NEXT:   (ref.is_null
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (then
  ;; CHECK-NEXT:    (call $import)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (if
  ;; CHECK-NEXT:   (ref.is_null
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (then
  ;; CHECK-NEXT:    (call $import)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (if
  ;; CHECK-NEXT:   (ref.is_null
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (then
  ;; CHECK-NEXT:    (call $import)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (if
  ;; CHECK-NEXT:   (ref.is_null
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (then
  ;; CHECK-NEXT:    (call $import)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (if
  ;; CHECK-NEXT:   (ref.is_null
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (then
  ;; CHECK-NEXT:    (call $import)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (local.get $x)
  ;; CHECK-NEXT: )
  (func $too-many-ifs (param $x anyref) (result anyref)
    ;; 5 ifs, which is too many.
    (if
      (ref.is_null
        (local.get $x)
      )
      (then
        (call $import)
      )
    )
    (if
      (ref.is_null
        (local.get $x)
      )
      (then
        (call $import)
      )
    )
    (if
      (ref.is_null
        (local.get $x)
      )
      (then
        (call $import)
      )
    )
    (if
      (ref.is_null
        (local.get $x)
      )
      (then
        (call $import)
      )
    )
    (if
      (ref.is_null
        (local.get $x)
      )
      (then
        (call $import)
      )
    )
    (local.get $x)
  )

  ;; CHECK:      (func $call-too-many-ifs (type $0)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (call $too-many-ifs
  ;; CHECK-NEXT:    (ref.null none)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (call $too-many-ifs
  ;; CHECK-NEXT:    (ref.null none)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-too-many-ifs
    (drop (call $too-many-ifs (ref.null none)))
    (drop (call $too-many-ifs (ref.null none)))
  )
)

;; CHECK:      (func $byn-split-outlined-A$maybe-work-hard (type $1) (param $x i32)
;; CHECK-NEXT:  (loop $l
;; CHECK-NEXT:   (call $import)
;; CHECK-NEXT:   (br $l)
;; CHECK-NEXT:  )
;; CHECK-NEXT: )

;; CHECK:      (func $byn-split-outlined-B$just-if (type $1) (param $x i32)
;; CHECK-NEXT:  (loop $l
;; CHECK-NEXT:   (call $import)
;; CHECK-NEXT:   (br_if $l
;; CHECK-NEXT:    (local.get $x)
;; CHECK-NEXT:   )
;; CHECK-NEXT:  )
;; CHECK-NEXT: )

;; CHECK:      (func $byn-split-outlined-A$many-params (type $5) (param $x i64) (param $y i32) (param $z f64)
;; CHECK-NEXT:  (loop $l
;; CHECK-NEXT:   (call $import)
;; CHECK-NEXT:   (br $l)
;; CHECK-NEXT:  )
;; CHECK-NEXT: )

;; CHECK:      (func $byn-split-outlined-A$condition-eqz (type $1) (param $x i32)
;; CHECK-NEXT:  (loop $l
;; CHECK-NEXT:   (call $import)
;; CHECK-NEXT:   (br $l)
;; CHECK-NEXT:  )
;; CHECK-NEXT: )

;; CHECK:      (func $byn-split-outlined-A$condition-global (type $0)
;; CHECK-NEXT:  (loop $l
;; CHECK-NEXT:   (call $import)
;; CHECK-NEXT:   (br $l)
;; CHECK-NEXT:  )
;; CHECK-NEXT: )

;; CHECK:      (func $byn-split-outlined-A$condition-ref.is (type $3) (param $x anyref)
;; CHECK-NEXT:  (loop $l
;; CHECK-NEXT:   (call $import)
;; CHECK-NEXT:   (br $l)
;; CHECK-NEXT:  )
;; CHECK-NEXT: )

;; CHECK:      (func $byn-split-outlined-A$start-used-globally (type $0)
;; CHECK-NEXT:  (loop $l
;; CHECK-NEXT:   (call $import)
;; CHECK-NEXT:   (br $l)
;; CHECK-NEXT:  )
;; CHECK-NEXT: )

;; CHECK:      (func $byn-split-outlined-A$colliding-name_67 (type $1) (param $x i32)
;; CHECK-NEXT:  (loop $l
;; CHECK-NEXT:   (call $import)
;; CHECK-NEXT:   (br $l)
;; CHECK-NEXT:  )
;; CHECK-NEXT: )

;; CHECK:      (func $byn-split-outlined-B$error-if-null (type $2) (param $x anyref) (result anyref)
;; CHECK-NEXT:  (call $import)
;; CHECK-NEXT:  (unreachable)
;; CHECK-NEXT: )

;; CHECK:      (func $byn-split-outlined-B$reachable-if-body (type $3) (param $x anyref)
;; CHECK-NEXT:  (loop $loop
;; CHECK-NEXT:   (call $import)
;; CHECK-NEXT:  )
;; CHECK-NEXT: )

;; CHECK:      (func $byn-split-outlined-B$unreachable-if-body-no-result (type $3) (param $x anyref)
;; CHECK-NEXT:  (call $import)
;; CHECK-NEXT:  (unreachable)
;; CHECK-NEXT: )

;; CHECK:      (func $byn-split-outlined-B$multi-if_76 (type $3) (param $x anyref)
;; CHECK-NEXT:  (loop $x
;; CHECK-NEXT:   (call $import)
;; CHECK-NEXT:   (br_if $x
;; CHECK-NEXT:    (global.get $glob)
;; CHECK-NEXT:   )
;; CHECK-NEXT:  )
;; CHECK-NEXT: )
(module
  ;; CHECK:      (type $none_=>_none (func))
  (type $none_=>_none (func))
  ;; CHECK:      (global $global$0 (mut i32) (i32.const 10))
  (global $global$0 (mut i32) (i32.const 10))
  ;; CHECK:      (export "0" (func $0))
  (export "0" (func $0))
  ;; CHECK:      (export "1" (func $1))
  (export "1" (func $1))
  ;; CHECK:      (func $0 (type $none_=>_none)
  ;; CHECK-NEXT:  (if
  ;; CHECK-NEXT:   (global.get $global$0)
  ;; CHECK-NEXT:   (then
  ;; CHECK-NEXT:    (return)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (block $__inlined_func$1
  ;; CHECK-NEXT:   (call $0)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (block $__inlined_func$1$1
  ;; CHECK-NEXT:   (call $0)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $0
    ;; A function that is a good candidate to partially inline.
    (if
      (global.get $global$0)
      (then
        (return)
      )
    )
    (call $1)
    (call $1)
  )
  ;; CHECK:      (func $1 (type $none_=>_none)
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-A$0$2
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (i32.eqz
  ;; CHECK-NEXT:     (global.get $global$0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (block $__inlined_func$byn-split-outlined-A$0$3
  ;; CHECK-NEXT:      (block
  ;; CHECK-NEXT:       (block $__inlined_func$1
  ;; CHECK-NEXT:        (block $__inlined_func$byn-split-inlineable-A$0$4
  ;; CHECK-NEXT:         (if
  ;; CHECK-NEXT:          (i32.eqz
  ;; CHECK-NEXT:           (global.get $global$0)
  ;; CHECK-NEXT:          )
  ;; CHECK-NEXT:          (then
  ;; CHECK-NEXT:           (call $byn-split-outlined-A$0)
  ;; CHECK-NEXT:          )
  ;; CHECK-NEXT:         )
  ;; CHECK-NEXT:        )
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:       (block $__inlined_func$1$1
  ;; CHECK-NEXT:        (block $__inlined_func$byn-split-inlineable-A$0$5
  ;; CHECK-NEXT:         (if
  ;; CHECK-NEXT:          (i32.eqz
  ;; CHECK-NEXT:           (global.get $global$0)
  ;; CHECK-NEXT:          )
  ;; CHECK-NEXT:          (then
  ;; CHECK-NEXT:           (call $byn-split-outlined-A$0)
  ;; CHECK-NEXT:          )
  ;; CHECK-NEXT:         )
  ;; CHECK-NEXT:        )
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $1
    ;; This and the previous function are mutually recursive. As a result, we
    ;; can keep partially inlining between them, creating new functions as we
    ;; go, even though that is not very useful.
    (call $0)
  )

  ;; Add a lot more functions, so the # of functions is high which would
  ;; otherwise limit the # of iterations that we run.
  ;; CHECK:      (func $2 (type $none_=>_none)
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT: )
  (func $2
    (nop)
  )
  ;; CHECK:      (func $3 (type $none_=>_none)
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT: )
  (func $3
    (nop)
  )
  ;; CHECK:      (func $4 (type $none_=>_none)
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT: )
  (func $4
    (nop)
  )
  ;; CHECK:      (func $5 (type $none_=>_none)
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT: )
  (func $5
    (nop)
  )
  ;; CHECK:      (func $6 (type $none_=>_none)
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT: )
  (func $6
    (nop)
  )
  ;; CHECK:      (func $7 (type $none_=>_none)
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT: )
  (func $7
    (nop)
  )
  ;; CHECK:      (func $8 (type $none_=>_none)
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT: )
  (func $8
    (nop)
  )
  ;; CHECK:      (func $9 (type $none_=>_none)
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT: )
  (func $9
    (nop)
  )
  ;; CHECK:      (func $10 (type $none_=>_none)
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT: )
  (func $10
    (nop)
  )
  ;; CHECK:      (func $11 (type $none_=>_none)
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT: )
  (func $11
    (nop)
  )
  ;; CHECK:      (func $12 (type $none_=>_none)
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT: )
  (func $12
    (nop)
  )
  ;; CHECK:      (func $13 (type $none_=>_none)
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT: )
  (func $13
    (nop)
  )
  ;; CHECK:      (func $14 (type $none_=>_none)
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT: )
  (func $14
    (nop)
  )
  ;; CHECK:      (func $15 (type $none_=>_none)
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT: )
  (func $15
    (nop)
  )
  ;; CHECK:      (func $16 (type $none_=>_none)
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT: )
  (func $16
    (nop)
  )
  ;; CHECK:      (func $17 (type $none_=>_none)
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT: )
  (func $17
    (nop)
  )
  ;; CHECK:      (func $18 (type $none_=>_none)
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT: )
  (func $18
    (nop)
  )
)

;; CHECK:      (func $byn-split-outlined-A$0 (type $none_=>_none)
;; CHECK-NEXT:  (block $__inlined_func$1
;; CHECK-NEXT:   (block $__inlined_func$byn-split-inlineable-A$0$6
;; CHECK-NEXT:    (if
;; CHECK-NEXT:     (i32.eqz
;; CHECK-NEXT:      (global.get $global$0)
;; CHECK-NEXT:     )
;; CHECK-NEXT:     (then
;; CHECK-NEXT:      (call $byn-split-outlined-A$0_21)
;; CHECK-NEXT:     )
;; CHECK-NEXT:    )
;; CHECK-NEXT:   )
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (block $__inlined_func$1$1
;; CHECK-NEXT:   (block $__inlined_func$byn-split-inlineable-A$0$7
;; CHECK-NEXT:    (if
;; CHECK-NEXT:     (i32.eqz
;; CHECK-NEXT:      (global.get $global$0)
;; CHECK-NEXT:     )
;; CHECK-NEXT:     (then
;; CHECK-NEXT:      (call $byn-split-outlined-A$0_21)
;; CHECK-NEXT:     )
;; CHECK-NEXT:    )
;; CHECK-NEXT:   )
;; CHECK-NEXT:  )
;; CHECK-NEXT: )

;; CHECK:      (func $byn-split-outlined-A$0_21 (type $none_=>_none)
;; CHECK-NEXT:  (block $__inlined_func$1
;; CHECK-NEXT:   (block $__inlined_func$byn-split-inlineable-A$0$8
;; CHECK-NEXT:    (if
;; CHECK-NEXT:     (i32.eqz
;; CHECK-NEXT:      (global.get $global$0)
;; CHECK-NEXT:     )
;; CHECK-NEXT:     (then
;; CHECK-NEXT:      (call $byn-split-outlined-A$0_22)
;; CHECK-NEXT:     )
;; CHECK-NEXT:    )
;; CHECK-NEXT:   )
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (block $__inlined_func$1$1
;; CHECK-NEXT:   (block $__inlined_func$byn-split-inlineable-A$0$9
;; CHECK-NEXT:    (if
;; CHECK-NEXT:     (i32.eqz
;; CHECK-NEXT:      (global.get $global$0)
;; CHECK-NEXT:     )
;; CHECK-NEXT:     (then
;; CHECK-NEXT:      (call $byn-split-outlined-A$0_22)
;; CHECK-NEXT:     )
;; CHECK-NEXT:    )
;; CHECK-NEXT:   )
;; CHECK-NEXT:  )
;; CHECK-NEXT: )

;; CHECK:      (func $byn-split-outlined-A$0_22 (type $none_=>_none)
;; CHECK-NEXT:  (block $__inlined_func$1
;; CHECK-NEXT:   (call $0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (block $__inlined_func$1$1
;; CHECK-NEXT:   (call $0)
;; CHECK-NEXT:  )
;; CHECK-NEXT: )
(module
  (func $middle-size-A (param $x i32)
    ;; This function is too big for normal inlining with the default size limit.
    ;; However, if we partially inline it then the outlined code becomes small
    ;; enough to be normally inlined. We should just inline it normally in that
    ;; case, to avoid wasted work.
    (if
      (local.get $x)
      (then
        (return)
      )
    )
    ;; 6x3 = 18 items, close to the default size limit of 20. With the if, we
    ;; hit that limit and are too big. But if we did partial inlining then the
    ;; lines below us are small enough to then be inlined normally.
    (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)) (drop (i32.const 0))
  )

  ;; CHECK:      (type $0 (func))

  ;; CHECK:      (type $1 (func (param i32)))

  ;; CHECK:      (type $2 (func (param i32) (result i32)))

  ;; CHECK:      (func $call-$middle-size-A (type $0)
  ;; CHECK-NEXT:  (local $0 i32)
  ;; CHECK-NEXT:  (local $1 i32)
  ;; CHECK-NEXT:  (block $__inlined_func$middle-size-A
  ;; CHECK-NEXT:   (local.set $0
  ;; CHECK-NEXT:    (i32.const 0)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (block
  ;; CHECK-NEXT:    (if
  ;; CHECK-NEXT:     (local.get $0)
  ;; CHECK-NEXT:     (then
  ;; CHECK-NEXT:      (br $__inlined_func$middle-size-A)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (block $__inlined_func$middle-size-A$1
  ;; CHECK-NEXT:   (local.set $1
  ;; CHECK-NEXT:    (i32.const 1)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (block
  ;; CHECK-NEXT:    (if
  ;; CHECK-NEXT:     (local.get $1)
  ;; CHECK-NEXT:     (then
  ;; CHECK-NEXT:      (br $__inlined_func$middle-size-A$1)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-$middle-size-A
    ;; This will be normally inlined, see the comment in the above function.
    ;; We can see it is normally inlined and not partially from the string
    ;; "__inlined_func" in the code (instead of "split" appearing anywhere).
    (call $middle-size-A
     (i32.const 0)
    )
    (call $middle-size-A
     (i32.const 1)
    )
  )

  (func $big-size-A (param $x i32)
    ;; As above, but a little larger - so large that we won't normally inline
    ;; it.
    (if
      (local.get $x)
      (then
        (return)
      )
    )
    ;; 6x4 = 24 items, which is more than the inlining limit.
    (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)) (drop (i32.const 0))
    (drop (i32.const 0)) (drop (i32.const 0)) (drop (i32.const 0))
  )

  ;; CHECK:      (func $call-$big-size-A (type $0)
  ;; CHECK-NEXT:  (local $0 i32)
  ;; CHECK-NEXT:  (local $1 i32)
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-A$big-size-A$2
  ;; CHECK-NEXT:   (local.set $0
  ;; CHECK-NEXT:    (i32.const 0)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (i32.eqz
  ;; CHECK-NEXT:     (local.get $0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-A$big-size-A
  ;; CHECK-NEXT:      (local.get $0)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (block $__inlined_func$byn-split-inlineable-A$big-size-A$3
  ;; CHECK-NEXT:   (local.set $1
  ;; CHECK-NEXT:    (i32.const 1)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (if
  ;; CHECK-NEXT:    (i32.eqz
  ;; CHECK-NEXT:     (local.get $1)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (call $byn-split-outlined-A$big-size-A
  ;; CHECK-NEXT:      (local.get $1)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-$big-size-A
    ;; Normal inlining can't work here, so we'll just do partial inlining.
    (call $big-size-A
      (i32.const 0)
    )
    (call $big-size-A
      (i32.const 1)
    )
  )

  (func $middle-size-B (param $x i32) (result i32)
    ;; As above, but for pattern B and not A.
    (if
      (local.get $x)
      (then
        (block
          (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)) (drop (i32.const 0))
          (unreachable)
        )
      )
    )
    (local.get $x)
  )

  ;; CHECK:      (func $call-$middle-size-B (type $0)
  ;; CHECK-NEXT:  (local $0 i32)
  ;; CHECK-NEXT:  (local $1 i32)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block $__inlined_func$middle-size-B$4 (result i32)
  ;; CHECK-NEXT:    (local.set $0
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (block (result i32)
  ;; CHECK-NEXT:     (if
  ;; CHECK-NEXT:      (local.get $0)
  ;; CHECK-NEXT:      (then
  ;; CHECK-NEXT:       (drop
  ;; CHECK-NEXT:        (i32.const 0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:       (drop
  ;; CHECK-NEXT:        (i32.const 0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:       (drop
  ;; CHECK-NEXT:        (i32.const 0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:       (drop
  ;; CHECK-NEXT:        (i32.const 0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:       (drop
  ;; CHECK-NEXT:        (i32.const 0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:       (drop
  ;; CHECK-NEXT:        (i32.const 0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:       (drop
  ;; CHECK-NEXT:        (i32.const 0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:       (drop
  ;; CHECK-NEXT:        (i32.const 0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:       (drop
  ;; CHECK-NEXT:        (i32.const 0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:       (unreachable)
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:     (local.get $0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block $__inlined_func$middle-size-B$5 (result i32)
  ;; CHECK-NEXT:    (local.set $1
  ;; CHECK-NEXT:     (i32.const 1)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (block (result i32)
  ;; CHECK-NEXT:     (if
  ;; CHECK-NEXT:      (local.get $1)
  ;; CHECK-NEXT:      (then
  ;; CHECK-NEXT:       (drop
  ;; CHECK-NEXT:        (i32.const 0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:       (drop
  ;; CHECK-NEXT:        (i32.const 0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:       (drop
  ;; CHECK-NEXT:        (i32.const 0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:       (drop
  ;; CHECK-NEXT:        (i32.const 0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:       (drop
  ;; CHECK-NEXT:        (i32.const 0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:       (drop
  ;; CHECK-NEXT:        (i32.const 0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:       (drop
  ;; CHECK-NEXT:        (i32.const 0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:       (drop
  ;; CHECK-NEXT:        (i32.const 0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:       (drop
  ;; CHECK-NEXT:        (i32.const 0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:       (unreachable)
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:     (local.get $1)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-$middle-size-B
    ;; We will normally inline here.
    (drop
      (call $middle-size-B
        (i32.const 0)
      )
    )
    (drop
      (call $middle-size-B
        (i32.const 1)
      )
    )
  )

  (func $big-size-B (param $x i32) (result i32)
    ;; As above, but a little larger - so large that we won't normally inline
    ;; it.
    (if
      (local.get $x)
      (then
        (block
          (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)) (drop (i32.const 0))
          (drop (i32.const 0)) (drop (i32.const 0)) (drop (i32.const 0))
          (unreachable)
        )
      )
    )
    (local.get $x)
  )

  ;; CHECK:      (func $call-$big-size-B (type $0)
  ;; CHECK-NEXT:  (local $0 i32)
  ;; CHECK-NEXT:  (local $1 i32)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block $__inlined_func$byn-split-inlineable-B$big-size-B$6 (result i32)
  ;; CHECK-NEXT:    (local.set $0
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (block (result i32)
  ;; CHECK-NEXT:     (if
  ;; CHECK-NEXT:      (local.get $0)
  ;; CHECK-NEXT:      (then
  ;; CHECK-NEXT:       (br $__inlined_func$byn-split-inlineable-B$big-size-B$6
  ;; CHECK-NEXT:        (call $byn-split-outlined-B$big-size-B
  ;; CHECK-NEXT:         (local.get $0)
  ;; CHECK-NEXT:        )
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:     (local.get $0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block $__inlined_func$byn-split-inlineable-B$big-size-B$7 (result i32)
  ;; CHECK-NEXT:    (local.set $1
  ;; CHECK-NEXT:     (i32.const 1)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (block (result i32)
  ;; CHECK-NEXT:     (if
  ;; CHECK-NEXT:      (local.get $1)
  ;; CHECK-NEXT:      (then
  ;; CHECK-NEXT:       (br $__inlined_func$byn-split-inlineable-B$big-size-B$7
  ;; CHECK-NEXT:        (call $byn-split-outlined-B$big-size-B
  ;; CHECK-NEXT:         (local.get $1)
  ;; CHECK-NEXT:        )
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:     (local.get $1)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-$big-size-B
    ;; We'll partially inline here.
    (drop
      (call $big-size-B
        (i32.const 0)
      )
    )
    (drop
      (call $big-size-B
        (i32.const 1)
      )
    )
  )
)
;; CHECK:      (func $byn-split-outlined-A$big-size-A (type $1) (param $x i32)
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT: )

;; CHECK:      (func $byn-split-outlined-B$big-size-B (type $2) (param $x i32) (result i32)
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (drop
;; CHECK-NEXT:   (i32.const 0)
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (unreachable)
;; CHECK-NEXT: )