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

;; RUN: foreach %s %t wasm-opt --denan -all -S -o - | filecheck %s

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

  ;; CHECK:      (type $1 (func (param f32) (result f32)))

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

  ;; CHECK:      (func $foo128 (type $0) (param $x v128) (result v128)
  ;; CHECK-NEXT:  (local.set $x
  ;; CHECK-NEXT:   (call $deNan128
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (v128.const i32x4 0x00000001 0x00000002 0x00000003 0x00000004)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (call $deNan128
  ;; CHECK-NEXT:   (call $foo128
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $foo128 (param $x v128) (result v128)
    ;; The incoming param will be de-naned.

    ;; This is not a NaN.
    (drop
      (v128.const i32x4 0x00000001 0x00000002 0x00000003 0x00000004)
    )
    ;; This is an f64 NaN and also an f32. It will become 0's.
    (drop
      (v128.const i32x4 0xffffffff 0x00000002 0x00000003 0x00000004)
    )
    ;; This is an f32 NaN and not an f64. It will also become 0's.
    (drop
      (v128.const i32x4 0x00000001 0xffffffff 0x00000003 0x00000004)
    )

    ;; The result here will be de-naned.
    (call $foo128 (local.get $x))
  )
)
;; CHECK:      (func $deNan32 (type $1) (param $0 f32) (result f32)
;; CHECK-NEXT:  (if (result f32)
;; CHECK-NEXT:   (f32.eq
;; CHECK-NEXT:    (local.get $0)
;; CHECK-NEXT:    (local.get $0)
;; CHECK-NEXT:   )
;; CHECK-NEXT:   (then
;; CHECK-NEXT:    (local.get $0)
;; CHECK-NEXT:   )
;; CHECK-NEXT:   (else
;; CHECK-NEXT:    (f32.const 0)
;; CHECK-NEXT:   )
;; CHECK-NEXT:  )
;; CHECK-NEXT: )

;; CHECK:      (func $deNan64 (type $2) (param $0 f64) (result f64)
;; CHECK-NEXT:  (if (result f64)
;; CHECK-NEXT:   (f64.eq
;; CHECK-NEXT:    (local.get $0)
;; CHECK-NEXT:    (local.get $0)
;; CHECK-NEXT:   )
;; CHECK-NEXT:   (then
;; CHECK-NEXT:    (local.get $0)
;; CHECK-NEXT:   )
;; CHECK-NEXT:   (else
;; CHECK-NEXT:    (f64.const 0)
;; CHECK-NEXT:   )
;; CHECK-NEXT:  )
;; CHECK-NEXT: )

;; CHECK:      (func $deNan128 (type $0) (param $0 v128) (result v128)
;; CHECK-NEXT:  (if (result v128)
;; CHECK-NEXT:   (i32.and
;; CHECK-NEXT:    (i32.and
;; CHECK-NEXT:     (f32.eq
;; CHECK-NEXT:      (f32x4.extract_lane 0
;; CHECK-NEXT:       (local.get $0)
;; CHECK-NEXT:      )
;; CHECK-NEXT:      (f32x4.extract_lane 0
;; CHECK-NEXT:       (local.get $0)
;; CHECK-NEXT:      )
;; CHECK-NEXT:     )
;; CHECK-NEXT:     (f32.eq
;; CHECK-NEXT:      (f32x4.extract_lane 1
;; CHECK-NEXT:       (local.get $0)
;; CHECK-NEXT:      )
;; CHECK-NEXT:      (f32x4.extract_lane 1
;; CHECK-NEXT:       (local.get $0)
;; CHECK-NEXT:      )
;; CHECK-NEXT:     )
;; CHECK-NEXT:    )
;; CHECK-NEXT:    (i32.and
;; CHECK-NEXT:     (f32.eq
;; CHECK-NEXT:      (f32x4.extract_lane 2
;; CHECK-NEXT:       (local.get $0)
;; CHECK-NEXT:      )
;; CHECK-NEXT:      (f32x4.extract_lane 2
;; CHECK-NEXT:       (local.get $0)
;; CHECK-NEXT:      )
;; CHECK-NEXT:     )
;; CHECK-NEXT:     (f32.eq
;; CHECK-NEXT:      (f32x4.extract_lane 3
;; CHECK-NEXT:       (local.get $0)
;; CHECK-NEXT:      )
;; CHECK-NEXT:      (f32x4.extract_lane 3
;; CHECK-NEXT:       (local.get $0)
;; CHECK-NEXT:      )
;; CHECK-NEXT:     )
;; CHECK-NEXT:    )
;; CHECK-NEXT:   )
;; CHECK-NEXT:   (then
;; CHECK-NEXT:    (local.get $0)
;; CHECK-NEXT:   )
;; CHECK-NEXT:   (else
;; CHECK-NEXT:    (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
;; CHECK-NEXT:   )
;; CHECK-NEXT:  )
;; CHECK-NEXT: )