Fix CHECK directives that weren't checking.
[oota-llvm.git] / test / CodeGen / WinEH / wineh-cloning.ll
1 ; RUN: opt -mtriple=x86_x64-pc-windows-msvc -S -winehprepare  < %s | FileCheck %s
2
3 declare i32 @__CxxFrameHandler3(...)
4
5 declare void @f()
6 declare i32 @g()
7 declare void @h(i32)
8 declare i1 @b()
9
10
11 define void @test1() personality i32 (...)* @__CxxFrameHandler3 {
12 entry:
13   ; %x def colors: {entry} subset of use colors; must spill
14   %x = call i32 @g()
15   invoke void @f()
16     to label %noreturn unwind label %catch
17 catch:
18   catchpad []
19     to label %noreturn unwind label %endcatch
20 noreturn:
21   ; %x use colors: {entry, cleanup}
22   call void @h(i32 %x)
23   unreachable
24 endcatch:
25   catchendpad unwind to caller
26 }
27 ; Need two copies of the call to @h, one under entry and one under catch.
28 ; Currently we generate a load for each, though we shouldn't need one
29 ; for the use in entry's copy.
30 ; CHECK-LABEL: @test1(
31 ; CHECK: entry:
32 ; CHECK:   store i32 %x, i32* [[Slot:%[^ ]+]]
33 ; CHECK:   invoke void @f()
34 ; CHECK:     to label %[[EntryCopy:[^ ]+]] unwind label %catch
35 ; CHECK: catch:
36 ; CHECK:   catchpad [] to label %[[CatchCopy:[^ ]+]] unwind
37 ; CHECK: [[CatchCopy]]:
38 ; CHECK:   [[LoadX2:%[^ ]+]] = load i32, i32* [[Slot]]
39 ; CHECK:   call void @h(i32 [[LoadX2]]
40 ; CHECK: [[EntryCopy]]:
41 ; CHECK:   [[LoadX1:%[^ ]+]] = load i32, i32* [[Slot]]
42 ; CHECK:   call void @h(i32 [[LoadX1]]
43
44
45 define void @test2() personality i32 (...)* @__CxxFrameHandler3 {
46 entry:
47   invoke void @f()
48     to label %exit unwind label %cleanup
49 cleanup:
50   cleanuppad []
51   br label %exit
52 exit:
53   call void @f()
54   ret void
55 }
56 ; Need two copies of %exit's call to @f -- the subsequent ret is only
57 ; valid when coming from %entry, but on the path from %cleanup, this
58 ; might be a valid call to @f which might dynamically not return.
59 ; CHECK-LABEL: @test2(
60 ; CHECK: entry:
61 ; CHECK:   invoke void @f()
62 ; CHECK:     to label %[[exit:[^ ]+]] unwind label %cleanup
63 ; CHECK: cleanup:
64 ; CHECK:   cleanuppad []
65 ; CHECK:   call void @f()
66 ; CHECK-NEXT: unreachable
67 ; CHECK: [[exit]]:
68 ; CHECK:   call void @f()
69 ; CHECK-NEXT: ret void
70
71
72 define void @test3() personality i32 (...)* @__CxxFrameHandler3 {
73 entry:
74   invoke void @f()
75     to label %invoke.cont unwind label %catch
76 invoke.cont:
77   invoke void @f()
78     to label %exit unwind label %cleanup
79 catch:
80   catchpad [] to label %shared unwind label %endcatch
81 endcatch:
82   catchendpad unwind to caller
83 cleanup:
84   cleanuppad []
85   br label %shared
86 shared:
87   call void @f()
88   br label %exit
89 exit:
90   ret void
91 }
92 ; Need two copies of %shared's call to @f (similar to @test2 but
93 ; the two regions here are siblings, not parent-child).
94 ; CHECK-LABEL: @test3(
95 ; CHECK:   invoke void @f()
96 ; CHECK:   invoke void @f()
97 ; CHECK:     to label %[[exit:[^ ]+]] unwind
98 ; CHECK: catch:
99 ; CHECK:   catchpad [] to label %[[shared:[^ ]+]] unwind
100 ; CHECK: cleanup:
101 ; CHECK:   cleanuppad []
102 ; CHECK:   call void @f()
103 ; CHECK-NEXT: unreachable
104 ; CHECK: [[shared]]:
105 ; CHECK:   call void @f()
106 ; CHECK-NEXT: unreachable
107 ; CHECK: [[exit]]:
108 ; CHECK:   ret void
109
110
111 define void @test4() personality i32 (...)* @__CxxFrameHandler3 {
112 entry:
113   invoke void @f()
114     to label %shared unwind label %catch
115 catch:
116   catchpad []
117     to label %shared unwind label %endcatch
118 endcatch:
119   catchendpad unwind to caller
120 shared:
121   %x = call i32 @g()
122   %i = call i32 @g()
123   %zero.trip = icmp eq i32 %i, 0
124   br i1 %zero.trip, label %exit, label %loop
125 loop:
126   %i.loop = phi i32 [ %i, %shared ], [ %i.dec, %loop.tail ]
127   %b = call i1 @b()
128   br i1 %b, label %left, label %right
129 left:
130   %y = call i32 @g()
131   br label %loop.tail
132 right:
133   call void @h(i32 %x)
134   br label %loop.tail
135 loop.tail:
136   %i.dec = sub i32 %i.loop, 1
137   %done = icmp eq i32 %i.dec, 0
138   br i1 %done, label %exit, label %loop
139 exit:
140   call void @h(i32 %x)
141   unreachable
142 }
143 ; Make sure we can clone regions that have internal control
144 ; flow and SSA values.  Here we need two copies of everything
145 ; from %shared to %exit.
146 ; CHECK-LABEL: @test4(
147 ; CHECK:  entry:
148 ; CHECK:    to label %[[shared_E:[^ ]+]] unwind label %catch
149 ; CHECK:  catch:
150 ; CHECK:    to label %[[shared_C:[^ ]+]] unwind label %endcatch
151 ; CHECK:  [[shared_C]]:
152 ; CHECK:    [[x_C:%[^ ]+]] = call i32 @g()
153 ; CHECK:    [[i_C:%[^ ]+]] = call i32 @g()
154 ; CHECK:    [[zt_C:%[^ ]+]] = icmp eq i32 [[i_C]], 0
155 ; CHECK:    br i1 [[zt_C]], label %[[exit_C:[^ ]+]], label %[[loop_C:[^ ]+]]
156 ; CHECK:  [[shared_E]]:
157 ; CHECK:    [[x_E:%[^ ]+]] = call i32 @g()
158 ; CHECK:    [[i_E:%[^ ]+]] = call i32 @g()
159 ; CHECK:    [[zt_E:%[^ ]+]] = icmp eq i32 [[i_E]], 0
160 ; CHECK:    br i1 [[zt_E]], label %[[exit_E:[^ ]+]], label %[[loop_E:[^ ]+]]
161 ; CHECK:  [[loop_C]]:
162 ; CHECK:    [[iloop_C:%[^ ]+]] = phi i32 [ [[i_C]], %[[shared_C]] ], [ [[idec_C:%[^ ]+]], %[[looptail_C:[^ ]+]] ]
163 ; CHECK:    [[b_C:%[^ ]+]] = call i1 @b()
164 ; CHECK:    br i1 [[b_C]], label %[[left_C:[^ ]+]], label %[[right_C:[^ ]+]]
165 ; CHECK:  [[loop_E]]:
166 ; CHECK:    [[iloop_E:%[^ ]+]] = phi i32 [ [[i_E]], %[[shared_E]] ], [ [[idec_E:%[^ ]+]], %[[looptail_E:[^ ]+]] ]
167 ; CHECK:    [[b_E:%[^ ]+]] = call i1 @b()
168 ; CHECK:    br i1 [[b_E]], label %[[left_E:[^ ]+]], label %[[right_E:[^ ]+]]
169 ; CHECK:  [[left_C]]:
170 ; CHECK:    [[y_C:%[^ ]+]] = call i32 @g()
171 ; CHECK:    br label %[[looptail_C]]
172 ; CHECK:  [[left_E]]:
173 ; CHECK:    [[y_E:%[^ ]+]] = call i32 @g()
174 ; CHECK:    br label %[[looptail_E]]
175 ; CHECK:  [[right_C]]:
176 ; CHECK:    call void @h(i32 [[x_C]])
177 ; CHECK:    br label %[[looptail_C]]
178 ; CHECK:  [[right_E]]:
179 ; CHECK:    call void @h(i32 [[x_E]])
180 ; CHECK:    br label %[[looptail_E]]
181 ; CHECK:  [[looptail_C]]:
182 ; CHECK:    [[idec_C]] = sub i32 [[iloop_C]], 1
183 ; CHECK:    [[done_C:%[^ ]+]] = icmp eq i32 [[idec_C]], 0
184 ; CHECK:    br i1 [[done_C]], label %[[exit_C]], label %[[loop_C]]
185 ; CHECK:  [[looptail_E]]:
186 ; CHECK:    [[idec_E]] = sub i32 [[iloop_E]], 1
187 ; CHECK:    [[done_E:%[^ ]+]] = icmp eq i32 [[idec_E]], 0
188 ; CHECK:    br i1 [[done_E]], label %[[exit_E]], label %[[loop_E]]
189 ; CHECK:  [[exit_C]]:
190 ; CHECK:    call void @h(i32 [[x_C]])
191 ; CHECK:    unreachable
192 ; CHECK:  [[exit_E]]:
193 ; CHECK:    call void @h(i32 [[x_E]])
194 ; CHECK:    unreachable
195
196
197 define void @test5() personality i32 (...)* @__CxxFrameHandler3 {
198 entry:
199   invoke void @f()
200     to label %exit unwind label %outer
201 outer:
202   %o = cleanuppad []
203   %x = call i32 @g()
204   invoke void @f()
205     to label %outer.ret unwind label %inner
206 inner:
207   %i = catchpad []
208     to label %inner.catch unwind label %inner.endcatch
209 inner.catch:
210   catchret %i to label %outer.post-inner
211 inner.endcatch:
212   catchendpad unwind to caller
213 outer.post-inner:
214   call void @h(i32 %x)
215   br label %outer.ret
216 outer.ret:
217   cleanupret %o unwind to caller
218 exit:
219   ret void
220 }
221 ; Simple nested case (catch-inside-cleanup).  Nothing needs
222 ; to be cloned.  The def and use of %x are both in %outer
223 ; and so don't need to be spilled.
224 ; CHECK-LABEL: @test5(
225 ; CHECK:      outer:
226 ; CHECK:        %x = call i32 @g()
227 ; CHECK-NEXT:   invoke void @f()
228 ; CHECK-NEXT:     to label %outer.ret unwind label %inner
229 ; CHECK:      inner:
230 ; CHECK:          to label %inner.catch unwind label %inner.endcatch
231 ; CHECK:      inner.catch:
232 ; CHECK-NEXT:   catchret %i to label %outer.post-inner
233 ; CHECK:      outer.post-inner:
234 ; CHECK-NEXT:   call void @h(i32 %x)
235 ; CHECK-NEXT:   br label %outer.ret
236
237
238 define void @test6() personality i32 (...)* @__CxxFrameHandler3 {
239 entry:
240   invoke void @f()
241     to label %invoke.cont unwind label %left
242 invoke.cont:
243   invoke void @f()
244     to label %exit unwind label %right
245 left:
246   cleanuppad []
247   br label %shared
248 right:
249   catchpad []
250     to label %right.catch unwind label %right.end
251 right.catch:
252   br label %shared
253 right.end:
254   catchendpad unwind to caller
255 shared:
256   %x = call i32 @g()
257   invoke void @f()
258     to label %shared.cont unwind label %inner
259 shared.cont:
260   unreachable
261 inner:
262   %i = cleanuppad []
263   call void @h(i32 %x)
264   cleanupret %i unwind label %right.end
265 exit:
266   ret void
267 }
268 ; %inner is a cleanup which appears both as a child of
269 ; %left and as a child of %right.  Since statically we
270 ; need each funclet to have a single parent, we need to
271 ; clone the entire %inner funclet so we can have one
272 ; copy under each parent.  The cleanupret in %inner
273 ; unwinds to the catchendpad for %right, so the copy
274 ; of %inner under %right should include it; the copy
275 ; of %inner under %left should instead have an
276 ; `unreachable` inserted there, but the copy under
277 ; %left still needs to be created because it's possible
278 ; the dynamic path enters %left, then enters %inner,
279 ; then calls @h, and that the call to @h doesn't return.
280 ; CHECK-LABEL: @test6(
281 ; TODO: CHECKs
282
283
284 define void @test7() personality i32 (...)* @__CxxFrameHandler3 {
285 entry:
286   invoke void @f()
287     to label %invoke.cont unwind label %left
288 invoke.cont:
289   invoke void @f()
290     to label %unreachable unwind label %right
291 left:
292   cleanuppad []
293   invoke void @f() to label %unreachable unwind label %inner
294 right:
295   catchpad []
296     to label %right.catch unwind label %right.end
297 right.catch:
298   invoke void @f() to label %unreachable unwind label %inner
299 right.end:
300   catchendpad unwind to caller
301 inner:
302   %i = cleanuppad []
303   %x = call i32 @g()
304   call void @h(i32 %x)
305   cleanupret %i unwind label %right.end
306 unreachable:
307   unreachable
308 }
309 ; Another case of a two-parent child (like @test6), this time
310 ; with the join at the entry itself instead of following a
311 ; non-pad join.
312 ; CHECK-LABEL: @test7(
313 ; TODO: CHECKs
314
315
316 define void @test8() personality i32 (...)* @__CxxFrameHandler3 {
317 entry:
318   invoke void @f()
319     to label %invoke.cont unwind label %left
320 invoke.cont:
321   invoke void @f()
322     to label %unreachable unwind label %right
323 left:
324   cleanuppad []
325   br label %shared
326 right:
327   catchpad []
328     to label %right.catch unwind label %right.end
329 right.catch:
330   br label %shared
331 right.end:
332   catchendpad unwind to caller
333 shared:
334   invoke void @f()
335     to label %unreachable unwind label %inner
336 inner:
337   cleanuppad []
338   invoke void @f()
339     to label %unreachable unwind label %inner.child
340 inner.child:
341   cleanuppad []
342   %x = call i32 @g()
343   call void @h(i32 %x)
344   unreachable
345 unreachable:
346   unreachable
347 }
348 ; %inner is a two-parent child which itself has a child; need
349 ; to make two copies of both the %inner and %inner.child.
350 ; CHECK-LABEL: @test8(
351 ; TODO: CHECKs
352
353
354 define void @test9() personality i32 (...)* @__CxxFrameHandler3 {
355 entry:
356   invoke void @f()
357     to label %invoke.cont unwind label %left
358 invoke.cont:
359   invoke void @f()
360     to label %unreachable unwind label %right
361 left:
362   cleanuppad []
363   call void @h(i32 1)
364   invoke void @f()
365     to label %unreachable unwind label %right
366 right:
367   cleanuppad []
368   call void @h(i32 2)
369   invoke void @f()
370     to label %unreachable unwind label %left
371 unreachable:
372   unreachable
373 }
374 ; This is an irreducible loop with two funclets that enter each other;
375 ; need to make two copies of each funclet (one a child of root, the
376 ; other a child of the opposite funclet), but also make sure not to
377 ; clone self-descendants (if we tried to do that we'd need to make an
378 ; infinite number of them).  Presumably if optimizations ever generated
379 ; such a thing it would mean that one of the two cleanups was originally
380 ; the parent of the other, but that we'd somehow lost track in the CFG
381 ; of which was which along the way; generating each possibility lets
382 ; whichever case was correct execute correctly.
383 ; CHECK-LABEL: @test9(
384 ; TODO: CHECKs