[WinEH] Use operand bundles to describe call sites
[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
8 declare void @llvm.foo(i32) nounwind
9 declare void @llvm.bar() nounwind
10 declare i32 @llvm.qux() nounwind
11 declare i1 @llvm.baz() nounwind
12
13 define void @test1() personality i32 (...)* @__CxxFrameHandler3 {
14 entry:
15   ; %x def colors: {entry} subset of use colors; must spill
16   %x = call i32 @llvm.qux()
17   invoke void @f()
18     to label %noreturn unwind label %catch.switch
19 catch.switch:
20   %cs = catchswitch within none [label %catch] unwind to caller
21 catch:
22   %cp = catchpad within %cs []
23   br label %noreturn
24 noreturn:
25   ; %x use colors: {entry, cleanup}
26   call void @llvm.foo(i32 %x)
27   unreachable
28 }
29 ; Need two copies of the call to @h, one under entry and one under catch.
30 ; Currently we generate a load for each, though we shouldn't need one
31 ; for the use in entry's copy.
32 ; CHECK-LABEL: define void @test1(
33 ; CHECK: entry:
34 ; CHECK:   %x = call i32 @llvm.qux()
35 ; CHECK:   invoke void @f()
36 ; CHECK:     to label %[[EntryCopy:[^ ]+]] unwind label %catch
37 ; CHECK: catch.switch:
38 ; CHECK:   %cs = catchswitch within none [label %catch] unwind to caller
39 ; CHECK: catch:
40 ; CHECK:   catchpad within %cs []
41 ; CHECK-NEXT: call void @llvm.foo(i32 %x)
42 ; CHECK: [[EntryCopy]]:
43 ; CHECK:   call void @llvm.foo(i32 %x)
44
45
46 define void @test2() personality i32 (...)* @__CxxFrameHandler3 {
47 entry:
48   invoke void @f()
49     to label %exit unwind label %cleanup
50 cleanup:
51   cleanuppad within none []
52   br label %exit
53 exit:
54   call void @llvm.bar()
55   ret void
56 }
57 ; Need two copies of %exit's call to @f -- the subsequent ret is only
58 ; valid when coming from %entry, but on the path from %cleanup, this
59 ; might be a valid call to @f which might dynamically not return.
60 ; CHECK-LABEL: define void @test2(
61 ; CHECK: entry:
62 ; CHECK:   invoke void @f()
63 ; CHECK:     to label %[[exit:[^ ]+]] unwind label %cleanup
64 ; CHECK: cleanup:
65 ; CHECK:   cleanuppad within none []
66 ; CHECK:   call void @llvm.bar()
67 ; CHECK-NEXT: unreachable
68 ; CHECK: [[exit]]:
69 ; CHECK:   call void @llvm.bar()
70 ; CHECK-NEXT: ret void
71
72
73 define void @test3() personality i32 (...)* @__CxxFrameHandler3 {
74 entry:
75   invoke void @f()
76     to label %invoke.cont unwind label %catch.switch
77 invoke.cont:
78   invoke void @f()
79     to label %exit unwind label %cleanup
80 catch.switch:
81   %cs = catchswitch within none [label %catch] unwind to caller
82 catch:
83   catchpad within %cs []
84   br label %shared
85 cleanup:
86   cleanuppad within none []
87   br label %shared
88 shared:
89   call void @llvm.bar()
90   br label %exit
91 exit:
92   ret void
93 }
94 ; Need two copies of %shared's call to @f (similar to @test2 but
95 ; the two regions here are siblings, not parent-child).
96 ; CHECK-LABEL: define void @test3(
97 ; CHECK:   invoke void @f()
98 ; CHECK:   invoke void @f()
99 ; CHECK:     to label %[[exit:[^ ]+]] unwind
100 ; CHECK: catch:
101 ; CHECK:   catchpad within %cs []
102 ; CHECK-NEXT: call void @llvm.bar()
103 ; CHECK-NEXT: unreachable
104 ; CHECK: cleanup:
105 ; CHECK:   cleanuppad within none []
106 ; CHECK:   call void @llvm.bar()
107 ; CHECK-NEXT: unreachable
108 ; CHECK: [[exit]]:
109 ; CHECK:   ret void
110
111
112 define void @test4() personality i32 (...)* @__CxxFrameHandler3 {
113 entry:
114   invoke void @f()
115     to label %shared unwind label %catch.switch
116 catch.switch:
117   %cs = catchswitch within none [label %catch] unwind to caller
118 catch:
119   catchpad within %cs []
120   br label %shared
121 shared:
122   %x = call i32 @llvm.qux()
123   %i = call i32 @llvm.qux()
124   %zero.trip = icmp eq i32 %i, 0
125   br i1 %zero.trip, label %exit, label %loop
126 loop:
127   %i.loop = phi i32 [ %i, %shared ], [ %i.dec, %loop.tail ]
128   %b = call i1 @llvm.baz()
129   br i1 %b, label %left, label %right
130 left:
131   %y = call i32 @llvm.qux()
132   br label %loop.tail
133 right:
134   call void @llvm.foo(i32 %x)
135   br label %loop.tail
136 loop.tail:
137   %i.dec = sub i32 %i.loop, 1
138   %done = icmp eq i32 %i.dec, 0
139   br i1 %done, label %exit, label %loop
140 exit:
141   call void @llvm.foo(i32 %x)
142   unreachable
143 }
144 ; Make sure we can clone regions that have internal control
145 ; flow and SSA values.  Here we need two copies of everything
146 ; from %shared to %exit.
147 ; CHECK-LABEL: define void @test4(
148 ; CHECK:  entry:
149 ; CHECK:    to label %[[shared_E:[^ ]+]] unwind label %catch.switch
150 ; CHECK:  catch:
151 ; CHECK:    catchpad within %cs []
152 ; CHECK:    [[x_C:%[^ ]+]] = call i32 @llvm.qux()
153 ; CHECK:    [[i_C:%[^ ]+]] = call i32 @llvm.qux()
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 @llvm.qux()
158 ; CHECK:    [[i_E:%[^ ]+]] = call i32 @llvm.qux()
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]], %catch ], [ [[idec_C:%[^ ]+]], %[[looptail_C:[^ ]+]] ]
163 ; CHECK:    [[b_C:%[^ ]+]] = call i1 @llvm.baz()
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 @llvm.baz()
168 ; CHECK:    br i1 [[b_E]], label %[[left_E:[^ ]+]], label %[[right_E:[^ ]+]]
169 ; CHECK:  [[left_C]]:
170 ; CHECK:    [[y_C:%[^ ]+]] = call i32 @llvm.qux()
171 ; CHECK:    br label %[[looptail_C]]
172 ; CHECK:  [[left_E]]:
173 ; CHECK:    [[y_E:%[^ ]+]] = call i32 @llvm.qux()
174 ; CHECK:    br label %[[looptail_E]]
175 ; CHECK:  [[right_C]]:
176 ; CHECK:    call void @llvm.foo(i32 [[x_C]])
177 ; CHECK:    br label %[[looptail_C]]
178 ; CHECK:  [[right_E]]:
179 ; CHECK:    call void @llvm.foo(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 @llvm.foo(i32 [[x_C]])
191 ; CHECK:    unreachable
192 ; CHECK:  [[exit_E]]:
193 ; CHECK:    call void @llvm.foo(i32 [[x_E]])
194 ; CHECK:    unreachable
195
196
197 define void @test5() personality i32 (...)* @__C_specific_handler {
198 entry:
199   invoke void @f()
200     to label %exit unwind label %outer
201 outer:
202   %o = cleanuppad within none []
203   %x = call i32 @llvm.qux()
204   invoke void @f() [ "funclet"(token %o) ]
205     to label %outer.ret unwind label %catch.switch
206 catch.switch:
207   %cs = catchswitch within %o [label %inner] unwind to caller
208 inner:
209   %i = catchpad within %cs []
210   catchret from %i to label %outer.post-inner
211 outer.post-inner:
212   call void @llvm.foo(i32 %x)
213   br label %outer.ret
214 outer.ret:
215   cleanupret from %o unwind to caller
216 exit:
217   ret void
218 }
219 ; Simple nested case (catch-inside-cleanup).  Nothing needs
220 ; to be cloned.  The def and use of %x are both in %outer
221 ; and so don't need to be spilled.
222 ; CHECK-LABEL: define void @test5(
223 ; CHECK:      outer:
224 ; CHECK:        %x = call i32 @llvm.qux()
225 ; CHECK-NEXT:   invoke void @f()
226 ; CHECK-NEXT:     to label %outer.ret unwind label %catch.switch
227 ; CHECK:      inner:
228 ; CHECK-NEXT:   %i = catchpad within %cs []
229 ; CHECK-NEXT:   catchret from %i to label %outer.post-inner
230 ; CHECK:      outer.post-inner:
231 ; CHECK-NEXT:   call void @llvm.foo(i32 %x)
232 ; CHECK-NEXT:   br label %outer.ret
233
234
235 define void @test9() personality i32 (...)* @__C_specific_handler {
236 entry:
237   invoke void @f()
238     to label %invoke.cont unwind label %left
239 invoke.cont:
240   invoke void @f()
241     to label %unreachable unwind label %right
242 left:
243   %cp.left = cleanuppad within none []
244   call void @llvm.foo(i32 1)
245   invoke void @f() [ "funclet"(token %cp.left) ]
246     to label %unreachable unwind label %right
247 right:
248   %cp.right = cleanuppad within none []
249   call void @llvm.foo(i32 2)
250   invoke void @f() [ "funclet"(token %cp.right) ]
251     to label %unreachable unwind label %left
252 unreachable:
253   unreachable
254 }
255 ; This is an irreducible loop with two funclets that enter each other.
256 ; CHECK-LABEL: define void @test9(
257 ; CHECK:     entry:
258 ; CHECK:               to label %invoke.cont unwind label %[[LEFT:.+]]
259 ; CHECK:     invoke.cont:
260 ; CHECK:               to label %[[UNREACHABLE_ENTRY:.+]] unwind label %[[RIGHT:.+]]
261 ; CHECK:     [[LEFT]]:
262 ; CHECK:       call void @llvm.foo(i32 1)
263 ; CHECK:       invoke void @f()
264 ; CHECK:               to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[RIGHT]]
265 ; CHECK:     [[RIGHT]]:
266 ; CHECK:       call void @llvm.foo(i32 2)
267 ; CHECK:       invoke void @f()
268 ; CHECK:               to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[LEFT]]
269 ; CHECK:     [[UNREACHABLE_RIGHT]]:
270 ; CHECK:       unreachable
271 ; CHECK:     [[UNREACHABLE_LEFT]]:
272 ; CHECK:       unreachable
273 ; CHECK:     [[UNREACHABLE_ENTRY]]:
274 ; CHECK:       unreachable
275
276
277 define void @test10() personality i32 (...)* @__CxxFrameHandler3 {
278 entry:
279   invoke void @f()
280     to label %unreachable unwind label %inner
281 inner:
282   %cleanup = cleanuppad within none []
283   ; make sure we don't overlook this cleanupret and try to process
284   ; successor %outer as a child of inner.
285   cleanupret from %cleanup unwind label %outer
286 outer:
287   %cs = catchswitch within none [label %catch.body] unwind to caller
288
289 catch.body:
290   %catch = catchpad within %cs []
291   catchret from %catch to label %exit
292 exit:
293   ret void
294 unreachable:
295   unreachable
296 }
297 ; CHECK-LABEL: define void @test10(
298 ; CHECK-NEXT: entry:
299 ; CHECK-NEXT:   invoke
300 ; CHECK-NEXT:     to label %unreachable unwind label %inner
301 ; CHECK:      inner:
302 ; CHECK-NEXT:   %cleanup = cleanuppad within none []
303 ; CHECK-NEXT:   cleanupret from %cleanup unwind label %outer
304 ; CHECK:      outer:
305 ; CHECK-NEXT:   %cs = catchswitch within none [label %catch.body] unwind to caller
306 ; CHECK:      catch.body:
307 ; CHECK-NEXT:   %catch = catchpad within %cs []
308 ; CHECK-NEXT:   catchret from %catch to label %exit
309 ; CHECK:      exit:
310 ; CHECK-NEXT:   ret void
311
312 define void @test11() personality i32 (...)* @__C_specific_handler {
313 entry:
314   invoke void @f()
315     to label %exit unwind label %cleanup.outer
316 cleanup.outer:
317   %outer = cleanuppad within none []
318   invoke void @f() [ "funclet"(token %outer) ]
319     to label %outer.cont unwind label %cleanup.inner
320 outer.cont:
321   br label %merge
322 cleanup.inner:
323   %inner = cleanuppad within %outer []
324   br label %merge
325 merge:
326   call void @llvm.bar()
327   unreachable
328 exit:
329   ret void
330 }
331 ; merge.end will get cloned for outer and inner, but is implausible
332 ; from inner, so the call @f() in inner's copy of merge should be
333 ; rewritten to call @f()
334 ; CHECK-LABEL: define void @test11()
335 ; CHECK:      %inner = cleanuppad within %outer []
336 ; CHECK-NEXT: call void @llvm.bar()
337 ; CHECK-NEXT: unreachable
338
339 define void @test12() personality i32 (...)* @__CxxFrameHandler3 !dbg !5 {
340 entry:
341   invoke void @f()
342     to label %cont unwind label %left, !dbg !8
343 cont:
344   invoke void @f()
345     to label %exit unwind label %right
346 left:
347   cleanuppad within none []
348   br label %join
349 right:
350   cleanuppad within none []
351   br label %join
352 join:
353   ; This call will get cloned; make sure we can handle cloning
354   ; instructions with debug metadata attached.
355   call void @llvm.bar(), !dbg !9
356   unreachable
357 exit:
358   ret void
359 }
360
361 ; CHECK-LABEL: define void @test13()
362 ; CHECK: ret void
363 define void @test13() personality i32 (...)* @__CxxFrameHandler3 {
364 entry:
365   ret void
366
367 unreachable:
368   cleanuppad within none []
369   unreachable
370 }
371
372 ;; Debug info (from test12)
373
374 ; Make sure the DISubprogram doesn't get cloned
375 ; CHECK-LABEL: !llvm.module.flags
376 ; CHECK-NOT: !DISubprogram
377 ; CHECK: !{{[0-9]+}} = distinct !DISubprogram(name: "test12"
378 ; CHECK-NOT: !DISubprogram
379 !llvm.module.flags = !{!0}
380 !llvm.dbg.cu = !{!1}
381
382 !0 = !{i32 2, !"Debug Info Version", i32 3}
383 !1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "compiler", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !3, subprograms: !4)
384 !2 = !DIFile(filename: "test.cpp", directory: ".")
385 !3 = !{}
386 !4 = !{!5}
387 !5 = distinct !DISubprogram(name: "test12", scope: !2, file: !2, type: !6, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, variables: !3)
388 !6 = !DISubroutineType(types: !7)
389 !7 = !{null}
390 !8 = !DILocation(line: 1, scope: !5)
391 !9 = !DILocation(line: 2, scope: !5)