;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
;; RUN: wasm-opt %s -all --disable-custom-descriptors \
;; RUN:     --type-ssa --roundtrip --fuzz-exec -S -o - | filecheck %s

(module
  ;; CHECK:      (type $foo (struct))
  (type $foo (struct))
  ;; CHECK:      (type $super (sub (struct (field (ref $foo)))))
  (type $super (sub (struct (field (ref $foo)))))
  ;; CHECK:      (type $sub (sub $super (struct (field (ref $foo)))))
  (type $sub (sub $super (struct (field (ref (exact $foo))))))

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

  ;; CHECK:      (rec
  ;; CHECK-NEXT:  (type $super_1 (sub $super (struct (field (ref $foo)))))

  ;; CHECK:       (type $5 (struct))

  ;; CHECK:      (export "test" (func $test))

  ;; CHECK:      (func $test (type $3) (result i32)
  ;; CHECK-NEXT:  (local $sub (ref $sub))
  ;; CHECK-NEXT:  (local $any anyref)
  ;; CHECK-NEXT:  (ref.test (ref $sub)
  ;; CHECK-NEXT:   (select (result anyref)
  ;; CHECK-NEXT:    (struct.new $super_1
  ;; CHECK-NEXT:     (struct.new_default $foo)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (local.get $any)
  ;; CHECK-NEXT:    (i32.const 1)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $test (export "test") (result i32)
    (local $sub (ref $sub))
    (local $any anyref)
    ;; TypeSSA will create another subtype of $super, which will differ from
    ;; $sub because its field will not be exact. However, since exactness will
    ;; be erased by the round trip, we still need a brand type to distinguish
    ;; $sub and the new subtype. If we did not insert a brand type, this
    ;; ref.test would incorrectly return 1 after optimization.
    (ref.test (ref $sub)
      ;; The select stops the ref.test from being optimized by finalization.
      (select (result anyref)
        (struct.new $super
          (struct.new $foo)
        )
        (local.get $any)
        (i32.const 1)
      )
    )
  )
)
