llvm/llvm/test/MC/WebAssembly/block-assembly.s

# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+exception-handling < %s | FileCheck %s
# Check that it converts to .o without errors, but don't check any output:
# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+exception-handling -filetype=obj -o %t.o < %s

  .tagtype  __cpp_exception i32

block_branch_test:
  .functype  block_branch_test () -> ()

  # Block input paramter / return tests

  i32.const 0
  block (i32) -> (i32)
  end_block
  drop

  i32.const 0
  i64.const 0
  block (i32, i64) -> (i32, f32)
    drop
    f32.const 0.0
  end_block
  drop
  drop

  i32.const 0
  loop (i32) -> (f32)
    drop
    f32.const 0.0
  end_loop
  drop

  i32.const 0
  i32.const 0
  if (i32) -> (i32)
  else
    i32.popcnt
  end_if
  drop

  try i32
    i32.const 0
  catch       __cpp_exception
    i32.clz
  catch_all
    i32.const 5
  end_try
  drop

  i32.const 0
  block (i32) -> (i32)
    block (i32) -> (f32)
      drop
      f32.const 0.0
    end_block
    drop
    i32.const 0
  end_block
  drop

  # Branch tests

  block f32
    f32.const 0.0
    i32.const 0
    br_if 0
    f32.const 1.0
    br 0
    # After 'br', we can pop any values from the polymorphic stack
    i32.add
    i32.sub
    i32.mul
    drop
  end_block
  drop

  block () -> (f32, f64)
    f32.const 0.0
    f64.const 0.0
    i32.const 0
    br_if 0
    block (f32, f64) -> (f32, f64)
      i32.const 1
      br_if 0
    end_block
  end_block
  drop
  drop

  # Within a loop, branches target the start of the loop
  i32.const 0
  loop (i32) -> ()
    i32.const 1
    br 0
  end_loop

  end_function

# CHECK-LABEL: block_branch_test

# CHECK:         i32.const  0
# CHECK-NEXT:    block     (i32) -> (i32)
# CHECK-NEXT:    end_block                               # label0:
# CHECK-NEXT:    drop

# CHECK:         i32.const  0
# CHECK-NEXT:    i64.const  0
# CHECK-NEXT:    block     (i32, i64) -> (i32, f32)
# CHECK-NEXT:    drop
# CHECK-NEXT:    f32.const  0x0p0
# CHECK-NEXT:    end_block                               # label1:
# CHECK-NEXT:    drop
# CHECK-NEXT:    drop

# CHECK:         i32.const  0
# CHECK-NEXT:    loop      (i32) -> (f32)                  # label2:
# CHECK-NEXT:    drop
# CHECK-NEXT:    f32.const  0x0p0
# CHECK-NEXT:    end_loop
# CHECK-NEXT:    drop

# CHECK:         i32.const  0
# CHECK-NEXT:    i32.const  0
# CHECK-NEXT:    if      (i32) -> (i32)
# CHECK-NEXT:    else
# CHECK-NEXT:    i32.popcnt
# CHECK-NEXT:    end_if
# CHECK-NEXT:    drop

# CHECK:         try       i32
# CHECK-NEXT:    i32.const  0
# CHECK-NEXT:    catch     __cpp_exception                 # catch3:
# CHECK-NEXT:    i32.clz
# CHECK-NEXT:    catch_all
# CHECK-NEXT:    i32.const  5
# CHECK-NEXT:    end_try                                 # label3:
# CHECK-NEXT:    drop

# CHECK:         i32.const  0
# CHECK-NEXT:    block     (i32) -> (i32)
# CHECK-NEXT:    block     (i32) -> (f32)
# CHECK-NEXT:    drop
# CHECK-NEXT:    f32.const  0x0p0
# CHECK-NEXT:    end_block                               # label5:
# CHECK-NEXT:    drop
# CHECK-NEXT:    i32.const  0
# CHECK-NEXT:    end_block                               # label4:
# CHECK-NEXT:    drop

# CHECK:         block     f32
# CHECK-NEXT:    f32.const  0x0p0
# CHECK-NEXT:    i32.const  0
# CHECK-NEXT:    br_if     0                               # 0: down to label6
# CHECK-NEXT:    f32.const  0x1p0
# CHECK-NEXT:    br        0                               # 0: down to label6
# CHECK-NEXT:    i32.add
# CHECK-NEXT:    i32.sub
# CHECK-NEXT:    i32.mul
# CHECK-NEXT:    drop
# CHECK-NEXT:    end_block                               # label6:
# CHECK-NEXT:    drop

# CHECK:         block     () -> (f32, f64)
# CHECK-NEXT:    f32.const  0x0p0
# CHECK-NEXT:    f64.const  0x0p0
# CHECK-NEXT:    i32.const  0
# CHECK-NEXT:    br_if     0                               # 0: down to label7
# CHECK-NEXT:    block     (f32, f64) -> (f32, f64)
# CHECK-NEXT:    i32.const  1
# CHECK-NEXT:    br_if     0                               # 0: down to label8
# CHECK-NEXT:    end_block                               # label8:
# CHECK-NEXT:    end_block                               # label7:
# CHECK-NEXT:    drop
# CHECK-NEXT:    drop

# CHECK:         i32.const  0
# CHECK-NEXT:    loop      (i32) -> ()                     # label9:
# CHECK-NEXT:    i32.const  1
# CHECK-NEXT:    br        0                               # 0: up to label9
# CHECK-NEXT:    end_loop

# CHECK:         end_function