forked from OSchip/llvm-project
176 lines
4.1 KiB
LLVM
176 lines
4.1 KiB
LLVM
; 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
|