[IR] Reformulate LLVM's EH funclet IR
[oota-llvm.git] / test / Transforms / LoopStrengthReduce / funclet.ll
1 ; RUN: opt < %s -loop-reduce -S | FileCheck %s
2
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"
5
6 declare i32 @_except_handler3(...)
7 declare i32 @__CxxFrameHandler3(...)
8
9 declare void @external(i32*)
10 declare void @reserve()
11
12 define void @f() personality i32 (...)* @_except_handler3 {
13 entry:
14   br label %throw
15
16 throw:                                            ; preds = %throw, %entry
17   %tmp96 = getelementptr inbounds i8, i8* undef, i32 1
18   invoke void @reserve()
19           to label %throw unwind label %pad
20
21 pad:                                              ; preds = %throw
22   %phi2 = phi i8* [ %tmp96, %throw ]
23   terminatepad within none [] unwind label %blah
24
25 blah:
26   %cs = catchswitch within none [label %unreachable] unwind label %blah2
27
28 unreachable:
29   catchpad within %cs []
30   unreachable
31
32 blah2:
33   %cleanuppadi4.i.i.i = cleanuppad within none []
34   br label %loop_body
35
36 loop_body:                                        ; preds = %iter, %pad
37   %tmp99 = phi i8* [ %tmp101, %iter ], [ %phi2, %blah2 ]
38   %tmp100 = icmp eq i8* %tmp99, undef
39   br i1 %tmp100, label %unwind_out, label %iter
40
41 iter:                                             ; preds = %loop_body
42   %tmp101 = getelementptr inbounds i8, i8* %tmp99, i32 1
43   br i1 undef, label %unwind_out, label %loop_body
44
45 unwind_out:                                       ; preds = %iter, %loop_body
46   cleanupret from %cleanuppadi4.i.i.i unwind to caller
47 }
48
49 ; CHECK-LABEL: define void @f(
50 ; CHECK: cleanuppad within none []
51 ; CHECK-NEXT: ptrtoint i8* %phi2 to i32
52
53 define void @g() personality i32 (...)* @_except_handler3 {
54 entry:
55   br label %throw
56
57 throw:                                            ; preds = %throw, %entry
58   %tmp96 = getelementptr inbounds i8, i8* undef, i32 1
59   invoke void @reserve()
60           to label %throw unwind label %pad
61
62 pad:
63   %phi2 = phi i8* [ %tmp96, %throw ]
64   %cs = catchswitch within none [label %unreachable, label %blah] unwind to caller
65
66 unreachable:
67   catchpad within %cs []
68   unreachable
69
70 blah:
71   %catchpad = catchpad within %cs []
72   br label %loop_body
73
74 unwind_out:
75   catchret from %catchpad to label %leave
76
77 leave:
78   ret void
79
80 loop_body:                                        ; preds = %iter, %pad
81   %tmp99 = phi i8* [ %tmp101, %iter ], [ %phi2, %blah ]
82   %tmp100 = icmp eq i8* %tmp99, undef
83   br i1 %tmp100, label %unwind_out, label %iter
84
85 iter:                                             ; preds = %loop_body
86   %tmp101 = getelementptr inbounds i8, i8* %tmp99, i32 1
87   br i1 undef, label %unwind_out, label %loop_body
88 }
89
90 ; CHECK-LABEL: define void @g(
91 ; CHECK: blah:
92 ; CHECK-NEXT: catchpad within %cs []
93 ; CHECK-NEXT: ptrtoint i8* %phi2 to i32
94
95
96 define void @h() personality i32 (...)* @_except_handler3 {
97 entry:
98   br label %throw
99
100 throw:                                            ; preds = %throw, %entry
101   %tmp96 = getelementptr inbounds i8, i8* undef, i32 1
102   invoke void @reserve()
103           to label %throw unwind label %pad
104
105 pad:
106   %cs = catchswitch within none [label %unreachable, label %blug] unwind to caller
107
108 unreachable:
109   catchpad within %cs []
110   unreachable
111
112 blug:
113   %phi2 = phi i8* [ %tmp96, %pad ]
114   %catchpad = catchpad within %cs []
115   br label %loop_body
116
117 unwind_out:
118   catchret from %catchpad to label %leave
119
120 leave:
121   ret void
122
123 loop_body:                                        ; preds = %iter, %pad
124   %tmp99 = phi i8* [ %tmp101, %iter ], [ %phi2, %blug ]
125   %tmp100 = icmp eq i8* %tmp99, undef
126   br i1 %tmp100, label %unwind_out, label %iter
127
128 iter:                                             ; preds = %loop_body
129   %tmp101 = getelementptr inbounds i8, i8* %tmp99, i32 1
130   br i1 undef, label %unwind_out, label %loop_body
131 }
132
133 ; CHECK-LABEL: define void @h(
134 ; CHECK: blug:
135 ; CHECK: catchpad within %cs []
136 ; CHECK-NEXT: ptrtoint i8* %phi2 to i32
137
138 define void @i() personality i32 (...)* @_except_handler3 {
139 entry:
140   br label %throw
141
142 throw:                                            ; preds = %throw, %entry
143   %tmp96 = getelementptr inbounds i8, i8* undef, i32 1
144   invoke void @reserve()
145           to label %throw unwind label %catchpad
146
147 catchpad:                                              ; preds = %throw
148   %phi2 = phi i8* [ %tmp96, %throw ]
149   %cs = catchswitch within none [label %cp_body] unwind label %cleanuppad
150
151 cp_body:
152   catchpad within %cs []
153   br label %loop_head
154
155 cleanuppad:
156   cleanuppad within none []
157   br label %loop_head
158
159 loop_head:
160   br label %loop_body
161
162 loop_body:                                        ; preds = %iter, %catchpad
163   %tmp99 = phi i8* [ %tmp101, %iter ], [ %phi2, %loop_head ]
164   %tmp100 = icmp eq i8* %tmp99, undef
165   br i1 %tmp100, label %unwind_out, label %iter
166
167 iter:                                             ; preds = %loop_body
168   %tmp101 = getelementptr inbounds i8, i8* %tmp99, i32 1
169   br i1 undef, label %unwind_out, label %loop_body
170
171 unwind_out:                                       ; preds = %iter, %loop_body
172   unreachable
173 }
174
175 ; CHECK-LABEL: define void @i(
176 ; CHECK: ptrtoint i8* %phi2 to i32
177
178 define void @test1(i32* %b, i32* %c) personality i32 (...)* @__CxxFrameHandler3 {
179 entry:
180   br label %for.cond
181
182 for.cond:                                         ; preds = %for.inc, %entry
183   %d.0 = phi i32* [ %b, %entry ], [ %incdec.ptr, %for.inc ]
184   invoke void @external(i32* %d.0)
185           to label %for.inc unwind label %catch.dispatch
186
187 for.inc:                                          ; preds = %for.cond
188   %incdec.ptr = getelementptr inbounds i32, i32* %d.0, i32 1
189   br label %for.cond
190
191 catch.dispatch:                                   ; preds = %for.cond
192   %cs = catchswitch within none [label %catch] unwind label %catch.dispatch.2
193
194 catch:                                            ; preds = %catch.dispatch
195   %0 = catchpad within %cs [i8* null, i32 64, i8* null]
196   catchret from %0 to label %try.cont
197
198 try.cont:                                         ; preds = %catch
199   invoke void @external(i32* %c)
200           to label %try.cont.7 unwind label %catch.dispatch.2
201
202 catch.dispatch.2:                                 ; preds = %try.cont, %catchendblock
203   %e.0 = phi i32* [ %c, %try.cont ], [ %b, %catch.dispatch ]
204   %cs2 = catchswitch within none [label %catch.4] unwind to caller
205
206 catch.4:                                          ; preds = %catch.dispatch.2
207   catchpad within %cs2 [i8* null, i32 64, i8* null]
208   unreachable
209
210 try.cont.7:                                       ; preds = %try.cont
211   ret void
212 }
213
214 ; CHECK-LABEL: define void @test1(
215 ; CHECK: for.cond:
216 ; CHECK:   %d.0 = phi i32* [ %b, %entry ], [ %incdec.ptr, %for.inc ]
217
218 ; CHECK: catch.dispatch.2:
219 ; CHECK: %e.0 = phi i32* [ %c, %try.cont ], [ %b, %catch.dispatch ]