1; RUN: llc -mtriple=i686-pc-windows-msvc < %s | FileCheck %s
2
3declare void @may_throw_or_crash()
4declare i32 @_except_handler3(...)
5declare i32 @_except_handler4(...)
6declare i32 @__CxxFrameHandler3(...)
7declare void @llvm.eh.begincatch(i8*, i8*)
8declare void @llvm.eh.endcatch()
9declare i32 @llvm.eh.typeid.for(i8*)
10
11define internal i32 @catchall_filt() {
12  ret i32 1
13}
14
15define void @use_except_handler3() personality i32 (...)* @_except_handler3 {
16entry:
17  invoke void @may_throw_or_crash()
18      to label %cont unwind label %lpad
19cont:
20  ret void
21lpad:
22  %cs = catchswitch within none [label %catch] unwind to caller
23catch:
24  %p = catchpad within %cs [i8* bitcast (i32 ()* @catchall_filt to i8*)]
25  catchret from %p to label %cont
26}
27
28; CHECK-LABEL: _use_except_handler3:
29; CHECK: pushl %ebp
30; CHECK-NEXT: movl %esp, %ebp
31; CHECK-NEXT: pushl %ebx
32; CHECK-NEXT: pushl %edi
33; CHECK-NEXT: pushl %esi
34; CHECK-NEXT: subl ${{[0-9]+}}, %esp
35; CHECK-NEXT: movl %esp, -36(%ebp)
36; CHECK-NEXT: movl $-1, -16(%ebp)
37; CHECK-NEXT: movl $L__ehtable$use_except_handler3, -20(%ebp)
38; CHECK-NEXT: leal -28(%ebp), %[[node:[^ ,]*]]
39; CHECK-NEXT: movl $__except_handler3, -24(%ebp)
40; CHECK-NEXT: movl %fs:0, %[[next:[^ ,]*]]
41; CHECK-NEXT: movl %[[next]], -28(%ebp)
42; CHECK-NEXT: movl %[[node]], %fs:0
43; CHECK-NEXT: movl $0, -16(%ebp)
44; CHECK-NEXT: calll _may_throw_or_crash
45
46; CHECK: movl -28(%ebp), %[[next:[^ ,]*]]
47; CHECK-NEXT: movl %[[next]], %fs:0
48; CHECK: retl
49; CHECK-NEXT: LBB1_2: # %catch{{$}}
50
51; CHECK: .section .xdata,"dr"
52; CHECK-LABEL: L__ehtable$use_except_handler3:
53; CHECK-NEXT:  .long   -1
54; CHECK-NEXT:  .long   _catchall_filt
55; CHECK-NEXT:  .long   LBB1_2
56
57define void @use_except_handler4() personality i32 (...)* @_except_handler4 {
58entry:
59  invoke void @may_throw_or_crash()
60      to label %cont unwind label %lpad
61cont:
62  ret void
63lpad:
64  %cs = catchswitch within none [label %catch] unwind to caller
65catch:
66  %p = catchpad within %cs [i8* bitcast (i32 ()* @catchall_filt to i8*)]
67  catchret from %p to label %cont
68}
69
70; CHECK-LABEL: _use_except_handler4:
71; CHECK: pushl %ebp
72; CHECK-NEXT: movl %esp, %ebp
73; CHECK-NEXT: pushl %ebx
74; CHECK-NEXT: pushl %edi
75; CHECK-NEXT: pushl %esi
76; CHECK-NEXT: subl ${{[0-9]+}}, %esp
77; CHECK-NEXT: movl %ebp, %eax
78; CHECK-NEXT: movl %esp, -36(%ebp)
79; CHECK-NEXT: movl $-2, -16(%ebp)
80; CHECK-NEXT: movl $L__ehtable$use_except_handler4, %[[lsda:[^ ,]*]]
81; CHECK-NEXT: movl ___security_cookie, %[[seccookie:[^ ,]*]]
82; CHECK-NEXT: xorl %[[seccookie]], %[[lsda]]
83; CHECK-NEXT: movl %[[lsda]], -20(%ebp)
84; CHECK-NEXT: xorl %[[seccookie]], %[[tmp1:[^ ,]*]]
85; CHECK-NEXT: movl %[[tmp1]], -40(%ebp)
86; CHECK-NEXT: leal -28(%ebp), %[[node:[^ ,]*]]
87; CHECK-NEXT: movl $__except_handler4, -24(%ebp)
88; CHECK-NEXT: movl %fs:0, %[[next:[^ ,]*]]
89; CHECK-NEXT: movl %[[next]], -28(%ebp)
90; CHECK-NEXT: movl %[[node]], %fs:0
91; CHECK-NEXT: movl $0, -16(%ebp)
92; CHECK-NEXT: calll _may_throw_or_crash
93
94; CHECK: movl -28(%ebp), %[[next:[^ ,]*]]
95; CHECK-NEXT: movl %[[next]], %fs:0
96; CHECK-NEXT: addl $28, %esp
97; CHECK-NEXT: popl %esi
98; CHECK-NEXT: popl %edi
99; CHECK-NEXT: popl %ebx
100; CHECK-NEXT: popl %ebp
101; CHECK-NEXT: retl
102; CHECK-NEXT: LBB2_2: # %catch{{$}}
103
104; CHECK: .section .xdata,"dr"
105; CHECK-LABEL: L__ehtable$use_except_handler4:
106; CHECK-NEXT:  .long   -2
107; CHECK-NEXT:  .long   0
108; CHECK-NEXT:  .long   -40
109; CHECK-NEXT:  .long   0
110; CHECK-NEXT:  .long   -2
111; CHECK-NEXT:  .long   _catchall_filt
112; CHECK-NEXT:  .long   LBB2_2
113
114define void @use_except_handler4_ssp() sspstrong personality i32 (...)* @_except_handler4 {
115entry:
116  invoke void @may_throw_or_crash()
117      to label %cont unwind label %lpad
118cont:
119  ret void
120lpad:
121  %cs = catchswitch within none [label %catch] unwind to caller
122catch:
123  %p = catchpad within %cs [i8* bitcast (i32 ()* @catchall_filt to i8*)]
124  catchret from %p to label %cont
125}
126
127; CHECK-LABEL: _use_except_handler4_ssp:
128; CHECK: pushl %ebp
129; CHECK-NEXT: movl %esp, %ebp
130; CHECK-NEXT: pushl %ebx
131; CHECK-NEXT: pushl %edi
132; CHECK-NEXT: pushl %esi
133; CHECK-NEXT: subl ${{[0-9]+}}, %esp
134; CHECK-NEXT: movl %ebp, %[[ehguard:[^ ,]*]]
135; CHECK-NEXT: movl %esp, -36(%ebp)
136; CHECK-NEXT: movl $-2, -16(%ebp)
137; CHECK-NEXT: movl $L__ehtable$use_except_handler4_ssp, %[[lsda:[^ ,]*]]
138; CHECK-NEXT: movl ___security_cookie, %[[seccookie:[^ ,]*]]
139; CHECK-NEXT: xorl %[[seccookie]], %[[lsda]]
140; CHECK-NEXT: movl %[[lsda]], -20(%ebp)
141; CHECK-NEXT: xorl %[[seccookie]], %[[ehguard]]
142; CHECK-NEXT: movl %[[ehguard]], -40(%ebp)
143; CHECK-NEXT: leal -28(%ebp), %[[node:[^ ,]*]]
144; CHECK-NEXT: movl $__except_handler4, -24(%ebp)
145; CHECK-NEXT: movl %fs:0, %[[next:[^ ,]*]]
146; CHECK-NEXT: movl %[[next]], -28(%ebp)
147; CHECK-NEXT: movl %[[node]], %fs:0
148; CHECK-NEXT: movl $0, -16(%ebp)
149; CHECK-NEXT: calll _may_throw_or_crash
150; CHECK: movl -28(%ebp), %[[next:[^ ,]*]]
151; CHECK-NEXT: movl %[[next]], %fs:0
152; CHECK: retl
153; CHECK-NEXT: [[catch:[^ ,]*]]: # %catch{{$}}
154
155
156
157; CHECK: .section .xdata,"dr"
158; CHECK-LABEL: L__ehtable$use_except_handler4_ssp:
159; CHECK-NEXT:  .long   -2
160; CHECK-NEXT:  .long   0
161; CHECK-NEXT:  .long   -40
162; CHECK-NEXT:  .long   0
163; CHECK-NEXT:  .long   -2
164; CHECK-NEXT:  .long   _catchall_filt
165; CHECK-NEXT:  .long   [[catch]]
166
167define void @use_CxxFrameHandler3() personality i32 (...)* @__CxxFrameHandler3 {
168  invoke void @may_throw_or_crash()
169      to label %cont unwind label %catchall
170cont:
171  ret void
172
173catchall:
174  %cs = catchswitch within none [label %catch] unwind to caller
175catch:
176  %p = catchpad within %cs [i8* null, i32 64, i8* null]
177  catchret from %p to label %cont
178}
179
180; CHECK-LABEL: _use_CxxFrameHandler3:
181; CHECK: pushl %ebp
182; CHECK-NEXT: movl %esp, %ebp
183; CHECK-NEXT: pushl %ebx
184; CHECK-NEXT: pushl %edi
185; CHECK-NEXT: pushl %esi
186; CHECK-NEXT: subl ${{[0-9]+}}, %esp
187; CHECK-NEXT: movl %esp, -28(%ebp)
188; CHECK-NEXT: movl $-1, -16(%ebp)
189; CHECK-NEXT: leal -24(%ebp), %[[node:[^ ,]*]]
190; CHECK-NEXT: movl $___ehhandler$use_CxxFrameHandler3, -20(%ebp)
191; CHECK-NEXT: movl %fs:0, %[[next:[^ ,]*]]
192; CHECK-NEXT: movl %[[next]], -24(%ebp)
193; CHECK-NEXT: movl %[[node]], %fs:0
194; CHECK-NEXT: movl $0, -16(%ebp)
195; CHECK-NEXT: calll _may_throw_or_crash
196; CHECK: movl -24(%ebp), %[[next:[^ ,]*]]
197; CHECK-NEXT: movl %[[next]], %fs:0
198; CHECK: retl
199
200; CHECK: .section .xdata,"dr"
201; CHECK-NEXT: .p2align 2
202; CHECK-LABEL: L__ehtable$use_CxxFrameHandler3:
203; CHECK-NEXT:  .long   429065506
204; CHECK-NEXT:  .long   2
205; CHECK-NEXT:  .long   ($stateUnwindMap$use_CxxFrameHandler3)
206; CHECK-NEXT:  .long   1
207; CHECK-NEXT:  .long   ($tryMap$use_CxxFrameHandler3)
208; CHECK-NEXT:  .long   0
209; CHECK-NEXT:  .long   0
210; CHECK-NEXT:  .long   0
211; CHECK-NEXT:  .long   1
212
213; CHECK-LABEL: ___ehhandler$use_CxxFrameHandler3:
214; CHECK: movl $L__ehtable$use_CxxFrameHandler3, %eax
215; CHECK-NEXT: jmp  ___CxxFrameHandler3 # TAILCALL
216
217; CHECK: .safeseh __except_handler3
218; CHECK-NEXT: .safeseh __except_handler4
219; CHECK-NEXT: .safeseh ___ehhandler$use_CxxFrameHandler3
220