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

;; With `-O3`, we always inline calls to functions that just call other
;; functions with "trivial" arguments.
;;
;; A trivial argument for now is just an instruction with size 1. E.g.
;; `local.get`, constants.
;;
;; In this test we check inlining when the trivial call arguments are
;; constants. In tests inlining-trivial-calls-{1,2,3}.wast we check locals.

;; RUN: foreach %s %t wasm-opt -all -O3 -S -o - | filecheck %s --check-prefix=O3
;; RUN: foreach %s %t wasm-opt -all -O2 -S -o - | filecheck %s --check-prefix=O2
;; RUN: foreach %s %t wasm-opt -all -Os -S -o - | filecheck %s --check-prefix=Os

(module
 ;; O3:      (type $0 (func (param i32 i32 i32)))
 ;; O2:      (type $1 (func))

 ;; O2:      (type $0 (func (param i32 i32 i32)))
 ;; Os:      (type $1 (func))

 ;; Os:      (type $0 (func (param i32 i32 i32)))
 (type $0 (func (param i32 i32 i32)))

 ;; O3:      (type $1 (func))
 (type $1 (func))

 (type $2 (func))

 ;; O3:      (import "env" "foo" (func $imported-foo (type $0) (param i32 i32 i32)))
 ;; O2:      (import "env" "foo" (func $imported-foo (type $0) (param i32 i32 i32)))
 ;; Os:      (import "env" "foo" (func $imported-foo (type $0) (param i32 i32 i32)))
 (import "env" "foo" (func $imported-foo (type $0) (param i32 i32 i32)))

 ;; O3:      (export "main" (func $main))
 ;; O2:      (export "main" (func $main))
 ;; Os:      (export "main" (func $main))
 (export "main" (func $main))

 ;; O2:      (func $call-foo (type $1)
 ;; O2-NEXT:  (call $imported-foo
 ;; O2-NEXT:   (i32.const 1)
 ;; O2-NEXT:   (i32.const 2)
 ;; O2-NEXT:   (i32.const 3)
 ;; O2-NEXT:  )
 ;; O2-NEXT: )
 ;; Os:      (func $call-foo (type $1)
 ;; Os-NEXT:  (call $imported-foo
 ;; Os-NEXT:   (i32.const 1)
 ;; Os-NEXT:   (i32.const 2)
 ;; Os-NEXT:   (i32.const 3)
 ;; Os-NEXT:  )
 ;; Os-NEXT: )
 (func $call-foo (type $1)
  (call $imported-foo
   (i32.const 1)
   (i32.const 2)
   (i32.const 3)))

 ;; O3:      (func $main (type $1)
 ;; O3-NEXT:  (call $imported-foo
 ;; O3-NEXT:   (i32.const 1)
 ;; O3-NEXT:   (i32.const 2)
 ;; O3-NEXT:   (i32.const 3)
 ;; O3-NEXT:  )
 ;; O3-NEXT:  (call $imported-foo
 ;; O3-NEXT:   (i32.const 1)
 ;; O3-NEXT:   (i32.const 2)
 ;; O3-NEXT:   (i32.const 3)
 ;; O3-NEXT:  )
 ;; O3-NEXT:  (call $imported-foo
 ;; O3-NEXT:   (i32.const 1)
 ;; O3-NEXT:   (i32.const 2)
 ;; O3-NEXT:   (i32.const 3)
 ;; O3-NEXT:  )
 ;; O3-NEXT: )
 ;; O2:      (func $main (type $1)
 ;; O2-NEXT:  (call $call-foo)
 ;; O2-NEXT:  (call $call-foo)
 ;; O2-NEXT:  (call $call-foo)
 ;; O2-NEXT: )
 ;; Os:      (func $main (type $1)
 ;; Os-NEXT:  (call $call-foo)
 ;; Os-NEXT:  (call $call-foo)
 ;; Os-NEXT:  (call $call-foo)
 ;; Os-NEXT: )
 (func $main (type $2)
  ;; All calls below should be inlined in -O3, but not in -O2 or -Os. We call
  ;; it multiple times to make sure it won't be inlined because there's only
  ;; one call, instead it will be inlined based on optimization settings and
  ;; whether the call is trivial.
  (call $call-foo)
  (call $call-foo)
  (call $call-foo)))
