xref: /aosp_15_r20/external/llvm/test/CodeGen/X86/win32-seh-catchpad.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
4*9880d681SAndroid Build Coastguard Workertarget triple = "i686-pc-windows-msvc"
5*9880d681SAndroid Build Coastguard Worker
6*9880d681SAndroid Build Coastguard Workerdefine void @try_except() #0 personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) {
7*9880d681SAndroid Build Coastguard Workerentry:
8*9880d681SAndroid Build Coastguard Worker  %__exception_code = alloca i32, align 4
9*9880d681SAndroid Build Coastguard Worker  call void (...) @llvm.localescape(i32* %__exception_code)
10*9880d681SAndroid Build Coastguard Worker  invoke void @f(i32 1) #3
11*9880d681SAndroid Build Coastguard Worker          to label %invoke.cont unwind label %catch.dispatch
12*9880d681SAndroid Build Coastguard Worker
13*9880d681SAndroid Build Coastguard Workercatch.dispatch:                                   ; preds = %entry
14*9880d681SAndroid Build Coastguard Worker  %cs1 = catchswitch within none [label %__except.ret] unwind to caller
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker__except.ret:                                     ; preds = %catch.dispatch
17*9880d681SAndroid Build Coastguard Worker  %0 = catchpad within %cs1 [i8* bitcast (i32 ()* @try_except_filter_catchall to i8*)]
18*9880d681SAndroid Build Coastguard Worker  catchret from %0 to label %__except
19*9880d681SAndroid Build Coastguard Worker
20*9880d681SAndroid Build Coastguard Worker__except:                                         ; preds = %__except.ret
21*9880d681SAndroid Build Coastguard Worker  call void @f(i32 2)
22*9880d681SAndroid Build Coastguard Worker  br label %__try.cont
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Worker__try.cont:                                       ; preds = %__except, %invoke.cont
25*9880d681SAndroid Build Coastguard Worker  call void @f(i32 3)
26*9880d681SAndroid Build Coastguard Worker  ret void
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Workerinvoke.cont:                                      ; preds = %entry
29*9880d681SAndroid Build Coastguard Worker  br label %__try.cont
30*9880d681SAndroid Build Coastguard Worker}
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: _try_except:
33*9880d681SAndroid Build Coastguard Worker;     Store state #0
34*9880d681SAndroid Build Coastguard Worker; CHECK: movl $0, -[[state:[0-9]+]](%ebp)
35*9880d681SAndroid Build Coastguard Worker; CHECK: pushl $1
36*9880d681SAndroid Build Coastguard Worker; CHECK: calll _f
37*9880d681SAndroid Build Coastguard Worker; CHECK: movl $-1, -[[state]](%ebp)
38*9880d681SAndroid Build Coastguard Worker; CHECK: pushl $3
39*9880d681SAndroid Build Coastguard Worker; CHECK: calll _f
40*9880d681SAndroid Build Coastguard Worker; CHECK: retl
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Worker;   __except
43*9880d681SAndroid Build Coastguard Worker; CHECK: movl $-1, -[[state]](%ebp)
44*9880d681SAndroid Build Coastguard Worker; CHECK: pushl $2
45*9880d681SAndroid Build Coastguard Worker; CHECK: calll _f
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Worker; CHECK: .section        .xdata,"dr"
48*9880d681SAndroid Build Coastguard Worker; CHECK: L__ehtable$try_except:
49*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   -1                          # ToState
50*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   _try_except_filter_catchall # Filter
51*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   LBB0_1
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Workerdefine internal i32 @try_except_filter_catchall() #0 {
54*9880d681SAndroid Build Coastguard Workerentry:
55*9880d681SAndroid Build Coastguard Worker  %0 = call i8* @llvm.frameaddress(i32 1)
56*9880d681SAndroid Build Coastguard Worker  %1 = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (void ()* @try_except to i8*), i8* %0)
57*9880d681SAndroid Build Coastguard Worker  %2 = call i8* @llvm.localrecover(i8* bitcast (void ()* @try_except to i8*), i8* %1, i32 0)
58*9880d681SAndroid Build Coastguard Worker  %__exception_code = bitcast i8* %2 to i32*
59*9880d681SAndroid Build Coastguard Worker  %3 = getelementptr inbounds i8, i8* %0, i32 -20
60*9880d681SAndroid Build Coastguard Worker  %4 = bitcast i8* %3 to i8**
61*9880d681SAndroid Build Coastguard Worker  %5 = load i8*, i8** %4, align 4
62*9880d681SAndroid Build Coastguard Worker  %6 = bitcast i8* %5 to { i32*, i8* }*
63*9880d681SAndroid Build Coastguard Worker  %7 = getelementptr inbounds { i32*, i8* }, { i32*, i8* }* %6, i32 0, i32 0
64*9880d681SAndroid Build Coastguard Worker  %8 = load i32*, i32** %7, align 4
65*9880d681SAndroid Build Coastguard Worker  %9 = load i32, i32* %8, align 4
66*9880d681SAndroid Build Coastguard Worker  store i32 %9, i32* %__exception_code, align 4
67*9880d681SAndroid Build Coastguard Worker  ret i32 1
68*9880d681SAndroid Build Coastguard Worker}
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Workerdefine void @nested_exceptions() #0 personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) {
71*9880d681SAndroid Build Coastguard Workerentry:
72*9880d681SAndroid Build Coastguard Worker  %__exception_code = alloca i32, align 4
73*9880d681SAndroid Build Coastguard Worker  call void (...) @llvm.localescape(i32* %__exception_code)
74*9880d681SAndroid Build Coastguard Worker  invoke void @crash() #3
75*9880d681SAndroid Build Coastguard Worker          to label %__try.cont unwind label %catch.dispatch
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Workercatch.dispatch:                                   ; preds = %entry
78*9880d681SAndroid Build Coastguard Worker  %cs1 = catchswitch within none [label %__except.ret] unwind label %catch.dispatch.11
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Worker__except.ret:                                     ; preds = %catch.dispatch
81*9880d681SAndroid Build Coastguard Worker  %0 = catchpad within %cs1 [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)]
82*9880d681SAndroid Build Coastguard Worker  catchret from %0 to label %__try.cont
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Worker__try.cont:                                       ; preds = %entry, %__except.ret
85*9880d681SAndroid Build Coastguard Worker  invoke void @crash() #3
86*9880d681SAndroid Build Coastguard Worker          to label %__try.cont.9 unwind label %catch.dispatch.5
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Workercatch.dispatch.5:                                 ; preds = %__try.cont
89*9880d681SAndroid Build Coastguard Worker  %cs2 = catchswitch within none [label %__except.ret.7] unwind label %catch.dispatch.11
90*9880d681SAndroid Build Coastguard Worker
91*9880d681SAndroid Build Coastguard Worker__except.ret.7:                                   ; preds = %catch.dispatch.5
92*9880d681SAndroid Build Coastguard Worker  %1 = catchpad within %cs2 [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)]
93*9880d681SAndroid Build Coastguard Worker  catchret from %1 to label %__try.cont.9
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Worker__try.cont.9:                                     ; preds = %__try.cont, %__except.ret.7
96*9880d681SAndroid Build Coastguard Worker  invoke void @crash() #3
97*9880d681SAndroid Build Coastguard Worker          to label %__try.cont.15 unwind label %catch.dispatch.11
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Workercatch.dispatch.11:                                ; preds = %catchendblock, %catchendblock.6, %__try.cont.9
100*9880d681SAndroid Build Coastguard Worker  %cs3 = catchswitch within none [label %__except.ret.13] unwind label %catch.dispatch.17
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker__except.ret.13:                                  ; preds = %catch.dispatch.11
103*9880d681SAndroid Build Coastguard Worker  %2 = catchpad within %cs3 [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)]
104*9880d681SAndroid Build Coastguard Worker  catchret from %2 to label %__try.cont.15
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Worker__try.cont.15:                                    ; preds = %__try.cont.9, %__except.ret.13
107*9880d681SAndroid Build Coastguard Worker  invoke void @crash() #3
108*9880d681SAndroid Build Coastguard Worker          to label %__try.cont.35 unwind label %catch.dispatch.17
109*9880d681SAndroid Build Coastguard Worker
110*9880d681SAndroid Build Coastguard Workercatch.dispatch.17:                                ; preds = %catchendblock.12, %__try.cont.15
111*9880d681SAndroid Build Coastguard Worker  %cs4 = catchswitch within none [label %__except.ret.19] unwind to caller
112*9880d681SAndroid Build Coastguard Worker
113*9880d681SAndroid Build Coastguard Worker__except.ret.19:                                  ; preds = %catch.dispatch.17
114*9880d681SAndroid Build Coastguard Worker  %3 = catchpad within %cs4 [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)]
115*9880d681SAndroid Build Coastguard Worker  catchret from %3 to label %__except.20
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker__except.20:                                      ; preds = %__except.ret.19
118*9880d681SAndroid Build Coastguard Worker  invoke void @crash() #3
119*9880d681SAndroid Build Coastguard Worker          to label %__try.cont.27 unwind label %catch.dispatch.23
120*9880d681SAndroid Build Coastguard Worker
121*9880d681SAndroid Build Coastguard Workercatch.dispatch.23:                                ; preds = %__except.20
122*9880d681SAndroid Build Coastguard Worker  %cs5 = catchswitch within none [label %__except.ret.25] unwind to caller
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Worker__except.ret.25:                                  ; preds = %catch.dispatch.23
125*9880d681SAndroid Build Coastguard Worker  %4 = catchpad within %cs5 [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)]
126*9880d681SAndroid Build Coastguard Worker  catchret from %4 to label %__try.cont.27
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Worker__try.cont.27:                                    ; preds = %__except.20, %__except.ret.25
129*9880d681SAndroid Build Coastguard Worker  invoke void @crash() #3
130*9880d681SAndroid Build Coastguard Worker          to label %__try.cont.35 unwind label %catch.dispatch.30
131*9880d681SAndroid Build Coastguard Worker
132*9880d681SAndroid Build Coastguard Workercatch.dispatch.30:                                ; preds = %__try.cont.27
133*9880d681SAndroid Build Coastguard Worker  %cs6 = catchswitch within none [label %__except.ret.32] unwind to caller
134*9880d681SAndroid Build Coastguard Worker
135*9880d681SAndroid Build Coastguard Worker__except.ret.32:                                  ; preds = %catch.dispatch.30
136*9880d681SAndroid Build Coastguard Worker  %5 = catchpad within %cs6 [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)]
137*9880d681SAndroid Build Coastguard Worker  catchret from %5 to label %__try.cont.35
138*9880d681SAndroid Build Coastguard Worker
139*9880d681SAndroid Build Coastguard Worker__try.cont.35:                                    ; preds = %__try.cont.15, %__try.cont.27, %__except.ret.32
140*9880d681SAndroid Build Coastguard Worker  ret void
141*9880d681SAndroid Build Coastguard Worker}
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker; This table is equivalent to the one produced by MSVC, even if it isn't in
144*9880d681SAndroid Build Coastguard Worker; quite the same order.
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: _nested_exceptions:
147*9880d681SAndroid Build Coastguard Worker; CHECK: L__ehtable$nested_exceptions:
148*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   -1
149*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   _nested_exceptions_filter_catchall
150*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   LBB
151*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   0
152*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   _nested_exceptions_filter_catchall
153*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   LBB
154*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   1
155*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   _nested_exceptions_filter_catchall
156*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   LBB
157*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   1
158*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   _nested_exceptions_filter_catchall
159*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   LBB
160*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   -1
161*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   _nested_exceptions_filter_catchall
162*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   LBB
163*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   -1
164*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   _nested_exceptions_filter_catchall
165*9880d681SAndroid Build Coastguard Worker; CHECK:         .long   LBB
166*9880d681SAndroid Build Coastguard Worker
167*9880d681SAndroid Build Coastguard Workerdeclare void @crash() #0
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Workerdefine internal i32 @nested_exceptions_filter_catchall() #0 {
170*9880d681SAndroid Build Coastguard Workerentry:
171*9880d681SAndroid Build Coastguard Worker  %0 = call i8* @llvm.frameaddress(i32 1)
172*9880d681SAndroid Build Coastguard Worker  %1 = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (void ()* @nested_exceptions to i8*), i8* %0)
173*9880d681SAndroid Build Coastguard Worker  %2 = call i8* @llvm.localrecover(i8* bitcast (void ()* @nested_exceptions to i8*), i8* %1, i32 0)
174*9880d681SAndroid Build Coastguard Worker  %__exception_code3 = bitcast i8* %2 to i32*
175*9880d681SAndroid Build Coastguard Worker  %3 = getelementptr inbounds i8, i8* %0, i32 -20
176*9880d681SAndroid Build Coastguard Worker  %4 = bitcast i8* %3 to i8**
177*9880d681SAndroid Build Coastguard Worker  %5 = load i8*, i8** %4, align 4
178*9880d681SAndroid Build Coastguard Worker  %6 = bitcast i8* %5 to { i32*, i8* }*
179*9880d681SAndroid Build Coastguard Worker  %7 = getelementptr inbounds { i32*, i8* }, { i32*, i8* }* %6, i32 0, i32 0
180*9880d681SAndroid Build Coastguard Worker  %8 = load i32*, i32** %7, align 4
181*9880d681SAndroid Build Coastguard Worker  %9 = load i32, i32* %8, align 4
182*9880d681SAndroid Build Coastguard Worker  store i32 %9, i32* %__exception_code3, align 4
183*9880d681SAndroid Build Coastguard Worker  ret i32 1
184*9880d681SAndroid Build Coastguard Worker}
185*9880d681SAndroid Build Coastguard Worker
186*9880d681SAndroid Build Coastguard Workerdefine void @code_in_catchpad() #0 personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) {
187*9880d681SAndroid Build Coastguard Workerentry:
188*9880d681SAndroid Build Coastguard Worker  invoke void @f(i32 1) #3
189*9880d681SAndroid Build Coastguard Worker          to label %__except unwind label %catch.dispatch
190*9880d681SAndroid Build Coastguard Worker
191*9880d681SAndroid Build Coastguard Workercatch.dispatch:                                   ; preds = %entry
192*9880d681SAndroid Build Coastguard Worker  %cs1 = catchswitch within none [label %__except.ret] unwind to caller
193*9880d681SAndroid Build Coastguard Worker
194*9880d681SAndroid Build Coastguard Worker__except.ret:                                     ; preds = %catch.dispatch
195*9880d681SAndroid Build Coastguard Worker  %0 = catchpad within %cs1 [i8* bitcast (i32 ()* @try_except_filter_catchall to i8*)]
196*9880d681SAndroid Build Coastguard Worker  call void @f(i32 2) [ "funclet"(token %0) ]
197*9880d681SAndroid Build Coastguard Worker  catchret from %0 to label %__except
198*9880d681SAndroid Build Coastguard Worker
199*9880d681SAndroid Build Coastguard Worker__except:
200*9880d681SAndroid Build Coastguard Worker  ret void
201*9880d681SAndroid Build Coastguard Worker}
202*9880d681SAndroid Build Coastguard Worker
203*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: _code_in_catchpad:
204*9880d681SAndroid Build Coastguard Worker; CHECK: # %__except.ret
205*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         movl    -24(%ebp), %esp
206*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         addl    $12, %ebp
207*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         movl    $-1, -16(%ebp)
208*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         pushl   $2
209*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         calll   _f
210*9880d681SAndroid Build Coastguard Worker
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind readnone
213*9880d681SAndroid Build Coastguard Workerdeclare i8* @llvm.frameaddress(i32) #1
214*9880d681SAndroid Build Coastguard Worker
215*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind readnone
216*9880d681SAndroid Build Coastguard Workerdeclare i8* @llvm.x86.seh.recoverfp(i8*, i8*) #1
217*9880d681SAndroid Build Coastguard Worker
218*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind readnone
219*9880d681SAndroid Build Coastguard Workerdeclare i8* @llvm.localrecover(i8*, i8*, i32) #1
220*9880d681SAndroid Build Coastguard Worker
221*9880d681SAndroid Build Coastguard Workerdeclare void @f(i32) #0
222*9880d681SAndroid Build Coastguard Worker
223*9880d681SAndroid Build Coastguard Workerdeclare i32 @_except_handler3(...)
224*9880d681SAndroid Build Coastguard Worker
225*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind
226*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.localescape(...) #2
227*9880d681SAndroid Build Coastguard Worker
228*9880d681SAndroid Build Coastguard Workerattributes #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" }
229*9880d681SAndroid Build Coastguard Workerattributes #1 = { nounwind readnone }
230*9880d681SAndroid Build Coastguard Workerattributes #2 = { nounwind }
231*9880d681SAndroid Build Coastguard Workerattributes #3 = { noinline }
232