Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / X86 / win32-seh-catchpad.ll
blobfa7335cb7bf6445699a5615a5efbff6a26457424
1 ; RUN: llc < %s | FileCheck %s
3 target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
4 target triple = "i686-pc-windows-msvc"
6 define void @try_except() #0 personality ptr @_except_handler3 {
7 entry:
8   %__exception_code = alloca i32, align 4
9   call void (...) @llvm.localescape(ptr %__exception_code)
10   invoke void @f(i32 1) #3
11           to label %invoke.cont unwind label %catch.dispatch
13 catch.dispatch:                                   ; preds = %entry
14   %cs1 = catchswitch within none [label %__except.ret] unwind to caller
16 __except.ret:                                     ; preds = %catch.dispatch
17   %0 = catchpad within %cs1 [ptr @try_except_filter_catchall]
18   catchret from %0 to label %__except
20 __except:                                         ; preds = %__except.ret
21   call void @f(i32 2)
22   br label %__try.cont
24 __try.cont:                                       ; preds = %__except, %invoke.cont
25   call void @f(i32 3)
26   ret void
28 invoke.cont:                                      ; preds = %entry
29   br label %__try.cont
32 ; CHECK-LABEL: _try_except:
33 ;     Store state #0
34 ; CHECK: movl $0, -[[state:[0-9]+]](%ebp)
35 ; CHECK: pushl $1
36 ; CHECK: calll _f
37 ; CHECK: movl $-1, -[[state]](%ebp)
38 ; CHECK: pushl $3
39 ; CHECK: calll _f
40 ; CHECK: retl
42 ;   __except
43 ; CHECK: movl $-1, -[[state]](%ebp)
44 ; CHECK: pushl $2
45 ; CHECK: calll _f
47 ; CHECK: .section        .xdata,"dr"
48 ; CHECK: L__ehtable$try_except:
49 ; CHECK:         .long   -1                          # ToState
50 ; CHECK:         .long   _try_except_filter_catchall # Filter
51 ; CHECK:         .long   LBB0_1
53 define internal i32 @try_except_filter_catchall() #0 {
54 entry:
55   %0 = call ptr @llvm.frameaddress(i32 1)
56   %1 = call ptr @llvm.eh.recoverfp(ptr @try_except, ptr %0)
57   %2 = call ptr @llvm.localrecover(ptr @try_except, ptr %1, i32 0)
58   %3 = getelementptr inbounds i8, ptr %0, i32 -20
59   %4 = load ptr, ptr %3, align 4
60   %5 = getelementptr inbounds { ptr, ptr }, ptr %4, i32 0, i32 0
61   %6 = load ptr, ptr %5, align 4
62   %7 = load i32, ptr %6, align 4
63   store i32 %7, ptr %2, align 4
64   ret i32 1
67 define void @nested_exceptions() #0 personality ptr @_except_handler3 {
68 entry:
69   %__exception_code = alloca i32, align 4
70   call void (...) @llvm.localescape(ptr %__exception_code)
71   invoke void @crash() #3
72           to label %__try.cont unwind label %catch.dispatch
74 catch.dispatch:                                   ; preds = %entry
75   %cs1 = catchswitch within none [label %__except.ret] unwind label %catch.dispatch.11
77 __except.ret:                                     ; preds = %catch.dispatch
78   %0 = catchpad within %cs1 [ptr @nested_exceptions_filter_catchall]
79   catchret from %0 to label %__try.cont
81 __try.cont:                                       ; preds = %entry, %__except.ret
82   invoke void @crash() #3
83           to label %__try.cont.9 unwind label %catch.dispatch.5
85 catch.dispatch.5:                                 ; preds = %__try.cont
86   %cs2 = catchswitch within none [label %__except.ret.7] unwind label %catch.dispatch.11
88 __except.ret.7:                                   ; preds = %catch.dispatch.5
89   %1 = catchpad within %cs2 [ptr @nested_exceptions_filter_catchall]
90   catchret from %1 to label %__try.cont.9
92 __try.cont.9:                                     ; preds = %__try.cont, %__except.ret.7
93   invoke void @crash() #3
94           to label %__try.cont.15 unwind label %catch.dispatch.11
96 catch.dispatch.11:                                ; preds = %catchendblock, %catchendblock.6, %__try.cont.9
97   %cs3 = catchswitch within none [label %__except.ret.13] unwind label %catch.dispatch.17
99 __except.ret.13:                                  ; preds = %catch.dispatch.11
100   %2 = catchpad within %cs3 [ptr @nested_exceptions_filter_catchall]
101   catchret from %2 to label %__try.cont.15
103 __try.cont.15:                                    ; preds = %__try.cont.9, %__except.ret.13
104   invoke void @crash() #3
105           to label %__try.cont.35 unwind label %catch.dispatch.17
107 catch.dispatch.17:                                ; preds = %catchendblock.12, %__try.cont.15
108   %cs4 = catchswitch within none [label %__except.ret.19] unwind to caller
110 __except.ret.19:                                  ; preds = %catch.dispatch.17
111   %3 = catchpad within %cs4 [ptr @nested_exceptions_filter_catchall]
112   catchret from %3 to label %__except.20
114 __except.20:                                      ; preds = %__except.ret.19
115   invoke void @crash() #3
116           to label %__try.cont.27 unwind label %catch.dispatch.23
118 catch.dispatch.23:                                ; preds = %__except.20
119   %cs5 = catchswitch within none [label %__except.ret.25] unwind to caller
121 __except.ret.25:                                  ; preds = %catch.dispatch.23
122   %4 = catchpad within %cs5 [ptr @nested_exceptions_filter_catchall]
123   catchret from %4 to label %__try.cont.27
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
129 catch.dispatch.30:                                ; preds = %__try.cont.27
130   %cs6 = catchswitch within none [label %__except.ret.32] unwind to caller
132 __except.ret.32:                                  ; preds = %catch.dispatch.30
133   %5 = catchpad within %cs6 [ptr @nested_exceptions_filter_catchall]
134   catchret from %5 to label %__try.cont.35
136 __try.cont.35:                                    ; preds = %__try.cont.15, %__try.cont.27, %__except.ret.32
137   ret void
140 ; This table is equivalent to the one produced by MSVC, even if it isn't in
141 ; quite the same order.
143 ; CHECK-LABEL: _nested_exceptions:
144 ; CHECK: L__ehtable$nested_exceptions:
145 ; CHECK:         .long   -1
146 ; CHECK:         .long   _nested_exceptions_filter_catchall
147 ; CHECK:         .long   LBB
148 ; CHECK:         .long   0
149 ; CHECK:         .long   _nested_exceptions_filter_catchall
150 ; CHECK:         .long   LBB
151 ; CHECK:         .long   1
152 ; CHECK:         .long   _nested_exceptions_filter_catchall
153 ; CHECK:         .long   LBB
154 ; CHECK:         .long   1
155 ; CHECK:         .long   _nested_exceptions_filter_catchall
156 ; CHECK:         .long   LBB
157 ; CHECK:         .long   -1
158 ; CHECK:         .long   _nested_exceptions_filter_catchall
159 ; CHECK:         .long   LBB
160 ; CHECK:         .long   -1
161 ; CHECK:         .long   _nested_exceptions_filter_catchall
162 ; CHECK:         .long   LBB
164 declare void @crash() #0
166 define internal i32 @nested_exceptions_filter_catchall() #0 {
167 entry:
168   %0 = call ptr @llvm.frameaddress(i32 1)
169   %1 = call ptr @llvm.eh.recoverfp(ptr @nested_exceptions, ptr %0)
170   %2 = call ptr @llvm.localrecover(ptr @nested_exceptions, ptr %1, i32 0)
171   %3 = getelementptr inbounds i8, ptr %0, i32 -20
172   %4 = load ptr, ptr %3, align 4
173   %5 = getelementptr inbounds { ptr, ptr }, ptr %4, i32 0, i32 0
174   %6 = load ptr, ptr %5, align 4
175   %7 = load i32, ptr %6, align 4
176   store i32 %7, ptr %2, align 4
177   ret i32 1
180 define void @code_in_catchpad() #0 personality ptr @_except_handler3 {
181 entry:
182   invoke void @f(i32 1) #3
183           to label %__except unwind label %catch.dispatch
185 catch.dispatch:                                   ; preds = %entry
186   %cs1 = catchswitch within none [label %__except.ret] unwind to caller
188 __except.ret:                                     ; preds = %catch.dispatch
189   %0 = catchpad within %cs1 [ptr @try_except_filter_catchall]
190   call void @f(i32 2) [ "funclet"(token %0) ]
191   catchret from %0 to label %__except
193 __except:
194   ret void
197 ; CHECK-LABEL: _code_in_catchpad:
198 ; CHECK: # %__except.ret
199 ; CHECK-NEXT:         movl    -24(%ebp), %esp
200 ; CHECK-NEXT:         addl    $12, %ebp
201 ; CHECK-NEXT:         movl    $-1, -16(%ebp)
202 ; CHECK-NEXT:         pushl   $2
203 ; CHECK-NEXT:         calll   _f
206 ; Function Attrs: nounwind readnone
207 declare ptr @llvm.frameaddress(i32) #1
209 ; Function Attrs: nounwind readnone
210 declare ptr @llvm.eh.recoverfp(ptr, ptr) #1
212 ; Function Attrs: nounwind readnone
213 declare ptr @llvm.localrecover(ptr, ptr, i32) #1
215 declare void @f(i32) #0
217 declare i32 @_except_handler3(...)
219 ; Function Attrs: nounwind
220 declare void @llvm.localescape(...) #2
222 attributes #0 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "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" }
223 attributes #1 = { nounwind readnone }
224 attributes #2 = { nounwind }
225 attributes #3 = { noinline }