# 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