| ; RUN: llc -mtriple x86_64-pc-windows-msvc < %s | FileCheck %s |
| |
| define void @two_invoke_merged() { |
| entry: |
| invoke void @try_body() |
| to label %again unwind label %lpad |
| |
| again: |
| invoke void @try_body() |
| to label %done unwind label %lpad |
| |
| done: |
| ret void |
| |
| lpad: |
| %vals = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) |
| catch i8* bitcast (i32 (i8*, i8*)* @filt0 to i8*) |
| catch i8* bitcast (i32 (i8*, i8*)* @filt1 to i8*) |
| %sel = extractvalue { i8*, i32 } %vals, 1 |
| call void @use_selector(i32 %sel) |
| ret void |
| } |
| |
| ; Normal path code |
| |
| ; CHECK-LABEL: {{^}}two_invoke_merged: |
| ; CHECK: .seh_proc two_invoke_merged |
| ; CHECK: .seh_handler __C_specific_handler, @unwind, @except |
| ; CHECK: .Ltmp0: |
| ; CHECK: callq try_body |
| ; CHECK-NEXT: .Ltmp1: |
| ; CHECK: .Ltmp2: |
| ; CHECK: callq try_body |
| ; CHECK-NEXT: .Ltmp3: |
| ; CHECK: retq |
| |
| ; Landing pad code |
| |
| ; CHECK: .Ltmp5: |
| ; CHECK: movl $1, %ecx |
| ; CHECK: jmp |
| ; CHECK: .Ltmp6: |
| ; CHECK: movl $2, %ecx |
| ; CHECK: callq use_selector |
| |
| ; CHECK: .seh_handlerdata |
| ; CHECK-NEXT: .long 2 |
| ; CHECK-NEXT: .long .Ltmp0@IMGREL |
| ; CHECK-NEXT: .long .Ltmp3@IMGREL+1 |
| ; CHECK-NEXT: .long filt0@IMGREL |
| ; CHECK-NEXT: .long .Ltmp5@IMGREL |
| ; CHECK-NEXT: .long .Ltmp0@IMGREL |
| ; CHECK-NEXT: .long .Ltmp3@IMGREL+1 |
| ; CHECK-NEXT: .long filt1@IMGREL |
| ; CHECK-NEXT: .long .Ltmp6@IMGREL |
| ; CHECK: .text |
| ; CHECK: .seh_endproc |
| |
| define void @two_invoke_gap() { |
| entry: |
| invoke void @try_body() |
| to label %again unwind label %lpad |
| |
| again: |
| call void @do_nothing_on_unwind() |
| invoke void @try_body() |
| to label %done unwind label %lpad |
| |
| done: |
| ret void |
| |
| lpad: |
| %vals = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) |
| catch i8* bitcast (i32 (i8*, i8*)* @filt0 to i8*) |
| %sel = extractvalue { i8*, i32 } %vals, 1 |
| call void @use_selector(i32 %sel) |
| ret void |
| } |
| |
| ; Normal path code |
| |
| ; CHECK-LABEL: {{^}}two_invoke_gap: |
| ; CHECK: .seh_proc two_invoke_gap |
| ; CHECK: .seh_handler __C_specific_handler, @unwind, @except |
| ; CHECK: .Ltmp11: |
| ; CHECK: callq try_body |
| ; CHECK-NEXT: .Ltmp12: |
| ; CHECK: callq do_nothing_on_unwind |
| ; CHECK: .Ltmp13: |
| ; CHECK: callq try_body |
| ; CHECK-NEXT: .Ltmp14: |
| ; CHECK: retq |
| |
| ; Landing pad code |
| |
| ; CHECK: .Ltmp16: |
| ; CHECK: movl $1, %ecx |
| ; CHECK: callq use_selector |
| |
| ; CHECK: .seh_handlerdata |
| ; CHECK-NEXT: .long 2 |
| ; CHECK-NEXT: .long .Ltmp11@IMGREL |
| ; CHECK-NEXT: .long .Ltmp12@IMGREL+1 |
| ; CHECK-NEXT: .long filt0@IMGREL |
| ; CHECK-NEXT: .long .Ltmp16@IMGREL |
| ; CHECK-NEXT: .long .Ltmp13@IMGREL |
| ; CHECK-NEXT: .long .Ltmp14@IMGREL+1 |
| ; CHECK-NEXT: .long filt0@IMGREL |
| ; CHECK-NEXT: .long .Ltmp16@IMGREL |
| ; CHECK: .text |
| ; CHECK: .seh_endproc |
| |
| define void @two_invoke_nounwind_gap() { |
| entry: |
| invoke void @try_body() |
| to label %again unwind label %lpad |
| |
| again: |
| call void @cannot_unwind() |
| invoke void @try_body() |
| to label %done unwind label %lpad |
| |
| done: |
| ret void |
| |
| lpad: |
| %vals = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) |
| catch i8* bitcast (i32 (i8*, i8*)* @filt0 to i8*) |
| %sel = extractvalue { i8*, i32 } %vals, 1 |
| call void @use_selector(i32 %sel) |
| ret void |
| } |
| |
| ; Normal path code |
| |
| ; CHECK-LABEL: {{^}}two_invoke_nounwind_gap: |
| ; CHECK: .seh_proc two_invoke_nounwind_gap |
| ; CHECK: .seh_handler __C_specific_handler, @unwind, @except |
| ; CHECK: .Ltmp21: |
| ; CHECK: callq try_body |
| ; CHECK-NEXT: .Ltmp22: |
| ; CHECK: callq cannot_unwind |
| ; CHECK: .Ltmp23: |
| ; CHECK: callq try_body |
| ; CHECK-NEXT: .Ltmp24: |
| ; CHECK: retq |
| |
| ; Landing pad code |
| |
| ; CHECK: .Ltmp26: |
| ; CHECK: movl $1, %ecx |
| ; CHECK: callq use_selector |
| |
| ; CHECK: .seh_handlerdata |
| ; CHECK-NEXT: .long 1 |
| ; CHECK-NEXT: .long .Ltmp21@IMGREL |
| ; CHECK-NEXT: .long .Ltmp24@IMGREL+1 |
| ; CHECK-NEXT: .long filt0@IMGREL |
| ; CHECK-NEXT: .long .Ltmp26@IMGREL |
| ; CHECK: .text |
| ; CHECK: .seh_endproc |
| |
| declare void @try_body() |
| declare void @do_nothing_on_unwind() |
| declare void @cannot_unwind() nounwind |
| declare void @use_selector(i32) |
| |
| declare i32 @filt0(i8* %eh_info, i8* %rsp) |
| declare i32 @filt1(i8* %eh_info, i8* %rsp) |
| |
| declare void @handler0() |
| declare void @handler1() |
| |
| declare i32 @__C_specific_handler(...) |
| declare i32 @llvm.eh.typeid.for(i8*) readnone nounwind |