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

;; Test code that can be partially inlined, with and without that option.
;;
;; This is similar to inlining_splitting.wast but focuses on testing that we
;; only partially inline when the commandline flag is provided. In both of the
;; $call-* functions below, we should partially inline when that flag is set.

;; RUN: foreach %s %t wasm-opt --inlining --optimize-level=3                          --all-features -S -o - | filecheck %s --check-prefix NORMAL_
;; RUN: foreach %s %t wasm-opt --inlining --optimize-level=3 --partial-inlining-ifs=1 --all-features -S -o - | filecheck %s --check-prefix PARTIAL

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

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

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

  ;; NORMAL_:      (import "a" "b" (func $import (type $0)))
  ;; PARTIAL:      (type $0 (func))

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

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

  ;; PARTIAL:      (import "a" "b" (func $import (type $0)))
  (import "a" "b" (func $import))

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

  ;; NORMAL_:      (func $pattern-A (type $1) (param $x i32)
  ;; NORMAL_-NEXT:  (if
  ;; NORMAL_-NEXT:   (local.get $x)
  ;; NORMAL_-NEXT:   (then
  ;; NORMAL_-NEXT:    (return)
  ;; NORMAL_-NEXT:   )
  ;; NORMAL_-NEXT:  )
  ;; NORMAL_-NEXT:  (loop $l
  ;; NORMAL_-NEXT:   (call $import)
  ;; NORMAL_-NEXT:   (br $l)
  ;; NORMAL_-NEXT:  )
  ;; NORMAL_-NEXT: )
  (func $pattern-A (param $x i32)
    (if
      (local.get $x)
      (then
        (return)
      )
    )
    (loop $l
      (call $import)
      (br $l)
    )
  )

  ;; NORMAL_:      (func $call-pattern-A (type $0)
  ;; NORMAL_-NEXT:  (call $pattern-A
  ;; NORMAL_-NEXT:   (i32.const 1)
  ;; NORMAL_-NEXT:  )
  ;; NORMAL_-NEXT:  (call $pattern-A
  ;; NORMAL_-NEXT:   (i32.const 2)
  ;; NORMAL_-NEXT:  )
  ;; NORMAL_-NEXT: )
  ;; PARTIAL:      (func $call-pattern-A (type $0)
  ;; PARTIAL-NEXT:  (local $0 i32)
  ;; PARTIAL-NEXT:  (local $1 i32)
  ;; PARTIAL-NEXT:  (block $__inlined_func$byn-split-inlineable-A$pattern-A
  ;; PARTIAL-NEXT:   (local.set $0
  ;; PARTIAL-NEXT:    (i32.const 1)
  ;; PARTIAL-NEXT:   )
  ;; PARTIAL-NEXT:   (if
  ;; PARTIAL-NEXT:    (i32.eqz
  ;; PARTIAL-NEXT:     (local.get $0)
  ;; PARTIAL-NEXT:    )
  ;; PARTIAL-NEXT:    (then
  ;; PARTIAL-NEXT:     (call $byn-split-outlined-A$pattern-A
  ;; PARTIAL-NEXT:      (local.get $0)
  ;; PARTIAL-NEXT:     )
  ;; PARTIAL-NEXT:    )
  ;; PARTIAL-NEXT:   )
  ;; PARTIAL-NEXT:  )
  ;; PARTIAL-NEXT:  (block $__inlined_func$byn-split-inlineable-A$pattern-A$1
  ;; PARTIAL-NEXT:   (local.set $1
  ;; PARTIAL-NEXT:    (i32.const 2)
  ;; PARTIAL-NEXT:   )
  ;; PARTIAL-NEXT:   (if
  ;; PARTIAL-NEXT:    (i32.eqz
  ;; PARTIAL-NEXT:     (local.get $1)
  ;; PARTIAL-NEXT:    )
  ;; PARTIAL-NEXT:    (then
  ;; PARTIAL-NEXT:     (call $byn-split-outlined-A$pattern-A
  ;; PARTIAL-NEXT:      (local.get $1)
  ;; PARTIAL-NEXT:     )
  ;; PARTIAL-NEXT:    )
  ;; PARTIAL-NEXT:   )
  ;; PARTIAL-NEXT:  )
  ;; PARTIAL-NEXT: )
  (func $call-pattern-A
    (call $pattern-A (i32.const 1))
    (call $pattern-A (i32.const 2))
  )

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

  ;; NORMAL_:      (func $pattern-B (type $2) (param $x i32) (result i32)
  ;; NORMAL_-NEXT:  (if
  ;; NORMAL_-NEXT:   (i32.eqz
  ;; NORMAL_-NEXT:    (local.get $x)
  ;; NORMAL_-NEXT:   )
  ;; NORMAL_-NEXT:   (then
  ;; NORMAL_-NEXT:    (call $import)
  ;; NORMAL_-NEXT:    (unreachable)
  ;; NORMAL_-NEXT:   )
  ;; NORMAL_-NEXT:  )
  ;; NORMAL_-NEXT:  (local.get $x)
  ;; NORMAL_-NEXT: )
  (func $pattern-B (param $x i32) (result i32)
    (if
      (i32.eqz
        (local.get $x)
      )
      (then
        (block
          (call $import)
          (unreachable)
        )
      )
    )
    (local.get $x)
  )

  ;; NORMAL_:      (func $call-pattern-B (type $0)
  ;; NORMAL_-NEXT:  (drop
  ;; NORMAL_-NEXT:   (call $pattern-B
  ;; NORMAL_-NEXT:    (i32.const 1)
  ;; NORMAL_-NEXT:   )
  ;; NORMAL_-NEXT:  )
  ;; NORMAL_-NEXT:  (drop
  ;; NORMAL_-NEXT:   (call $pattern-B
  ;; NORMAL_-NEXT:    (i32.const 2)
  ;; NORMAL_-NEXT:   )
  ;; NORMAL_-NEXT:  )
  ;; NORMAL_-NEXT: )
  ;; PARTIAL:      (func $call-pattern-B (type $0)
  ;; PARTIAL-NEXT:  (local $0 i32)
  ;; PARTIAL-NEXT:  (local $1 i32)
  ;; PARTIAL-NEXT:  (drop
  ;; PARTIAL-NEXT:   (block $__inlined_func$byn-split-inlineable-B$pattern-B$2 (result i32)
  ;; PARTIAL-NEXT:    (local.set $0
  ;; PARTIAL-NEXT:     (i32.const 1)
  ;; PARTIAL-NEXT:    )
  ;; PARTIAL-NEXT:    (block (result i32)
  ;; PARTIAL-NEXT:     (if
  ;; PARTIAL-NEXT:      (i32.eqz
  ;; PARTIAL-NEXT:       (local.get $0)
  ;; PARTIAL-NEXT:      )
  ;; PARTIAL-NEXT:      (then
  ;; PARTIAL-NEXT:       (br $__inlined_func$byn-split-inlineable-B$pattern-B$2
  ;; PARTIAL-NEXT:        (call $byn-split-outlined-B$pattern-B
  ;; PARTIAL-NEXT:         (local.get $0)
  ;; PARTIAL-NEXT:        )
  ;; PARTIAL-NEXT:       )
  ;; PARTIAL-NEXT:      )
  ;; PARTIAL-NEXT:     )
  ;; PARTIAL-NEXT:     (local.get $0)
  ;; PARTIAL-NEXT:    )
  ;; PARTIAL-NEXT:   )
  ;; PARTIAL-NEXT:  )
  ;; PARTIAL-NEXT:  (drop
  ;; PARTIAL-NEXT:   (block $__inlined_func$byn-split-inlineable-B$pattern-B$3 (result i32)
  ;; PARTIAL-NEXT:    (local.set $1
  ;; PARTIAL-NEXT:     (i32.const 2)
  ;; PARTIAL-NEXT:    )
  ;; PARTIAL-NEXT:    (block (result i32)
  ;; PARTIAL-NEXT:     (if
  ;; PARTIAL-NEXT:      (i32.eqz
  ;; PARTIAL-NEXT:       (local.get $1)
  ;; PARTIAL-NEXT:      )
  ;; PARTIAL-NEXT:      (then
  ;; PARTIAL-NEXT:       (br $__inlined_func$byn-split-inlineable-B$pattern-B$3
  ;; PARTIAL-NEXT:        (call $byn-split-outlined-B$pattern-B
  ;; PARTIAL-NEXT:         (local.get $1)
  ;; PARTIAL-NEXT:        )
  ;; PARTIAL-NEXT:       )
  ;; PARTIAL-NEXT:      )
  ;; PARTIAL-NEXT:     )
  ;; PARTIAL-NEXT:     (local.get $1)
  ;; PARTIAL-NEXT:    )
  ;; PARTIAL-NEXT:   )
  ;; PARTIAL-NEXT:  )
  ;; PARTIAL-NEXT: )
  (func $call-pattern-B
    (drop (call $pattern-B (i32.const 1)))
    (drop (call $pattern-B (i32.const 2)))
  )
)
;; PARTIAL:      (func $byn-split-outlined-A$pattern-A (type $1) (param $x i32)
;; PARTIAL-NEXT:  (loop $l
;; PARTIAL-NEXT:   (call $import)
;; PARTIAL-NEXT:   (br $l)
;; PARTIAL-NEXT:  )
;; PARTIAL-NEXT: )

;; PARTIAL:      (func $byn-split-outlined-B$pattern-B (type $2) (param $x i32) (result i32)
;; PARTIAL-NEXT:  (call $import)
;; PARTIAL-NEXT:  (unreachable)
;; PARTIAL-NEXT: )