blob: dd14f2df6899eb4aa0559eca9bc8451ec6ae8714 [file] [log] [blame]
Reid Kleckner94b704c2015-09-09 21:10:03 +00001; RUN: llc < %s | FileCheck %s
2
3target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
4target triple = "i686-pc-windows-msvc"
5
6define void @try_except() #0 personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) {
7entry:
8 %__exception_code = alloca i32, align 4
9 call void (...) @llvm.localescape(i32* %__exception_code)
10 invoke void @f(i32 1) #3
11 to label %invoke.cont unwind label %catch.dispatch
12
13catch.dispatch: ; preds = %entry
14 %0 = catchpad [i8* bitcast (i32 ()* @try_except_filter_catchall to i8*)] to label %__except.ret unwind label %catchendblock
15
16__except.ret: ; preds = %catch.dispatch
17 catchret %0 to label %__except
18
19__except: ; preds = %__except.ret
20 call void @f(i32 2)
21 br label %__try.cont
22
23__try.cont: ; preds = %__except, %invoke.cont
24 call void @f(i32 3)
25 ret void
26
27catchendblock: ; preds = %catch.dispatch
28 catchendpad unwind to caller
29
30invoke.cont: ; preds = %entry
31 br label %__try.cont
32}
33
34; CHECK-LABEL: _try_except:
35; Store state #0
36; CHECK: movl $0, -[[state:[0-9]+]](%ebp)
37; CHECK: movl $1, (%esp)
38; CHECK: calll _f
39; CHECK: movl $-1, -[[state]](%ebp)
40; CHECK: movl $3, (%esp)
41; CHECK: calll _f
42; CHECK: retl
43
44; __except
45; CHECK: movl $-1, -[[state]](%ebp)
46; CHECK: movl $2, (%esp)
47; CHECK: calll _f
48
49; CHECK: .section .xdata,"dr"
50; CHECK: L__ehtable$try_except:
51; CHECK: .long -1
52; CHECK: .long _try_except_filter_catchall
53; CHECK: .long LBB0_1
54
55define internal i32 @try_except_filter_catchall() #0 {
56entry:
57 %0 = call i8* @llvm.frameaddress(i32 1)
58 %1 = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (void ()* @try_except to i8*), i8* %0)
59 %2 = call i8* @llvm.localrecover(i8* bitcast (void ()* @try_except to i8*), i8* %1, i32 0)
60 %__exception_code = bitcast i8* %2 to i32*
61 %3 = getelementptr inbounds i8, i8* %0, i32 -20
62 %4 = bitcast i8* %3 to i8**
63 %5 = load i8*, i8** %4, align 4
64 %6 = bitcast i8* %5 to { i32*, i8* }*
65 %7 = getelementptr inbounds { i32*, i8* }, { i32*, i8* }* %6, i32 0, i32 0
66 %8 = load i32*, i32** %7, align 4
67 %9 = load i32, i32* %8, align 4
68 store i32 %9, i32* %__exception_code, align 4
69 ret i32 1
70}
71
72define void @nested_exceptions() #0 personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) {
73entry:
74 %__exception_code = alloca i32, align 4
75 call void (...) @llvm.localescape(i32* %__exception_code)
76 invoke void @crash() #3
77 to label %__try.cont unwind label %catch.dispatch
78
79catch.dispatch: ; preds = %entry
80 %0 = catchpad [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] to label %__except.ret unwind label %catchendblock
81
82__except.ret: ; preds = %catch.dispatch
83 catchret %0 to label %__try.cont
84
85__try.cont: ; preds = %entry, %__except.ret
86 invoke void @crash() #3
87 to label %__try.cont.9 unwind label %catch.dispatch.5
88
89catch.dispatch.5: ; preds = %__try.cont
90 %1 = catchpad [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] to label %__except.ret.7 unwind label %catchendblock.6
91
92__except.ret.7: ; preds = %catch.dispatch.5
93 catchret %1 to label %__try.cont.9
94
95__try.cont.9: ; preds = %__try.cont, %__except.ret.7
96 invoke void @crash() #3
97 to label %__try.cont.15 unwind label %catch.dispatch.11
98
99catch.dispatch.11: ; preds = %catchendblock, %catchendblock.6, %__try.cont.9
100 %2 = catchpad [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] to label %__except.ret.13 unwind label %catchendblock.12
101
102__except.ret.13: ; preds = %catch.dispatch.11
103 catchret %2 to label %__try.cont.15
104
105__try.cont.15: ; preds = %__try.cont.9, %__except.ret.13
106 invoke void @crash() #3
107 to label %__try.cont.35 unwind label %catch.dispatch.17
108
109catch.dispatch.17: ; preds = %catchendblock.12, %__try.cont.15
110 %3 = catchpad [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] to label %__except.ret.19 unwind label %catchendblock.18
111
112__except.ret.19: ; preds = %catch.dispatch.17
113 catchret %3 to label %__except.20
114
115__except.20: ; preds = %__except.ret.19
116 invoke void @crash() #3
117 to label %__try.cont.27 unwind label %catch.dispatch.23
118
119catch.dispatch.23: ; preds = %__except.20
120 %4 = catchpad [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] to label %__except.ret.25 unwind label %catchendblock.24
121
122__except.ret.25: ; preds = %catch.dispatch.23
123 catchret %4 to label %__try.cont.27
124
125__try.cont.27: ; preds = %__except.20, %__except.ret.25
126 invoke void @crash() #3
127 to label %__try.cont.35 unwind label %catch.dispatch.30
128
129catch.dispatch.30: ; preds = %__try.cont.27
130 %5 = catchpad [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] to label %__except.ret.32 unwind label %catchendblock.31
131
132__except.ret.32: ; preds = %catch.dispatch.30
133 catchret %5 to label %__try.cont.35
134
135__try.cont.35: ; preds = %__try.cont.15, %__try.cont.27, %__except.ret.32
136 ret void
137
138catchendblock.31: ; preds = %catch.dispatch.30
139 catchendpad unwind to caller
140
141catchendblock.24: ; preds = %catch.dispatch.23
142 catchendpad unwind to caller
143
144catchendblock.18: ; preds = %catch.dispatch.17
145 catchendpad unwind to caller
146
147catchendblock.12: ; preds = %catch.dispatch.11
148 catchendpad unwind label %catch.dispatch.17
149
150catchendblock.6: ; preds = %catch.dispatch.5
151 catchendpad unwind label %catch.dispatch.11
152
153catchendblock: ; preds = %catch.dispatch
154 catchendpad unwind label %catch.dispatch.11
155}
156
157; This table is equivalent to the one produced by MSVC, even if it isn't in
158; quite the same order.
159
160; CHECK-LABEL: _nested_exceptions:
161; CHECK: L__ehtable$nested_exceptions:
162; CHECK: .long -1
163; CHECK: .long _nested_exceptions_filter_catchall
164; CHECK: .long LBB
165; CHECK: .long -1
166; CHECK: .long _nested_exceptions_filter_catchall
167; CHECK: .long LBB
168; CHECK: .long -1
169; CHECK: .long _nested_exceptions_filter_catchall
170; CHECK: .long LBB
171; CHECK: .long 2
172; CHECK: .long _nested_exceptions_filter_catchall
173; CHECK: .long LBB
174; CHECK: .long 3
175; CHECK: .long _nested_exceptions_filter_catchall
176; CHECK: .long LBB
177; CHECK: .long 3
178; CHECK: .long _nested_exceptions_filter_catchall
179; CHECK: .long LBB
180
181declare void @crash() #0
182
183define internal i32 @nested_exceptions_filter_catchall() #0 {
184entry:
185 %0 = call i8* @llvm.frameaddress(i32 1)
186 %1 = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (void ()* @nested_exceptions to i8*), i8* %0)
187 %2 = call i8* @llvm.localrecover(i8* bitcast (void ()* @nested_exceptions to i8*), i8* %1, i32 0)
188 %__exception_code3 = bitcast i8* %2 to i32*
189 %3 = getelementptr inbounds i8, i8* %0, i32 -20
190 %4 = bitcast i8* %3 to i8**
191 %5 = load i8*, i8** %4, align 4
192 %6 = bitcast i8* %5 to { i32*, i8* }*
193 %7 = getelementptr inbounds { i32*, i8* }, { i32*, i8* }* %6, i32 0, i32 0
194 %8 = load i32*, i32** %7, align 4
195 %9 = load i32, i32* %8, align 4
196 store i32 %9, i32* %__exception_code3, align 4
197 ret i32 1
198}
199
David Majnemer7735a6d2015-10-06 23:31:59 +0000200define void @code_in_catchpad() #0 personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) {
201entry:
202 invoke void @f(i32 1) #3
203 to label %__except unwind label %catch.dispatch
204
205catch.dispatch: ; preds = %entry
206 %0 = catchpad [i8* bitcast (i32 ()* @try_except_filter_catchall to i8*)] to label %__except.ret unwind label %catchendblock
207
208__except.ret: ; preds = %catch.dispatch
209 call void @f(i32 2)
210 catchret %0 to label %__except
211
212__except:
213 ret void
214
215catchendblock: ; preds = %catch.dispatch
216 catchendpad unwind to caller
217}
218
219; CHECK-LABEL: _code_in_catchpad:
220; CHECK: # %catch.dispatch
221; CHECK-NEXT: movl -24(%ebp), %esp
222; CHECK-NEXT: addl $12, %ebp
223; CHECK: # %__except.ret
224; CHECK-NEXT: movl $-1, -16(%ebp)
225; CHECK-NEXT: movl $2, (%esp)
226; CHECK-NEXT: calll _f
227
228
Reid Kleckner94b704c2015-09-09 21:10:03 +0000229; Function Attrs: nounwind readnone
230declare i8* @llvm.frameaddress(i32) #1
231
232; Function Attrs: nounwind readnone
233declare i8* @llvm.x86.seh.recoverfp(i8*, i8*) #1
234
235; Function Attrs: nounwind readnone
236declare i8* @llvm.localrecover(i8*, i8*, i32) #1
237
238declare void @f(i32) #0
239
240declare i32 @_except_handler3(...)
241
242; Function Attrs: nounwind
243declare void @llvm.localescape(...) #2
244
245attributes #0 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
246attributes #1 = { nounwind readnone }
247attributes #2 = { nounwind }
248attributes #3 = { noinline }