1; RUN: llc -mtriple x86_64-pc-windows-msvc < %s | FileCheck %s
2
3define void @two_invoke_merged() {
4entry:
5  invoke void @try_body()
6          to label %again unwind label %lpad
7
8again:
9  invoke void @try_body()
10          to label %done unwind label %lpad
11
12done:
13  ret void
14
15lpad:
16  %vals = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
17          catch i8* bitcast (i32 (i8*, i8*)* @filt0 to i8*)
18          catch i8* bitcast (i32 (i8*, i8*)* @filt1 to i8*)
19  %sel = extractvalue { i8*, i32 } %vals, 1
20  call void @use_selector(i32 %sel)
21  ret void
22}
23
24; Normal path code
25
26; CHECK-LABEL: {{^}}two_invoke_merged:
27; CHECK: .seh_proc two_invoke_merged
28; CHECK: .seh_handler __C_specific_handler, @unwind, @except
29; CHECK: .Ltmp0:
30; CHECK: callq try_body
31; CHECK-NEXT: .Ltmp1:
32; CHECK: .Ltmp2:
33; CHECK: callq try_body
34; CHECK-NEXT: .Ltmp3:
35; CHECK: retq
36
37; Landing pad code
38
39; CHECK: .Ltmp5:
40; CHECK: movl $1, %ecx
41; CHECK: jmp
42; CHECK: .Ltmp6:
43; CHECK: movl $2, %ecx
44; CHECK: callq use_selector
45
46; CHECK: .seh_handlerdata
47; CHECK-NEXT: .long 2
48; CHECK-NEXT: .long .Ltmp0@IMGREL
49; CHECK-NEXT: .long .Ltmp3@IMGREL+1
50; CHECK-NEXT: .long filt0@IMGREL
51; CHECK-NEXT: .long .Ltmp5@IMGREL
52; CHECK-NEXT: .long .Ltmp0@IMGREL
53; CHECK-NEXT: .long .Ltmp3@IMGREL+1
54; CHECK-NEXT: .long filt1@IMGREL
55; CHECK-NEXT: .long .Ltmp6@IMGREL
56; CHECK: .text
57; CHECK: .seh_endproc
58
59define void @two_invoke_gap() {
60entry:
61  invoke void @try_body()
62          to label %again unwind label %lpad
63
64again:
65  call void @do_nothing_on_unwind()
66  invoke void @try_body()
67          to label %done unwind label %lpad
68
69done:
70  ret void
71
72lpad:
73  %vals = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
74          catch i8* bitcast (i32 (i8*, i8*)* @filt0 to i8*)
75  %sel = extractvalue { i8*, i32 } %vals, 1
76  call void @use_selector(i32 %sel)
77  ret void
78}
79
80; Normal path code
81
82; CHECK-LABEL: {{^}}two_invoke_gap:
83; CHECK: .seh_proc two_invoke_gap
84; CHECK: .seh_handler __C_specific_handler, @unwind, @except
85; CHECK: .Ltmp11:
86; CHECK: callq try_body
87; CHECK-NEXT: .Ltmp12:
88; CHECK: callq do_nothing_on_unwind
89; CHECK: .Ltmp13:
90; CHECK: callq try_body
91; CHECK-NEXT: .Ltmp14:
92; CHECK: retq
93
94; Landing pad code
95
96; CHECK: .Ltmp16:
97; CHECK: movl $1, %ecx
98; CHECK: callq use_selector
99
100; CHECK: .seh_handlerdata
101; CHECK-NEXT: .long 2
102; CHECK-NEXT: .long .Ltmp11@IMGREL
103; CHECK-NEXT: .long .Ltmp12@IMGREL+1
104; CHECK-NEXT: .long filt0@IMGREL
105; CHECK-NEXT: .long .Ltmp16@IMGREL
106; CHECK-NEXT: .long .Ltmp13@IMGREL
107; CHECK-NEXT: .long .Ltmp14@IMGREL+1
108; CHECK-NEXT: .long filt0@IMGREL
109; CHECK-NEXT: .long .Ltmp16@IMGREL
110; CHECK: .text
111; CHECK: .seh_endproc
112
113define void @two_invoke_nounwind_gap() {
114entry:
115  invoke void @try_body()
116          to label %again unwind label %lpad
117
118again:
119  call void @cannot_unwind()
120  invoke void @try_body()
121          to label %done unwind label %lpad
122
123done:
124  ret void
125
126lpad:
127  %vals = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
128          catch i8* bitcast (i32 (i8*, i8*)* @filt0 to i8*)
129  %sel = extractvalue { i8*, i32 } %vals, 1
130  call void @use_selector(i32 %sel)
131  ret void
132}
133
134; Normal path code
135
136; CHECK-LABEL: {{^}}two_invoke_nounwind_gap:
137; CHECK: .seh_proc two_invoke_nounwind_gap
138; CHECK: .seh_handler __C_specific_handler, @unwind, @except
139; CHECK: .Ltmp21:
140; CHECK: callq try_body
141; CHECK-NEXT: .Ltmp22:
142; CHECK: callq cannot_unwind
143; CHECK: .Ltmp23:
144; CHECK: callq try_body
145; CHECK-NEXT: .Ltmp24:
146; CHECK: retq
147
148; Landing pad code
149
150; CHECK: .Ltmp26:
151; CHECK: movl $1, %ecx
152; CHECK: callq use_selector
153
154; CHECK: .seh_handlerdata
155; CHECK-NEXT: .long 1
156; CHECK-NEXT: .long .Ltmp21@IMGREL
157; CHECK-NEXT: .long .Ltmp24@IMGREL+1
158; CHECK-NEXT: .long filt0@IMGREL
159; CHECK-NEXT: .long .Ltmp26@IMGREL
160; CHECK: .text
161; CHECK: .seh_endproc
162
163declare void @try_body()
164declare void @do_nothing_on_unwind()
165declare void @cannot_unwind() nounwind
166declare void @use_selector(i32)
167
168declare i32 @filt0(i8* %eh_info, i8* %rsp)
169declare i32 @filt1(i8* %eh_info, i8* %rsp)
170
171declare void @handler0()
172declare void @handler1()
173
174declare i32 @__C_specific_handler(...)
175declare i32 @llvm.eh.typeid.for(i8*) readnone nounwind
176