;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
;; NOTE: This test was ported using port_passes_tests_to_lit.py and could be cleaned up.

;; RUN: foreach %s %t wasm-opt -all --legalize-and-prune-js-interface -S -o - | filecheck %s

(module
  (import "env" "imported-64" (func $imported-64 (param i32 f64) (result i64)))

  (import "env" "imported-v128" (func $imported-v128 (result v128)))

  (import "env" "imported-mv" (func $imported-mv (result i32 f64)))

  (import "env" "imported-v128-param" (func $imported-v128-param (param v128) (result i32)))

  (import "env" "imported-v128-param-noresult" (func $imported-v128-param-noresult (param v128)))

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

  ;; CHECK:      (type $1 (func (result i32 f64)))

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

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

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

  ;; CHECK:      (type $5 (func (result i32)))

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

  ;; CHECK:      (type $7 (func (param i32 f64) (result i32)))

  ;; CHECK:      (import "env" "getTempRet0" (func $getTempRet0 (type $5) (result i32)))

  ;; CHECK:      (import "env" "imported-64" (func $legalimport$imported-64 (type $7) (param i32 f64) (result i32)))

  ;; CHECK:      (func $imported-v128 (type $0) (result v128)
  ;; CHECK-NEXT:  (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
  ;; CHECK-NEXT: )

  ;; CHECK:      (func $imported-mv (type $1) (result i32 f64)
  ;; CHECK-NEXT:  (tuple.make 2
  ;; CHECK-NEXT:   (i32.const 0)
  ;; CHECK-NEXT:   (f64.const 0)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )

  ;; CHECK:      (func $imported-v128-param (type $2) (param $0 v128) (result i32)
  ;; CHECK-NEXT:  (i32.const 0)
  ;; CHECK-NEXT: )

  ;; CHECK:      (func $imported-v128-param-noresult (type $3) (param $0 v128)
  ;; CHECK-NEXT:  (nop)
  ;; CHECK-NEXT: )

  ;; CHECK:      (func $call-64 (type $4)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (call $legalfunc$imported-64
  ;; CHECK-NEXT:    (i32.const 0)
  ;; CHECK-NEXT:    (f64.const 1.2)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (call $imported-v128)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (tuple.drop 2
  ;; CHECK-NEXT:   (call $imported-mv)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (call $imported-v128-param
  ;; CHECK-NEXT:    (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (call $imported-v128-param-noresult
  ;; CHECK-NEXT:   (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $call-64
    ;; This import has an i64 which will be legalized, the same as in the
    ;; normal --legalize-js-interface pass. Note how the multiple params are not
    ;; an issue for us.
    (drop (call $imported-64
      (i32.const 0)
      (f64.const 1.2)
    ))

    ;; This import uses SIMD, which we must prune from the list of imports.
    ;; We'll define it in a trivial manner inside the module instead.
    (drop (call $imported-v128))

    ;; Ditto, but with multivalue.
    (tuple.drop 2 (call $imported-mv))

    ;; Ditto, but now the illegal thing is a param.
    (drop (call $imported-v128-param
      (v128.const i32x4 0 0 0 0)
    ))

    ;; Ditto, but no result this time.
    (call $imported-v128-param-noresult
      (v128.const i32x4 0 0 0 0)
    )
  )
)

;; CHECK:      (func $legalfunc$imported-64 (type $6) (param $0 i32) (param $1 f64) (result i64)
;; CHECK-NEXT:  (i64.or
;; CHECK-NEXT:   (i64.extend_i32_u
;; CHECK-NEXT:    (call $legalimport$imported-64
;; CHECK-NEXT:     (local.get $0)
;; CHECK-NEXT:     (local.get $1)
;; CHECK-NEXT:    )
;; CHECK-NEXT:   )
;; CHECK-NEXT:   (i64.shl
;; CHECK-NEXT:    (i64.extend_i32_u
;; CHECK-NEXT:     (call $getTempRet0)
;; CHECK-NEXT:    )
;; CHECK-NEXT:    (i64.const 32)
;; CHECK-NEXT:   )
;; CHECK-NEXT:  )
;; CHECK-NEXT: )
(module
  ;; CHECK:      (type $0 (func (param i64) (result i64)))

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

  ;; CHECK:      (type $2 (func (result v128)))

  ;; CHECK:      (type $3 (func (result i32 i32)))

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

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

  ;; CHECK:      (import "env" "setTempRet0" (func $setTempRet0 (type $4) (param i32)))

  ;; CHECK:      (export "export-64" (func $legalstub$export-64))

  ;; CHECK:      (func $export-64 (type $0) (param $x i64) (result i64)
  ;; CHECK-NEXT:  (unreachable)
  ;; CHECK-NEXT: )
  (func $export-64 (export "export-64") (param $x i64) (result i64)
    ;; This can be legalized. Note we have two params, but that's no problem.
    (unreachable)
  )

  ;; CHECK:      (func $export-v128 (type $1) (param $x v128)
  ;; CHECK-NEXT:  (unreachable)
  ;; CHECK-NEXT: )
  (func $export-v128 (export "export-v128") (param $x v128)
    ;; This will be pruned.
    (unreachable)
  )

  ;; CHECK:      (func $export-v128-result (type $2) (result v128)
  ;; CHECK-NEXT:  (unreachable)
  ;; CHECK-NEXT: )
  (func $export-v128-result (export "export-v128-result") (result v128)
    ;; This will be pruned.
    (unreachable)
  )

  ;; CHECK:      (func $export-mv (type $3) (result i32 i32)
  ;; CHECK-NEXT:  (unreachable)
  ;; CHECK-NEXT: )
  (func $export-mv (export "export-mv") (result i32 i32)
    ;; This will be pruned.
    (unreachable)
  )
)

;; CHECK:      (func $legalstub$export-64 (type $5) (param $0 i32) (param $1 i32) (result i32)
;; CHECK-NEXT:  (local $2 i64)
;; CHECK-NEXT:  (local.set $2
;; CHECK-NEXT:   (call $export-64
;; CHECK-NEXT:    (i64.or
;; CHECK-NEXT:     (i64.extend_i32_u
;; CHECK-NEXT:      (local.get $0)
;; CHECK-NEXT:     )
;; CHECK-NEXT:     (i64.shl
;; CHECK-NEXT:      (i64.extend_i32_u
;; CHECK-NEXT:       (local.get $1)
;; CHECK-NEXT:      )
;; CHECK-NEXT:      (i64.const 32)
;; CHECK-NEXT:     )
;; CHECK-NEXT:    )
;; CHECK-NEXT:   )
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (call $setTempRet0
;; CHECK-NEXT:   (i32.wrap_i64
;; CHECK-NEXT:    (i64.shr_u
;; CHECK-NEXT:     (local.get $2)
;; CHECK-NEXT:     (i64.const 32)
;; CHECK-NEXT:    )
;; CHECK-NEXT:   )
;; CHECK-NEXT:  )
;; CHECK-NEXT:  (i32.wrap_i64
;; CHECK-NEXT:   (local.get $2)
;; CHECK-NEXT:  )
;; CHECK-NEXT: )
(module
  (import "env" "imported-v128" (func $imported-v128 (result v128)))

  ;; The import is also exported. We will both implement it with a trivial body
  ;; and also prune the export, so it remains neither an import nor an export.
  (export "imported-v128" (func $imported-v128))
)
;; CHECK:      (type $0 (func (result v128)))

;; CHECK:      (func $imported-v128 (type $0) (result v128)
;; CHECK-NEXT:  (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
;; CHECK-NEXT: )