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

;; Check that we optimize the cast correctly when the fallthrough has exact
;; type, whether or not custom descriptors is enabled.

;; RUN: wasm-opt %s -all                              --remove-unused-brs -S -o - | filecheck %s
;; RUN: wasm-opt %s -all --disable-custom-descriptors --remove-unused-brs -S -o - | filecheck %s --check-prefix=NO_CD

(module
  ;; CHECK:      (type $foo (struct))
  ;; NO_CD:      (type $foo (struct))
  (type $foo (struct))

  ;; CHECK:      (func $br_on_cast (type $1) (param $0 (ref (exact $foo)))
  ;; CHECK-NEXT:  (local $inexact (ref $foo))
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block $block (result (ref (exact $foo)))
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (br $block
  ;; CHECK-NEXT:      (ref.cast (ref (exact $foo))
  ;; CHECK-NEXT:       (local.tee $inexact
  ;; CHECK-NEXT:        (local.get $0)
  ;; CHECK-NEXT:       )
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (local.get $0)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  ;; NO_CD:      (func $br_on_cast (type $1) (param $0 (ref (exact $foo)))
  ;; NO_CD-NEXT:  (local $inexact (ref $foo))
  ;; NO_CD-NEXT:  (drop
  ;; NO_CD-NEXT:   (block $block (result (ref $foo))
  ;; NO_CD-NEXT:    (drop
  ;; NO_CD-NEXT:     (br $block
  ;; NO_CD-NEXT:      (local.tee $inexact
  ;; NO_CD-NEXT:       (local.get $0)
  ;; NO_CD-NEXT:      )
  ;; NO_CD-NEXT:     )
  ;; NO_CD-NEXT:    )
  ;; NO_CD-NEXT:    (local.get $0)
  ;; NO_CD-NEXT:   )
  ;; NO_CD-NEXT:  )
  ;; NO_CD-NEXT: )
  (func $br_on_cast (param (ref (exact $foo)))
    (local $inexact (ref $foo))
    (drop
      (block (result (ref $foo))
        (drop
          (br_on_cast 0 anyref (ref $foo)
            (local.tee $inexact
              (local.get 0)
            )
          )
        )
        (local.get 0)
      )
    )
  )

  ;; CHECK:      (func $br_on_cast_fail (type $1) (param $0 (ref (exact $foo)))
  ;; CHECK-NEXT:  (local $inexact (ref $foo))
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block $block (result (ref (exact $foo)))
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (ref.cast (ref (exact $foo))
  ;; CHECK-NEXT:      (local.tee $inexact
  ;; CHECK-NEXT:       (local.get $0)
  ;; CHECK-NEXT:      )
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (local.get $0)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  ;; NO_CD:      (func $br_on_cast_fail (type $1) (param $0 (ref (exact $foo)))
  ;; NO_CD-NEXT:  (local $inexact (ref $foo))
  ;; NO_CD-NEXT:  (drop
  ;; NO_CD-NEXT:   (block $block (result (ref (exact $foo)))
  ;; NO_CD-NEXT:    (drop
  ;; NO_CD-NEXT:     (local.tee $inexact
  ;; NO_CD-NEXT:      (local.get $0)
  ;; NO_CD-NEXT:     )
  ;; NO_CD-NEXT:    )
  ;; NO_CD-NEXT:    (local.get $0)
  ;; NO_CD-NEXT:   )
  ;; NO_CD-NEXT:  )
  ;; NO_CD-NEXT: )
  (func $br_on_cast_fail (param (ref (exact $foo)))
    (local $inexact (ref $foo))
    (drop
      (block (result (ref $foo))
        (drop
          (br_on_cast_fail 0 anyref (ref $foo)
            (local.tee $inexact
              (local.get 0)
            )
          )
        )
        (local.get 0)
      )
    )
  )
)
