;; 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 --remove-unused-brs --shrink-level=1 -S -o - | filecheck %s

(module
  (memory 256 256)
  (type $0 (func (param i32)))
  ;; CHECK:      (type $2 (func (result i32)))

  ;; CHECK:      (type $1 (func))
  (type $1 (func))
  (type $2 (func (result i32)))
  ;; CHECK:      (memory $0 256 256)

  ;; CHECK:      (func $b14 (result i32)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (select
  ;; CHECK-NEXT:    (block $block1 (result i32)
  ;; CHECK-NEXT:     (i32.const 12)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (block $block3 (result i32)
  ;; CHECK-NEXT:     (i32.const 27)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (i32.const 1)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (if (result i32)
  ;; CHECK-NEXT:    (i32.const 1)
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (i32.load
  ;; CHECK-NEXT:      (i32.const 10)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (else
  ;; CHECK-NEXT:     (i32.const 27)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (select
  ;; CHECK-NEXT:    (i32.rem_s
  ;; CHECK-NEXT:     (i32.const 11)
  ;; CHECK-NEXT:     (i32.const 12)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (i32.const 27)
  ;; CHECK-NEXT:    (i32.const 1)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (if (result i32)
  ;; CHECK-NEXT:    (i32.const 1)
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (i32.trunc_f64_u
  ;; CHECK-NEXT:      (f64.const 12.34)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (else
  ;; CHECK-NEXT:     (i32.const 27)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (i32.const 0)
  ;; CHECK-NEXT: )
  (func $b14 (type $2)
    (drop
      (if (result i32) ;; with shrinking, this can become a select
        (i32.const 1)
        (then
          (block $block1 (result i32)
            (i32.const 12)
          )
        )
        (else
          (block $block3 (result i32)
            (i32.const 27)
          )
        )
      )
    )
    (drop
      (if (result i32)
        (i32.const 1)
        (then
          (i32.load (i32.const 10)) ;; load may have side effects, unless ignored
        )
        (else
          (i32.const 27)
        )
      )
    )
    (drop
      (if (result i32)
        (i32.const 1)
        (then
          (i32.rem_s (i32.const 11) (i32.const 12)) ;; rem may have side effects, unless ignored
        )
        (else
          (i32.const 27)
        )
      )
    )
    (drop
      (if (result i32)
        (i32.const 1)
        (then
          (i32.trunc_f64_u (f64.const 12.34)) ;; float to int may have side effects, unless ignored
        )
        (else
          (i32.const 27)
        )
      )
    )
    (i32.const 0)
  )
  ;; CHECK:      (func $join-br_ifs
  ;; CHECK-NEXT:  (local $x i32)
  ;; CHECK-NEXT:  (block $out
  ;; CHECK-NEXT:   (br_if $out
  ;; CHECK-NEXT:    (i32.or
  ;; CHECK-NEXT:     (local.get $x)
  ;; CHECK-NEXT:     (local.get $x)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (nop)
  ;; CHECK-NEXT:   (br_if $out
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (block $out2
  ;; CHECK-NEXT:   (block $out3
  ;; CHECK-NEXT:    (br_if $out2
  ;; CHECK-NEXT:     (local.get $x)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (br_if $out3
  ;; CHECK-NEXT:     (local.get $x)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (br_if $out2
  ;; CHECK-NEXT:     (local.get $x)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (block $out4
  ;; CHECK-NEXT:   (block $out5
  ;; CHECK-NEXT:    (br_if $out4
  ;; CHECK-NEXT:     (local.get $x)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (br_if $out5
  ;; CHECK-NEXT:     (i32.or
  ;; CHECK-NEXT:      (local.get $x)
  ;; CHECK-NEXT:      (local.get $x)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (nop)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (block $out6
  ;; CHECK-NEXT:   (block $out7
  ;; CHECK-NEXT:    (br_if $out6
  ;; CHECK-NEXT:     (i32.or
  ;; CHECK-NEXT:      (local.get $x)
  ;; CHECK-NEXT:      (local.get $x)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (nop)
  ;; CHECK-NEXT:    (br_if $out7
  ;; CHECK-NEXT:     (local.get $x)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (if
  ;; CHECK-NEXT:   (i32.eqz
  ;; CHECK-NEXT:    (i32.or
  ;; CHECK-NEXT:     (call $b14)
  ;; CHECK-NEXT:     (local.get $x)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (then
  ;; CHECK-NEXT:    (block $out8
  ;; CHECK-NEXT:     (nop)
  ;; CHECK-NEXT:     (nop)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (block $out80
  ;; CHECK-NEXT:   (br_if $out80
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (br_if $out80
  ;; CHECK-NEXT:    (call $b14)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $join-br_ifs
    (local $x i32)
    (block $out
      (br_if $out (local.get $x))
      (br_if $out (local.get $x))
      (br_if $out (local.get $x))
    )
    (block $out2
      (block $out3
        (br_if $out2 (local.get $x))
        (br_if $out3 (local.get $x))
        (br_if $out2 (local.get $x))
      )
      (unreachable)
    )
    (block $out4
      (block $out5
        (br_if $out4 (local.get $x))
        (br_if $out5 (local.get $x))
        (br_if $out5 (local.get $x))
      )
      (unreachable)
    )
    (block $out6
      (block $out7
        (br_if $out6 (local.get $x))
        (br_if $out6 (local.get $x))
        (br_if $out7 (local.get $x))
      )
      (unreachable)
    )
    (block $out8
      (br_if $out8 (call $b14)) ;; side effect
      (br_if $out8 (local.get $x))
    )
    (block $out8
      (br_if $out8 (local.get $x))
      (br_if $out8 (call $b14)) ;; side effect
    )
  )
  ;; CHECK:      (func $join-and-it-becomes-unreachable
  ;; CHECK-NEXT:  (block $label$1
  ;; CHECK-NEXT:   (block
  ;; CHECK-NEXT:    (br_if $label$1
  ;; CHECK-NEXT:     (i32.load8_u
  ;; CHECK-NEXT:      (i32.const -93487262)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (br_if $label$1
  ;; CHECK-NEXT:     (loop $label$5
  ;; CHECK-NEXT:      (br $label$5)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $join-and-it-becomes-unreachable
   (block $label$1
    (block
     (br_if $label$1
      (i32.load8_u
       (i32.const -93487262)
      )
     )
     (br_if $label$1
      (loop $label$5 ;; this is unreachable (infinite loop, no exit)
       (br $label$5)
      )
     )
    )
   )
  )
  ;; CHECK:      (func $br-if-unreachable-pair
  ;; CHECK-NEXT:  (local $x i32)
  ;; CHECK-NEXT:  (block $label$14
  ;; CHECK-NEXT:   (br_if $label$14
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (br_if $label$14
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $br-if-unreachable-pair
   (local $x i32)
   (block $label$14
    (br_if $label$14
     (unreachable)
    )
    (br_if $label$14
     (local.get $x)
    )
   )
  )
  ;; CHECK:      (func $br-if-unreachable-pair2
  ;; CHECK-NEXT:  (local $x i32)
  ;; CHECK-NEXT:  (block $label$14
  ;; CHECK-NEXT:   (br_if $label$14
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (br_if $label$14
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $br-if-unreachable-pair2
   (local $x i32)
   (block $label$14
    (br_if $label$14
     (local.get $x)
    )
    (br_if $label$14
     (unreachable)
    )
   )
  )
  ;; CHECK:      (func $simple-switch (result i32)
  ;; CHECK-NEXT:  (block $A
  ;; CHECK-NEXT:   (block $B
  ;; CHECK-NEXT:    (block $y
  ;; CHECK-NEXT:     (br_table $A $y $y $y $y $y $A $y $y $y $y $A $y
  ;; CHECK-NEXT:      (i32.const 0)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:     (return
  ;; CHECK-NEXT:      (i32.const 0)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (return
  ;; CHECK-NEXT:     (i32.const 1)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (return
  ;; CHECK-NEXT:    (i32.const 2)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (i32.const 3)
  ;; CHECK-NEXT: )
  (func $simple-switch (result i32)
    (block $A
      (block $B
        (block $y
          (br_table $A $y $y $y $y $y $A $y $y $y $y $A $y
            (i32.const 0)
          )
          (return (i32.const 0))
        )
        (return (i32.const 1))
      )
      (return (i32.const 2))
    )
    (return (i32.const 3))
  )
  ;; CHECK:      (func $simple-switch-2 (result i32)
  ;; CHECK-NEXT:  (local $0 i32)
  ;; CHECK-NEXT:  (block $A
  ;; CHECK-NEXT:   (block $B
  ;; CHECK-NEXT:    (block $y
  ;; CHECK-NEXT:     (br_if $A
  ;; CHECK-NEXT:      (i32.or
  ;; CHECK-NEXT:       (i32.eqz
  ;; CHECK-NEXT:        (local.tee $0
  ;; CHECK-NEXT:         (i32.const 0)
  ;; CHECK-NEXT:        )
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:       (i32.eq
  ;; CHECK-NEXT:        (local.get $0)
  ;; CHECK-NEXT:        (i32.const 12)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:     (nop)
  ;; CHECK-NEXT:     (br $y)
  ;; CHECK-NEXT:     (return
  ;; CHECK-NEXT:      (i32.const 0)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (return
  ;; CHECK-NEXT:     (i32.const 1)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (return
  ;; CHECK-NEXT:    (i32.const 2)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (i32.const 3)
  ;; CHECK-NEXT: )
  (func $simple-switch-2 (result i32)
    (block $A
      (block $B
        (block $y
          (br_table $A $y $y $y $y $y $y $y $y $y $y $y $A $y
            (i32.const 0)
          )
          (return (i32.const 0))
        )
        (return (i32.const 1))
      )
      (return (i32.const 2))
    )
    (return (i32.const 3))
  )
  ;; CHECK:      (func $simple-switch-3 (result i32)
  ;; CHECK-NEXT:  (local $0 i32)
  ;; CHECK-NEXT:  (block $A
  ;; CHECK-NEXT:   (block $B
  ;; CHECK-NEXT:    (block $y
  ;; CHECK-NEXT:     (br_if $A
  ;; CHECK-NEXT:      (i32.eqz
  ;; CHECK-NEXT:       (local.tee $0
  ;; CHECK-NEXT:        (i32.const 0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:     (br_if $B
  ;; CHECK-NEXT:      (i32.eq
  ;; CHECK-NEXT:       (local.get $0)
  ;; CHECK-NEXT:       (i32.const 1025)
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:     (br $y)
  ;; CHECK-NEXT:     (return
  ;; CHECK-NEXT:      (i32.const 0)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (return
  ;; CHECK-NEXT:     (i32.const 1)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (return
  ;; CHECK-NEXT:    (i32.const 2)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (i32.const 3)
  ;; CHECK-NEXT: )
  (func $simple-switch-3 (result i32)
    (block $A
      (block $B
        (block $y
          (br_table $A $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $y $B $y
            (i32.const 0)
          )
          (return (i32.const 0))
        )
        (return (i32.const 1))
      )
      (return (i32.const 2))
    )
    (return (i32.const 3))
  )
  ;; CHECK:      (func $simple-switch-4 (result i32)
  ;; CHECK-NEXT:  (block $A
  ;; CHECK-NEXT:   (block $B
  ;; CHECK-NEXT:    (block $y
  ;; CHECK-NEXT:     (br_table $A $y $y $y $y $y $A $y $y $y $y $y $A $y
  ;; CHECK-NEXT:      (i32.const 0)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:     (return
  ;; CHECK-NEXT:      (i32.const 0)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (return
  ;; CHECK-NEXT:     (i32.const 1)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (return
  ;; CHECK-NEXT:    (i32.const 2)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (i32.const 3)
  ;; CHECK-NEXT: )
  (func $simple-switch-4 (result i32)
    (block $A
      (block $B
        (block $y
          (br_table $A $y $y $y $y $y $A $y $y $y $y $y $A $y
            (i32.const 0)
          )
          (return (i32.const 0))
        )
        (return (i32.const 1))
      )
      (return (i32.const 2))
    )
    (return (i32.const 3))
  )
)
