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

;; RUN: wasm-opt -all --inlining %s -S -o - | filecheck %s --check-prefix=shrink0
;; RUN: wasm-opt -all --inlining --shrink-level=1 %s -S -o - | filecheck %s --check-prefix=shrink1
;; RUN: wasm-opt -all --inlining --optimize-level=3 %s -S -o - | filecheck %s --check-prefix=optimize3

(module
 ;; shrink0:      (type $2 (func (param i32)))

 ;; shrink0:      (type $1 (func (param i32) (result i32)))

 ;; shrink0:      (type $0 (func (param i32 i32) (result i32)))
 ;; shrink1:      (type $2 (func (param i32)))

 ;; shrink1:      (type $1 (func (param i32) (result i32)))

 ;; shrink1:      (type $0 (func (param i32 i32) (result i32)))
 (type $0 (func (param i32 i32) (result i32)))
 (type $1 (func (param i32) (result i32)))
 ;; optimize3:      (type $2 (func (param i32)))
 (type $2 (func (param i32)))
 ;; shrink0:      (type $3 (func))
 ;; shrink1:      (type $3 (func))
 ;; optimize3:      (type $3 (func))
 (type $3 (func))
 ;; shrink0:      (import "env" "foo" (func $drop-import (type $2) (param i32)))
 ;; shrink1:      (import "env" "foo" (func $drop-import (type $2) (param i32)))
 ;; optimize3:      (import "env" "foo" (func $drop-import (type $2) (param i32)))
 (import "env" "foo" (func $drop-import (type $2) (param i32)))
 ;; shrink0:      (export "main" (func $main))
 ;; shrink1:      (export "main" (func $main))
 ;; optimize3:      (export "main" (func $main))
 (export "main" (func $main))
 ;; This will be inlined in all shrink and optimization modes.
 (func $trivial-binary-instruction-small (type $0) (param $p1 i32) (param $p2 i32) (result i32)
  (i32.add
   (local.get $p1)
   (local.get $p2)
  )
 )
 ;; This will always be inlined when not shrinking and optimize level is 3.
 ;; shrink0:      (func $trivial-binary-instruction-large (type $1) (param $p1 i32) (result i32)
 ;; shrink0-NEXT:  (i32.add
 ;; shrink0-NEXT:   (local.get $p1)
 ;; shrink0-NEXT:   (i32.const 2147483647)
 ;; shrink0-NEXT:  )
 ;; shrink0-NEXT: )
 ;; shrink1:      (func $trivial-binary-instruction-large (type $1) (param $p1 i32) (result i32)
 ;; shrink1-NEXT:  (i32.add
 ;; shrink1-NEXT:   (local.get $p1)
 ;; shrink1-NEXT:   (i32.const 2147483647)
 ;; shrink1-NEXT:  )
 ;; shrink1-NEXT: )
 (func $trivial-binary-instruction-large (type $1) (param $p1 i32) (result i32)
  (i32.add
   (local.get $p1)
   (i32.const 2147483647)
  )
 )
 ;; This will always be inlined when not shrinking and optimize level is 3.
 ;; shrink0:      (func $non-trivial-binary-instruction (type $0) (param $p1 i32) (param $p2 i32) (result i32)
 ;; shrink0-NEXT:  (i32.add
 ;; shrink0-NEXT:   (local.get $p2)
 ;; shrink0-NEXT:   (local.get $p1)
 ;; shrink0-NEXT:  )
 ;; shrink0-NEXT: )
 ;; shrink1:      (func $non-trivial-binary-instruction (type $0) (param $p1 i32) (param $p2 i32) (result i32)
 ;; shrink1-NEXT:  (i32.add
 ;; shrink1-NEXT:   (local.get $p2)
 ;; shrink1-NEXT:   (local.get $p1)
 ;; shrink1-NEXT:  )
 ;; shrink1-NEXT: )
 (func $non-trivial-binary-instruction (type $0) (param $p1 i32) (param $p2 i32) (result i32)
  (i32.add
   (local.get $p2)
   (local.get $p1)
  )
 )
 ;; This will be inlined in all shrink and optimization modes.
 (func $trivial-unary-instruction (type $1) (param $p1 i32) (result i32)
  (i32.eqz
   (local.get $p1)
  )
 )
 ;; Note: we need more than one caller for each function to test inlining based
 ;; on trivial-ness of the function bodies. With one call we always inline.
 ;; shrink0:      (func $main (type $3)
 ;; shrink0-NEXT:  (local $0 i32)
 ;; shrink0-NEXT:  (local $1 i32)
 ;; shrink0-NEXT:  (local $2 i32)
 ;; shrink0-NEXT:  (local $3 i32)
 ;; shrink0-NEXT:  (local $4 i32)
 ;; shrink0-NEXT:  (local $5 i32)
 ;; shrink0-NEXT:  (call $drop-import
 ;; shrink0-NEXT:   (block $__inlined_func$trivial-binary-instruction-small (result i32)
 ;; shrink0-NEXT:    (local.set $0
 ;; shrink0-NEXT:     (i32.const 1)
 ;; shrink0-NEXT:    )
 ;; shrink0-NEXT:    (local.set $1
 ;; shrink0-NEXT:     (i32.const 2)
 ;; shrink0-NEXT:    )
 ;; shrink0-NEXT:    (i32.add
 ;; shrink0-NEXT:     (local.get $0)
 ;; shrink0-NEXT:     (local.get $1)
 ;; shrink0-NEXT:    )
 ;; shrink0-NEXT:   )
 ;; shrink0-NEXT:  )
 ;; shrink0-NEXT:  (call $drop-import
 ;; shrink0-NEXT:   (block $__inlined_func$trivial-binary-instruction-small$1 (result i32)
 ;; shrink0-NEXT:    (local.set $2
 ;; shrink0-NEXT:     (i32.const 3)
 ;; shrink0-NEXT:    )
 ;; shrink0-NEXT:    (local.set $3
 ;; shrink0-NEXT:     (i32.const 4)
 ;; shrink0-NEXT:    )
 ;; shrink0-NEXT:    (i32.add
 ;; shrink0-NEXT:     (local.get $2)
 ;; shrink0-NEXT:     (local.get $3)
 ;; shrink0-NEXT:    )
 ;; shrink0-NEXT:   )
 ;; shrink0-NEXT:  )
 ;; shrink0-NEXT:  (call $drop-import
 ;; shrink0-NEXT:   (call $trivial-binary-instruction-large
 ;; shrink0-NEXT:    (i32.const 5)
 ;; shrink0-NEXT:   )
 ;; shrink0-NEXT:  )
 ;; shrink0-NEXT:  (call $drop-import
 ;; shrink0-NEXT:   (call $trivial-binary-instruction-large
 ;; shrink0-NEXT:    (i32.const 6)
 ;; shrink0-NEXT:   )
 ;; shrink0-NEXT:  )
 ;; shrink0-NEXT:  (call $drop-import
 ;; shrink0-NEXT:   (call $non-trivial-binary-instruction
 ;; shrink0-NEXT:    (i32.const 7)
 ;; shrink0-NEXT:    (i32.const 8)
 ;; shrink0-NEXT:   )
 ;; shrink0-NEXT:  )
 ;; shrink0-NEXT:  (call $drop-import
 ;; shrink0-NEXT:   (call $non-trivial-binary-instruction
 ;; shrink0-NEXT:    (i32.const 9)
 ;; shrink0-NEXT:    (i32.const 10)
 ;; shrink0-NEXT:   )
 ;; shrink0-NEXT:  )
 ;; shrink0-NEXT:  (call $drop-import
 ;; shrink0-NEXT:   (block $__inlined_func$trivial-unary-instruction$2 (result i32)
 ;; shrink0-NEXT:    (local.set $4
 ;; shrink0-NEXT:     (i32.const 11)
 ;; shrink0-NEXT:    )
 ;; shrink0-NEXT:    (i32.eqz
 ;; shrink0-NEXT:     (local.get $4)
 ;; shrink0-NEXT:    )
 ;; shrink0-NEXT:   )
 ;; shrink0-NEXT:  )
 ;; shrink0-NEXT:  (call $drop-import
 ;; shrink0-NEXT:   (block $__inlined_func$trivial-unary-instruction$3 (result i32)
 ;; shrink0-NEXT:    (local.set $5
 ;; shrink0-NEXT:     (i32.const 12)
 ;; shrink0-NEXT:    )
 ;; shrink0-NEXT:    (i32.eqz
 ;; shrink0-NEXT:     (local.get $5)
 ;; shrink0-NEXT:    )
 ;; shrink0-NEXT:   )
 ;; shrink0-NEXT:  )
 ;; shrink0-NEXT: )
 ;; shrink1:      (func $main (type $3)
 ;; shrink1-NEXT:  (local $0 i32)
 ;; shrink1-NEXT:  (local $1 i32)
 ;; shrink1-NEXT:  (local $2 i32)
 ;; shrink1-NEXT:  (local $3 i32)
 ;; shrink1-NEXT:  (local $4 i32)
 ;; shrink1-NEXT:  (local $5 i32)
 ;; shrink1-NEXT:  (call $drop-import
 ;; shrink1-NEXT:   (block $__inlined_func$trivial-binary-instruction-small (result i32)
 ;; shrink1-NEXT:    (local.set $0
 ;; shrink1-NEXT:     (i32.const 1)
 ;; shrink1-NEXT:    )
 ;; shrink1-NEXT:    (local.set $1
 ;; shrink1-NEXT:     (i32.const 2)
 ;; shrink1-NEXT:    )
 ;; shrink1-NEXT:    (i32.add
 ;; shrink1-NEXT:     (local.get $0)
 ;; shrink1-NEXT:     (local.get $1)
 ;; shrink1-NEXT:    )
 ;; shrink1-NEXT:   )
 ;; shrink1-NEXT:  )
 ;; shrink1-NEXT:  (call $drop-import
 ;; shrink1-NEXT:   (block $__inlined_func$trivial-binary-instruction-small$1 (result i32)
 ;; shrink1-NEXT:    (local.set $2
 ;; shrink1-NEXT:     (i32.const 3)
 ;; shrink1-NEXT:    )
 ;; shrink1-NEXT:    (local.set $3
 ;; shrink1-NEXT:     (i32.const 4)
 ;; shrink1-NEXT:    )
 ;; shrink1-NEXT:    (i32.add
 ;; shrink1-NEXT:     (local.get $2)
 ;; shrink1-NEXT:     (local.get $3)
 ;; shrink1-NEXT:    )
 ;; shrink1-NEXT:   )
 ;; shrink1-NEXT:  )
 ;; shrink1-NEXT:  (call $drop-import
 ;; shrink1-NEXT:   (call $trivial-binary-instruction-large
 ;; shrink1-NEXT:    (i32.const 5)
 ;; shrink1-NEXT:   )
 ;; shrink1-NEXT:  )
 ;; shrink1-NEXT:  (call $drop-import
 ;; shrink1-NEXT:   (call $trivial-binary-instruction-large
 ;; shrink1-NEXT:    (i32.const 6)
 ;; shrink1-NEXT:   )
 ;; shrink1-NEXT:  )
 ;; shrink1-NEXT:  (call $drop-import
 ;; shrink1-NEXT:   (call $non-trivial-binary-instruction
 ;; shrink1-NEXT:    (i32.const 7)
 ;; shrink1-NEXT:    (i32.const 8)
 ;; shrink1-NEXT:   )
 ;; shrink1-NEXT:  )
 ;; shrink1-NEXT:  (call $drop-import
 ;; shrink1-NEXT:   (call $non-trivial-binary-instruction
 ;; shrink1-NEXT:    (i32.const 9)
 ;; shrink1-NEXT:    (i32.const 10)
 ;; shrink1-NEXT:   )
 ;; shrink1-NEXT:  )
 ;; shrink1-NEXT:  (call $drop-import
 ;; shrink1-NEXT:   (block $__inlined_func$trivial-unary-instruction$2 (result i32)
 ;; shrink1-NEXT:    (local.set $4
 ;; shrink1-NEXT:     (i32.const 11)
 ;; shrink1-NEXT:    )
 ;; shrink1-NEXT:    (i32.eqz
 ;; shrink1-NEXT:     (local.get $4)
 ;; shrink1-NEXT:    )
 ;; shrink1-NEXT:   )
 ;; shrink1-NEXT:  )
 ;; shrink1-NEXT:  (call $drop-import
 ;; shrink1-NEXT:   (block $__inlined_func$trivial-unary-instruction$3 (result i32)
 ;; shrink1-NEXT:    (local.set $5
 ;; shrink1-NEXT:     (i32.const 12)
 ;; shrink1-NEXT:    )
 ;; shrink1-NEXT:    (i32.eqz
 ;; shrink1-NEXT:     (local.get $5)
 ;; shrink1-NEXT:    )
 ;; shrink1-NEXT:   )
 ;; shrink1-NEXT:  )
 ;; shrink1-NEXT: )
 ;; optimize3:      (func $main (type $3)
 ;; optimize3-NEXT:  (local $0 i32)
 ;; optimize3-NEXT:  (local $1 i32)
 ;; optimize3-NEXT:  (local $2 i32)
 ;; optimize3-NEXT:  (local $3 i32)
 ;; optimize3-NEXT:  (local $4 i32)
 ;; optimize3-NEXT:  (local $5 i32)
 ;; optimize3-NEXT:  (local $6 i32)
 ;; optimize3-NEXT:  (local $7 i32)
 ;; optimize3-NEXT:  (local $8 i32)
 ;; optimize3-NEXT:  (local $9 i32)
 ;; optimize3-NEXT:  (local $10 i32)
 ;; optimize3-NEXT:  (local $11 i32)
 ;; optimize3-NEXT:  (call $drop-import
 ;; optimize3-NEXT:   (block $__inlined_func$trivial-binary-instruction-small (result i32)
 ;; optimize3-NEXT:    (local.set $0
 ;; optimize3-NEXT:     (i32.const 1)
 ;; optimize3-NEXT:    )
 ;; optimize3-NEXT:    (local.set $1
 ;; optimize3-NEXT:     (i32.const 2)
 ;; optimize3-NEXT:    )
 ;; optimize3-NEXT:    (i32.add
 ;; optimize3-NEXT:     (local.get $0)
 ;; optimize3-NEXT:     (local.get $1)
 ;; optimize3-NEXT:    )
 ;; optimize3-NEXT:   )
 ;; optimize3-NEXT:  )
 ;; optimize3-NEXT:  (call $drop-import
 ;; optimize3-NEXT:   (block $__inlined_func$trivial-binary-instruction-small$1 (result i32)
 ;; optimize3-NEXT:    (local.set $2
 ;; optimize3-NEXT:     (i32.const 3)
 ;; optimize3-NEXT:    )
 ;; optimize3-NEXT:    (local.set $3
 ;; optimize3-NEXT:     (i32.const 4)
 ;; optimize3-NEXT:    )
 ;; optimize3-NEXT:    (i32.add
 ;; optimize3-NEXT:     (local.get $2)
 ;; optimize3-NEXT:     (local.get $3)
 ;; optimize3-NEXT:    )
 ;; optimize3-NEXT:   )
 ;; optimize3-NEXT:  )
 ;; optimize3-NEXT:  (call $drop-import
 ;; optimize3-NEXT:   (block $__inlined_func$trivial-binary-instruction-large$2 (result i32)
 ;; optimize3-NEXT:    (local.set $4
 ;; optimize3-NEXT:     (i32.const 5)
 ;; optimize3-NEXT:    )
 ;; optimize3-NEXT:    (i32.add
 ;; optimize3-NEXT:     (local.get $4)
 ;; optimize3-NEXT:     (i32.const 2147483647)
 ;; optimize3-NEXT:    )
 ;; optimize3-NEXT:   )
 ;; optimize3-NEXT:  )
 ;; optimize3-NEXT:  (call $drop-import
 ;; optimize3-NEXT:   (block $__inlined_func$trivial-binary-instruction-large$3 (result i32)
 ;; optimize3-NEXT:    (local.set $5
 ;; optimize3-NEXT:     (i32.const 6)
 ;; optimize3-NEXT:    )
 ;; optimize3-NEXT:    (i32.add
 ;; optimize3-NEXT:     (local.get $5)
 ;; optimize3-NEXT:     (i32.const 2147483647)
 ;; optimize3-NEXT:    )
 ;; optimize3-NEXT:   )
 ;; optimize3-NEXT:  )
 ;; optimize3-NEXT:  (call $drop-import
 ;; optimize3-NEXT:   (block $__inlined_func$non-trivial-binary-instruction$4 (result i32)
 ;; optimize3-NEXT:    (local.set $6
 ;; optimize3-NEXT:     (i32.const 7)
 ;; optimize3-NEXT:    )
 ;; optimize3-NEXT:    (local.set $7
 ;; optimize3-NEXT:     (i32.const 8)
 ;; optimize3-NEXT:    )
 ;; optimize3-NEXT:    (i32.add
 ;; optimize3-NEXT:     (local.get $7)
 ;; optimize3-NEXT:     (local.get $6)
 ;; optimize3-NEXT:    )
 ;; optimize3-NEXT:   )
 ;; optimize3-NEXT:  )
 ;; optimize3-NEXT:  (call $drop-import
 ;; optimize3-NEXT:   (block $__inlined_func$non-trivial-binary-instruction$5 (result i32)
 ;; optimize3-NEXT:    (local.set $8
 ;; optimize3-NEXT:     (i32.const 9)
 ;; optimize3-NEXT:    )
 ;; optimize3-NEXT:    (local.set $9
 ;; optimize3-NEXT:     (i32.const 10)
 ;; optimize3-NEXT:    )
 ;; optimize3-NEXT:    (i32.add
 ;; optimize3-NEXT:     (local.get $9)
 ;; optimize3-NEXT:     (local.get $8)
 ;; optimize3-NEXT:    )
 ;; optimize3-NEXT:   )
 ;; optimize3-NEXT:  )
 ;; optimize3-NEXT:  (call $drop-import
 ;; optimize3-NEXT:   (block $__inlined_func$trivial-unary-instruction$6 (result i32)
 ;; optimize3-NEXT:    (local.set $10
 ;; optimize3-NEXT:     (i32.const 11)
 ;; optimize3-NEXT:    )
 ;; optimize3-NEXT:    (i32.eqz
 ;; optimize3-NEXT:     (local.get $10)
 ;; optimize3-NEXT:    )
 ;; optimize3-NEXT:   )
 ;; optimize3-NEXT:  )
 ;; optimize3-NEXT:  (call $drop-import
 ;; optimize3-NEXT:   (block $__inlined_func$trivial-unary-instruction$7 (result i32)
 ;; optimize3-NEXT:    (local.set $11
 ;; optimize3-NEXT:     (i32.const 12)
 ;; optimize3-NEXT:    )
 ;; optimize3-NEXT:    (i32.eqz
 ;; optimize3-NEXT:     (local.get $11)
 ;; optimize3-NEXT:    )
 ;; optimize3-NEXT:   )
 ;; optimize3-NEXT:  )
 ;; optimize3-NEXT: )
 (func $main (type $3)
  (call $drop-import
   (call $trivial-binary-instruction-small
    (i32.const 1)
    (i32.const 2)
   )
  )
  (call $drop-import
   (call $trivial-binary-instruction-small
    (i32.const 3)
    (i32.const 4)
   )
  )
  (call $drop-import
   (call $trivial-binary-instruction-large
    (i32.const 5)
   )
  )
  (call $drop-import
   (call $trivial-binary-instruction-large
    (i32.const 6)
   )
  )
  (call $drop-import
   (call $non-trivial-binary-instruction
    (i32.const 7)
    (i32.const 8)
   )
  )
  (call $drop-import
   (call $non-trivial-binary-instruction
    (i32.const 9)
    (i32.const 10)
   )
  )
  (call $drop-import
   (call $trivial-unary-instruction
    (i32.const 11)
   )
  )
  (call $drop-import
   (call $trivial-unary-instruction
    (i32.const 12)
   )
  )
 )
)
