66a9132980fcbf1f22a47b46d81015f811d35097
[oota-llvm.git] / test / CodeGen / WinEH / wineh-cloning.ll
1 ; RUN: opt -mtriple=x86_64-pc-windows-msvc -S -winehprepare  < %s | FileCheck %s
2
3 declare i32 @__CxxFrameHandler3(...)
4 declare i32 @__C_specific_handler(...)
5
6 declare void @f()
7 declare i32 @g()
8 declare void @h(i32)
9 declare i1 @b()
10
11
12 define void @test1() personality i32 (...)* @__CxxFrameHandler3 {
13 entry:
14   ; %x def colors: {entry} subset of use colors; must spill
15   %x = call i32 @g()
16   invoke void @f()
17     to label %noreturn unwind label %catch.switch
18 catch.switch:
19   %cs = catchswitch within none [label %catch] unwind to caller
20 catch:
21   catchpad within %cs []
22   br label %noreturn
23 noreturn:
24   ; %x use colors: {entry, cleanup}
25   call void @h(i32 %x)
26   unreachable
27 }
28 ; Need two copies of the call to @h, one under entry and one under catch.
29 ; Currently we generate a load for each, though we shouldn't need one
30 ; for the use in entry's copy.
31 ; CHECK-LABEL: define void @test1(
32 ; CHECK: entry:
33 ; CHECK:   %x = call i32 @g()
34 ; CHECK:   invoke void @f()
35 ; CHECK:     to label %[[EntryCopy:[^ ]+]] unwind label %catch
36 ; CHECK: catch.switch:
37 ; CHECK:   %cs = catchswitch within none [label %catch] unwind to caller
38 ; CHECK: catch:
39 ; CHECK:   catchpad within %cs []
40 ; CHECK-NEXT: call void @h(i32 %x)
41 ; CHECK: [[EntryCopy]]:
42 ; CHECK:   call void @h(i32 %x)
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 within none []
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: define void @test2(
60 ; CHECK: entry:
61 ; CHECK:   invoke void @f()
62 ; CHECK:     to label %[[exit:[^ ]+]] unwind label %cleanup
63 ; CHECK: cleanup:
64 ; CHECK:   cleanuppad within none []
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.switch
76 invoke.cont:
77   invoke void @f()
78     to label %exit unwind label %cleanup
79 catch.switch:
80   %cs = catchswitch within none [label %catch] unwind to caller
81 catch:
82   catchpad within %cs []
83   br label %shared
84 cleanup:
85   cleanuppad within none []
86   br label %shared
87 shared:
88   call void @f()
89   br label %exit
90 exit:
91   ret void
92 }
93 ; Need two copies of %shared's call to @f (similar to @test2 but
94 ; the two regions here are siblings, not parent-child).
95 ; CHECK-LABEL: define void @test3(
96 ; CHECK:   invoke void @f()
97 ; CHECK:   invoke void @f()
98 ; CHECK:     to label %[[exit:[^ ]+]] unwind
99 ; CHECK: catch:
100 ; CHECK:   catchpad within %cs []
101 ; CHECK-NEXT: call void @f()
102 ; CHECK-NEXT: unreachable
103 ; CHECK: cleanup:
104 ; CHECK:   cleanuppad within none []
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.switch
115 catch.switch:
116   %cs = catchswitch within none [label %catch] unwind to caller
117 catch:
118   catchpad within %cs []
119   br label %shared
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: define void @test4(
147 ; CHECK:  entry:
148 ; CHECK:    to label %[[shared_E:[^ ]+]] unwind label %catch.switch
149 ; CHECK:  catch:
150 ; CHECK:    catchpad within %cs []
151 ; CHECK:    [[x_C:%[^ ]+]] = call i32 @g()
152 ; CHECK:    [[i_C:%[^ ]+]] = call i32 @g()
153 ; CHECK:    [[zt_C:%[^ ]+]] = icmp eq i32 [[i_C]], 0
154 ; CHECK:    br i1 [[zt_C]], label %[[exit_C:[^ ]+]], label %[[loop_C:[^ ]+]]
155 ; CHECK:  [[shared_E]]:
156 ; CHECK:    [[x_E:%[^ ]+]] = call i32 @g()
157 ; CHECK:    [[i_E:%[^ ]+]] = call i32 @g()
158 ; CHECK:    [[zt_E:%[^ ]+]] = icmp eq i32 [[i_E]], 0
159 ; CHECK:    br i1 [[zt_E]], label %[[exit_E:[^ ]+]], label %[[loop_E:[^ ]+]]
160 ; CHECK:  [[loop_C]]:
161 ; CHECK:    [[iloop_C:%[^ ]+]] = phi i32 [ [[i_C]], %catch ], [ [[idec_C:%[^ ]+]], %[[looptail_C:[^ ]+]] ]
162 ; CHECK:    [[b_C:%[^ ]+]] = call i1 @b()
163 ; CHECK:    br i1 [[b_C]], label %[[left_C:[^ ]+]], label %[[right_C:[^ ]+]]
164 ; CHECK:  [[loop_E]]:
165 ; CHECK:    [[iloop_E:%[^ ]+]] = phi i32 [ [[i_E]], %[[shared_E]] ], [ [[idec_E:%[^ ]+]], %[[looptail_E:[^ ]+]] ]
166 ; CHECK:    [[b_E:%[^ ]+]] = call i1 @b()
167 ; CHECK:    br i1 [[b_E]], label %[[left_E:[^ ]+]], label %[[right_E:[^ ]+]]
168 ; CHECK:  [[left_C]]:
169 ; CHECK:    [[y_C:%[^ ]+]] = call i32 @g()
170 ; CHECK:    br label %[[looptail_C]]
171 ; CHECK:  [[left_E]]:
172 ; CHECK:    [[y_E:%[^ ]+]] = call i32 @g()
173 ; CHECK:    br label %[[looptail_E]]
174 ; CHECK:  [[right_C]]:
175 ; CHECK:    call void @h(i32 [[x_C]])
176 ; CHECK:    br label %[[looptail_C]]
177 ; CHECK:  [[right_E]]:
178 ; CHECK:    call void @h(i32 [[x_E]])
179 ; CHECK:    br label %[[looptail_E]]
180 ; CHECK:  [[looptail_C]]:
181 ; CHECK:    [[idec_C]] = sub i32 [[iloop_C]], 1
182 ; CHECK:    [[done_C:%[^ ]+]] = icmp eq i32 [[idec_C]], 0
183 ; CHECK:    br i1 [[done_C]], label %[[exit_C]], label %[[loop_C]]
184 ; CHECK:  [[looptail_E]]:
185 ; CHECK:    [[idec_E]] = sub i32 [[iloop_E]], 1
186 ; CHECK:    [[done_E:%[^ ]+]] = icmp eq i32 [[idec_E]], 0
187 ; CHECK:    br i1 [[done_E]], label %[[exit_E]], label %[[loop_E]]
188 ; CHECK:  [[exit_C]]:
189 ; CHECK:    call void @h(i32 [[x_C]])
190 ; CHECK:    unreachable
191 ; CHECK:  [[exit_E]]:
192 ; CHECK:    call void @h(i32 [[x_E]])
193 ; CHECK:    unreachable
194
195
196 define void @test5() personality i32 (...)* @__C_specific_handler {
197 entry:
198   invoke void @f()
199     to label %exit unwind label %outer
200 outer:
201   %o = cleanuppad within none []
202   %x = call i32 @g()
203   invoke void @f()
204     to label %outer.ret unwind label %catch.switch
205 catch.switch:
206   %cs = catchswitch within %o [label %inner] unwind to caller
207 inner:
208   %i = catchpad within %cs []
209   catchret from %i to label %outer.post-inner
210 outer.post-inner:
211   call void @h(i32 %x)
212   br label %outer.ret
213 outer.ret:
214   cleanupret from %o unwind to caller
215 exit:
216   ret void
217 }
218 ; Simple nested case (catch-inside-cleanup).  Nothing needs
219 ; to be cloned.  The def and use of %x are both in %outer
220 ; and so don't need to be spilled.
221 ; CHECK-LABEL: define void @test5(
222 ; CHECK:      outer:
223 ; CHECK:        %x = call i32 @g()
224 ; CHECK-NEXT:   invoke void @f()
225 ; CHECK-NEXT:     to label %outer.ret unwind label %catch.switch
226 ; CHECK:      inner:
227 ; CHECK-NEXT:   %i = catchpad within %cs []
228 ; CHECK-NEXT:   catchret from %i to label %outer.post-inner
229 ; CHECK:      outer.post-inner:
230 ; CHECK-NEXT:   call void @h(i32 %x)
231 ; CHECK-NEXT:   br label %outer.ret
232
233
234 define void @test6() personality i32 (...)* @__C_specific_handler {
235 entry:
236   invoke void @f()
237     to label %invoke.cont unwind label %left
238 invoke.cont:
239   invoke void @f()
240     to label %exit unwind label %right
241 left:
242   cleanuppad within none []
243   br label %shared
244 right:
245   %cs = catchswitch within none [label %right.catch] unwind to caller
246 right.catch:
247   catchpad within %cs []
248   br label %shared
249 shared:
250   %x = call i32 @g()
251   invoke void @f()
252     to label %shared.cont unwind label %inner
253 shared.cont:
254   unreachable
255 inner:
256   %i = cleanuppad within none []
257   call void @h(i32 %x)
258   cleanupret from %i unwind to caller
259 exit:
260   ret void
261 }
262 ; CHECK-LABEL: define void @test6(
263 ; CHECK:     left:
264 ; CHECK:       %x.for.left = call i32 @g()
265 ; CHECK:       invoke void @f()
266 ; CHECK:           to label %shared.cont.for.left unwind label %inner
267 ; CHECK:     right.catch:
268 ; CHECK:       catchpad
269 ; CHECK:       %x = call i32 @g()
270 ; CHECK:           to label %shared.cont unwind label %inner
271 ; CHECK:     shared.cont:
272 ; CHECK:       unreachable
273 ; CHECK:     shared.cont.for.left:
274 ; CHECK:       unreachable
275 ; CHECK:     inner:
276 ; CHECK:       %i = cleanuppad within none []
277 ; CHECK:       call void @h(i32 %x1.wineh.reload)
278 ; CHECK:       cleanupret from %i unwind to caller
279
280
281 define void @test9() personality i32 (...)* @__C_specific_handler {
282 entry:
283   invoke void @f()
284     to label %invoke.cont unwind label %left
285 invoke.cont:
286   invoke void @f()
287     to label %unreachable unwind label %right
288 left:
289   cleanuppad within none []
290   call void @h(i32 1)
291   invoke void @f()
292     to label %unreachable unwind label %right
293 right:
294   cleanuppad within none []
295   call void @h(i32 2)
296   invoke void @f()
297     to label %unreachable unwind label %left
298 unreachable:
299   unreachable
300 }
301 ; This is an irreducible loop with two funclets that enter each other.
302 ; CHECK-LABEL: define void @test9(
303 ; CHECK:     entry:
304 ; CHECK:               to label %invoke.cont unwind label %[[LEFT:.+]]
305 ; CHECK:     invoke.cont:
306 ; CHECK:               to label %[[UNREACHABLE_ENTRY:.+]] unwind label %[[RIGHT:.+]]
307 ; CHECK:     [[LEFT]]:
308 ; CHECK:       call void @h(i32 1)
309 ; CHECK:       invoke void @f()
310 ; CHECK:               to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[RIGHT]]
311 ; CHECK:     [[RIGHT]]:
312 ; CHECK:       call void @h(i32 2)
313 ; CHECK:       invoke void @f()
314 ; CHECK:               to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[LEFT]]
315 ; CHECK:     [[UNREACHABLE_RIGHT]]:
316 ; CHECK:       unreachable
317 ; CHECK:     [[UNREACHABLE_LEFT]]:
318 ; CHECK:       unreachable
319 ; CHECK:     [[UNREACHABLE_ENTRY]]:
320 ; CHECK:       unreachable
321
322
323 define void @test10() personality i32 (...)* @__CxxFrameHandler3 {
324 entry:
325   invoke void @f()
326     to label %unreachable unwind label %inner
327 inner:
328   %cleanup = cleanuppad within none []
329   ; make sure we don't overlook this cleanupret and try to process
330   ; successor %outer as a child of inner.
331   cleanupret from %cleanup unwind label %outer
332 outer:
333   %cs = catchswitch within none [label %catch.body] unwind to caller
334
335 catch.body:
336   %catch = catchpad within %cs []
337   catchret from %catch to label %exit
338 exit:
339   ret void
340 unreachable:
341   unreachable
342 }
343 ; CHECK-LABEL: define void @test10(
344 ; CHECK-NEXT: entry:
345 ; CHECK-NEXT:   invoke
346 ; CHECK-NEXT:     to label %unreachable unwind label %inner
347 ; CHECK:      inner:
348 ; CHECK-NEXT:   %cleanup = cleanuppad within none []
349 ; CHECK-NEXT:   cleanupret from %cleanup unwind label %outer
350 ; CHECK:      outer:
351 ; CHECK-NEXT:   %cs = catchswitch within none [label %catch.body] unwind to caller
352 ; CHECK:      catch.body:
353 ; CHECK-NEXT:   %catch = catchpad within %cs []
354 ; CHECK-NEXT:   catchret from %catch to label %exit
355 ; CHECK:      exit:
356 ; CHECK-NEXT:   ret void
357
358 define void @test11() personality i32 (...)* @__C_specific_handler {
359 entry:
360   invoke void @f()
361     to label %exit unwind label %cleanup.outer
362 cleanup.outer:
363   %outer = cleanuppad within none []
364   invoke void @f()
365     to label %outer.cont unwind label %cleanup.inner
366 outer.cont:
367   br label %merge
368 cleanup.inner:
369   %inner = cleanuppad within %outer []
370   br label %merge
371 merge:
372   call void @f()
373   unreachable
374 exit:
375   ret void
376 }
377 ; merge.end will get cloned for outer and inner, but is implausible
378 ; from inner, so the call @f() in inner's copy of merge should be
379 ; rewritten to call @f()
380 ; CHECK-LABEL: define void @test11()
381 ; CHECK:      %inner = cleanuppad within %outer []
382 ; CHECK-NEXT: call void @f()
383 ; CHECK-NEXT: unreachable
384
385 define void @test12() personality i32 (...)* @__CxxFrameHandler3 !dbg !5 {
386 entry:
387   invoke void @f()
388     to label %cont unwind label %left, !dbg !8
389 cont:
390   invoke void @f()
391     to label %exit unwind label %right
392 left:
393   cleanuppad within none []
394   br label %join
395 right:
396   cleanuppad within none []
397   br label %join
398 join:
399   ; This call will get cloned; make sure we can handle cloning
400   ; instructions with debug metadata attached.
401   call void @f(), !dbg !9
402   unreachable
403 exit:
404   ret void
405 }
406
407 ; CHECK-LABEL: define void @test13()
408 ; CHECK: ret void
409 define void @test13() personality i32 (...)* @__CxxFrameHandler3 {
410 entry:
411   ret void
412
413 unreachable:
414   cleanuppad within none []
415   unreachable
416 }
417
418 ;; Debug info (from test12)
419
420 ; Make sure the DISubprogram doesn't get cloned
421 ; CHECK-LABEL: !llvm.module.flags
422 ; CHECK-NOT: !DISubprogram
423 ; CHECK: !{{[0-9]+}} = distinct !DISubprogram(name: "test12"
424 ; CHECK-NOT: !DISubprogram
425 !llvm.module.flags = !{!0}
426 !llvm.dbg.cu = !{!1}
427
428 !0 = !{i32 2, !"Debug Info Version", i32 3}
429 !1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "compiler", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !3, subprograms: !4)
430 !2 = !DIFile(filename: "test.cpp", directory: ".")
431 !3 = !{}
432 !4 = !{!5}
433 !5 = distinct !DISubprogram(name: "test12", scope: !2, file: !2, type: !6, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, variables: !3)
434 !6 = !DISubroutineType(types: !7)
435 !7 = !{null}
436 !8 = !DILocation(line: 1, scope: !5)
437 !9 = !DILocation(line: 2, scope: !5)