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

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

;; RUN: wasm-opt -all --roundtrip %s -S -o - | filecheck %s --check-prefix=RTRIP

;; RUN: wasm-opt -all %s -g -o %t.wasm -osm %t.map
;; RUN: wasm-opt -all %t.wasm -ism %t.map -S -o - | filecheck %s --check-prefix=SRCMP

(module

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

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

  ;; CHECK:      (func $no-annotations (type $0) (param $x i32)
  ;; CHECK-NEXT:  (block $out
  ;; CHECK-NEXT:   (br_if $out
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  ;; RTRIP:      (type $0 (func (param i32)))

  ;; RTRIP:      (type $1 (func (param anyref)))

  ;; RTRIP:      (func $no-annotations (type $0) (param $x i32)
  ;; RTRIP-NEXT:  (block $block
  ;; RTRIP-NEXT:   (br_if $block
  ;; RTRIP-NEXT:    (local.get $x)
  ;; RTRIP-NEXT:   )
  ;; RTRIP-NEXT:  )
  ;; RTRIP-NEXT: )
  ;; SRCMP:      (type $0 (func (param i32)))

  ;; SRCMP:      (type $1 (func (param anyref)))

  ;; SRCMP:      (func $no-annotations (type $0) (param $x i32)
  ;; SRCMP-NEXT:  (block $block
  ;; SRCMP-NEXT:   (br_if $block
  ;; SRCMP-NEXT:    (local.get $x)
  ;; SRCMP-NEXT:   )
  ;; SRCMP-NEXT:  )
  ;; SRCMP-NEXT: )
  (func $no-annotations (param $x i32)
    ;; A function with no annotations. This tests that we use function indexes
    ;; properly in the section.
    (block $out
      (br_if $out
        (local.get $x)
      )
    )
  )

  ;; CHECK:      (func $branch-hints-br_if (type $0) (param $x i32)
  ;; CHECK-NEXT:  (block $out
  ;; CHECK-NEXT:   (@metadata.code.branch_hint "\00")
  ;; CHECK-NEXT:   (br_if $out
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (@metadata.code.branch_hint "\01")
  ;; CHECK-NEXT:   (br_if $out
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (@metadata.code.branch_hint "\00")
  ;; CHECK-NEXT:   (br_if $out
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  ;; RTRIP:      (func $branch-hints-br_if (type $0) (param $x i32)
  ;; RTRIP-NEXT:  (block $block
  ;; RTRIP-NEXT:   (@metadata.code.branch_hint "\00")
  ;; RTRIP-NEXT:   (br_if $block
  ;; RTRIP-NEXT:    (local.get $x)
  ;; RTRIP-NEXT:   )
  ;; RTRIP-NEXT:   (@metadata.code.branch_hint "\01")
  ;; RTRIP-NEXT:   (br_if $block
  ;; RTRIP-NEXT:    (local.get $x)
  ;; RTRIP-NEXT:   )
  ;; RTRIP-NEXT:   (@metadata.code.branch_hint "\00")
  ;; RTRIP-NEXT:   (br_if $block
  ;; RTRIP-NEXT:    (local.get $x)
  ;; RTRIP-NEXT:   )
  ;; RTRIP-NEXT:  )
  ;; RTRIP-NEXT: )
  ;; SRCMP:      (func $branch-hints-br_if (type $0) (param $x i32)
  ;; SRCMP-NEXT:  (block $block
  ;; SRCMP-NEXT:   (@metadata.code.branch_hint "\00")
  ;; SRCMP-NEXT:   (br_if $block
  ;; SRCMP-NEXT:    (local.get $x)
  ;; SRCMP-NEXT:   )
  ;; SRCMP-NEXT:   (@metadata.code.branch_hint "\01")
  ;; SRCMP-NEXT:   (br_if $block
  ;; SRCMP-NEXT:    (local.get $x)
  ;; SRCMP-NEXT:   )
  ;; SRCMP-NEXT:   (@metadata.code.branch_hint "\00")
  ;; SRCMP-NEXT:   (br_if $block
  ;; SRCMP-NEXT:    (local.get $x)
  ;; SRCMP-NEXT:   )
  ;; SRCMP-NEXT:  )
  ;; SRCMP-NEXT: )
  (func $branch-hints-br_if (param $x i32)
    (block $out
      ;; A branch annotated as unlikely, and one as likely.
      (@metadata.code.branch_hint "\00")
      (br_if $out
        (local.get $x)
      )
      (@metadata.code.branch_hint "\01")
      (br_if $out
        (local.get $x)
      )
      ;; The last one wins.
      (@metadata.code.branch_hint "\01")
      (@metadata.code.branch_hint "\00")
      (br_if $out
        (local.get $x)
      )
    )
  )

  ;; CHECK:      (func $branch_hints-br_if-2 (type $0) (param $x i32)
  ;; CHECK-NEXT:  (local $unused f64)
  ;; CHECK-NEXT:  (block $out
  ;; CHECK-NEXT:   (@metadata.code.branch_hint "\01")
  ;; CHECK-NEXT:   (br_if $out
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  ;; RTRIP:      (func $branch_hints-br_if-2 (type $0) (param $x i32)
  ;; RTRIP-NEXT:  (local $unused f64)
  ;; RTRIP-NEXT:  (block $block
  ;; RTRIP-NEXT:   (@metadata.code.branch_hint "\01")
  ;; RTRIP-NEXT:   (br_if $block
  ;; RTRIP-NEXT:    (local.get $x)
  ;; RTRIP-NEXT:   )
  ;; RTRIP-NEXT:  )
  ;; RTRIP-NEXT: )
  ;; SRCMP:      (func $branch_hints-br_if-2 (type $0) (param $x i32)
  ;; SRCMP-NEXT:  (local $unused f64)
  ;; SRCMP-NEXT:  (block $block
  ;; SRCMP-NEXT:   (@metadata.code.branch_hint "\01")
  ;; SRCMP-NEXT:   (br_if $block
  ;; SRCMP-NEXT:    (local.get $x)
  ;; SRCMP-NEXT:   )
  ;; SRCMP-NEXT:  )
  ;; SRCMP-NEXT: )
  (func $branch_hints-br_if-2 (param $x i32)
    (local $unused f64)
    ;; A second function with hints. This one also has local definitions, which
    ;; should not confuse us (branch hint offsets are relative to the start of
    ;; the local definitions, not the end).
    (block $out
      (@metadata.code.branch_hint "\01")
      (br_if $out
        (local.get $x)
      )
    )
  )

  ;; CHECK:      (func $mixing (type $0) (param $x i32)
  ;; CHECK-NEXT:  ;;@ mixing.src:1337:42
  ;; CHECK-NEXT:  (block $out
  ;; CHECK-NEXT:   (@metadata.code.branch_hint "\01")
  ;; CHECK-NEXT:   (br_if $out
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  ;; RTRIP:      (func $mixing (type $0) (param $x i32)
  ;; RTRIP-NEXT:  (block $block
  ;; RTRIP-NEXT:   (@metadata.code.branch_hint "\01")
  ;; RTRIP-NEXT:   (br_if $block
  ;; RTRIP-NEXT:    (local.get $x)
  ;; RTRIP-NEXT:   )
  ;; RTRIP-NEXT:  )
  ;; RTRIP-NEXT: )
  ;; SRCMP:      (func $mixing (type $0) (param $x i32)
  ;; SRCMP-NEXT:  ;;@ mixing.src:1337:42
  ;; SRCMP-NEXT:  (block $block
  ;; SRCMP-NEXT:   (@metadata.code.branch_hint "\01")
  ;; SRCMP-NEXT:   (br_if $block
  ;; SRCMP-NEXT:    (local.get $x)
  ;; SRCMP-NEXT:   )
  ;; SRCMP-NEXT:  )
  ;; SRCMP-NEXT: )
  (func $mixing (param $x i32)
    ;; Mix branch hints with source locations. Both hints should remain (though
    ;; not in --roundtrip, which does not use source maps).
    ;;@ mixing.src:1337:42
    (block $out
      (@metadata.code.branch_hint "\01")
      (br_if $out
        (local.get $x)
      )
    )
  )

  ;; CHECK:      (func $branch-hints-if (type $0) (param $x i32)
  ;; CHECK-NEXT:  (@metadata.code.branch_hint "\00")
  ;; CHECK-NEXT:  (if
  ;; CHECK-NEXT:   (local.get $x)
  ;; CHECK-NEXT:   (then
  ;; CHECK-NEXT:    (@metadata.code.branch_hint "\01")
  ;; CHECK-NEXT:    (if
  ;; CHECK-NEXT:     (local.get $x)
  ;; CHECK-NEXT:     (then
  ;; CHECK-NEXT:      (nop)
  ;; CHECK-NEXT:     )
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  ;; RTRIP:      (func $branch-hints-if (type $0) (param $x i32)
  ;; RTRIP-NEXT:  (@metadata.code.branch_hint "\00")
  ;; RTRIP-NEXT:  (if
  ;; RTRIP-NEXT:   (local.get $x)
  ;; RTRIP-NEXT:   (then
  ;; RTRIP-NEXT:    (@metadata.code.branch_hint "\01")
  ;; RTRIP-NEXT:    (if
  ;; RTRIP-NEXT:     (local.get $x)
  ;; RTRIP-NEXT:     (then
  ;; RTRIP-NEXT:      (nop)
  ;; RTRIP-NEXT:     )
  ;; RTRIP-NEXT:    )
  ;; RTRIP-NEXT:   )
  ;; RTRIP-NEXT:  )
  ;; RTRIP-NEXT: )
  ;; SRCMP:      (func $branch-hints-if (type $0) (param $x i32)
  ;; SRCMP-NEXT:  (@metadata.code.branch_hint "\00")
  ;; SRCMP-NEXT:  (if
  ;; SRCMP-NEXT:   (local.get $x)
  ;; SRCMP-NEXT:   (then
  ;; SRCMP-NEXT:    (@metadata.code.branch_hint "\01")
  ;; SRCMP-NEXT:    (if
  ;; SRCMP-NEXT:     (local.get $x)
  ;; SRCMP-NEXT:     (then
  ;; SRCMP-NEXT:      (nop)
  ;; SRCMP-NEXT:     )
  ;; SRCMP-NEXT:    )
  ;; SRCMP-NEXT:   )
  ;; SRCMP-NEXT:  )
  ;; SRCMP-NEXT: )
  (func $branch-hints-if (param $x i32)
    (@metadata.code.branch_hint "\00")
    (if
      (local.get $x)
      (then
        (@metadata.code.branch_hint "\01")
        (if
          (local.get $x)
          (then
            (nop)
          )
        )
      )
    )
  )

  ;; CHECK:      (func $branch-hints-if-else (type $0) (param $x i32)
  ;; CHECK-NEXT:  (@metadata.code.branch_hint "\01")
  ;; CHECK-NEXT:  (if
  ;; CHECK-NEXT:   (local.get $x)
  ;; CHECK-NEXT:   (then
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (i32.const 1)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (else
  ;; CHECK-NEXT:    (drop
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  ;; RTRIP:      (func $branch-hints-if-else (type $0) (param $x i32)
  ;; RTRIP-NEXT:  (@metadata.code.branch_hint "\01")
  ;; RTRIP-NEXT:  (if
  ;; RTRIP-NEXT:   (local.get $x)
  ;; RTRIP-NEXT:   (then
  ;; RTRIP-NEXT:    (drop
  ;; RTRIP-NEXT:     (i32.const 1)
  ;; RTRIP-NEXT:    )
  ;; RTRIP-NEXT:   )
  ;; RTRIP-NEXT:   (else
  ;; RTRIP-NEXT:    (drop
  ;; RTRIP-NEXT:     (i32.const 0)
  ;; RTRIP-NEXT:    )
  ;; RTRIP-NEXT:   )
  ;; RTRIP-NEXT:  )
  ;; RTRIP-NEXT: )
  ;; SRCMP:      (func $branch-hints-if-else (type $0) (param $x i32)
  ;; SRCMP-NEXT:  (@metadata.code.branch_hint "\01")
  ;; SRCMP-NEXT:  (if
  ;; SRCMP-NEXT:   (local.get $x)
  ;; SRCMP-NEXT:   (then
  ;; SRCMP-NEXT:    (drop
  ;; SRCMP-NEXT:     (i32.const 1)
  ;; SRCMP-NEXT:    )
  ;; SRCMP-NEXT:   )
  ;; SRCMP-NEXT:   (else
  ;; SRCMP-NEXT:    (drop
  ;; SRCMP-NEXT:     (i32.const 0)
  ;; SRCMP-NEXT:    )
  ;; SRCMP-NEXT:   )
  ;; SRCMP-NEXT:  )
  ;; SRCMP-NEXT: )
  (func $branch-hints-if-else (param $x i32)
    (@metadata.code.branch_hint "\01")
    (if
      (local.get $x)
      (then
        (drop
          (i32.const 1)
        )
      )
      (else
        (drop
          (i32.const 0)
        )
      )
    )
  )

  ;; CHECK:      (func $branch-hints-if-else-result (type $0) (param $x i32)
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (@metadata.code.branch_hint "\01")
  ;; CHECK-NEXT:   (if (result i32)
  ;; CHECK-NEXT:    (local.get $x)
  ;; CHECK-NEXT:    (then
  ;; CHECK-NEXT:     (i32.const 1)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:    (else
  ;; CHECK-NEXT:     (i32.const 0)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  ;; RTRIP:      (func $branch-hints-if-else-result (type $0) (param $x i32)
  ;; RTRIP-NEXT:  (drop
  ;; RTRIP-NEXT:   (@metadata.code.branch_hint "\01")
  ;; RTRIP-NEXT:   (if (result i32)
  ;; RTRIP-NEXT:    (local.get $x)
  ;; RTRIP-NEXT:    (then
  ;; RTRIP-NEXT:     (i32.const 1)
  ;; RTRIP-NEXT:    )
  ;; RTRIP-NEXT:    (else
  ;; RTRIP-NEXT:     (i32.const 0)
  ;; RTRIP-NEXT:    )
  ;; RTRIP-NEXT:   )
  ;; RTRIP-NEXT:  )
  ;; RTRIP-NEXT: )
  ;; SRCMP:      (func $branch-hints-if-else-result (type $0) (param $x i32)
  ;; SRCMP-NEXT:  (drop
  ;; SRCMP-NEXT:   (@metadata.code.branch_hint "\01")
  ;; SRCMP-NEXT:   (if (result i32)
  ;; SRCMP-NEXT:    (local.get $x)
  ;; SRCMP-NEXT:    (then
  ;; SRCMP-NEXT:     (i32.const 1)
  ;; SRCMP-NEXT:    )
  ;; SRCMP-NEXT:    (else
  ;; SRCMP-NEXT:     (i32.const 0)
  ;; SRCMP-NEXT:    )
  ;; SRCMP-NEXT:   )
  ;; SRCMP-NEXT:  )
  ;; SRCMP-NEXT: )
  (func $branch-hints-if-else-result (param $x i32)
    (drop
      (@metadata.code.branch_hint "\01")
      (if (result i32)
        (local.get $x)
        (then
          (i32.const 1)
        )
        (else
          (i32.const 0)
        )
      )
    )
  )

  ;; CHECK:      (func $branch-hints-br_on (type $1) (param $x anyref)
  ;; CHECK-NEXT:  (block $out
  ;; CHECK-NEXT:   (drop
  ;; CHECK-NEXT:    (@metadata.code.branch_hint "\00")
  ;; CHECK-NEXT:    (br_on_null $out
  ;; CHECK-NEXT:     (local.get $x)
  ;; CHECK-NEXT:    )
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  ;; RTRIP:      (func $branch-hints-br_on (type $1) (param $x anyref)
  ;; RTRIP-NEXT:  (block $block
  ;; RTRIP-NEXT:   (drop
  ;; RTRIP-NEXT:    (@metadata.code.branch_hint "\00")
  ;; RTRIP-NEXT:    (br_on_null $block
  ;; RTRIP-NEXT:     (local.get $x)
  ;; RTRIP-NEXT:    )
  ;; RTRIP-NEXT:   )
  ;; RTRIP-NEXT:  )
  ;; RTRIP-NEXT: )
  ;; SRCMP:      (func $branch-hints-br_on (type $1) (param $x anyref)
  ;; SRCMP-NEXT:  (block $block
  ;; SRCMP-NEXT:   (drop
  ;; SRCMP-NEXT:    (@metadata.code.branch_hint "\00")
  ;; SRCMP-NEXT:    (br_on_null $block
  ;; SRCMP-NEXT:     (local.get $x)
  ;; SRCMP-NEXT:    )
  ;; SRCMP-NEXT:   )
  ;; SRCMP-NEXT:  )
  ;; SRCMP-NEXT: )
  (func $branch-hints-br_on (param $x anyref)
    (block $out
      (drop
        (@metadata.code.branch_hint "\00")
        (br_on_null $out
          (local.get $x)
        )
      )
    )
  )
)
