blob: 86984c7b5db8c37aeb6b7137d94030e2f7936a00 [file] [log] [blame]
David Majnemer8a1c45d2015-12-12 05:38:55 +00001; RUN: opt -mtriple=x86_64-pc-windows-msvc -S -winehprepare < %s | FileCheck %s
Joseph Tremouletec182852015-08-28 01:12:35 +00002
3declare i32 @__CxxFrameHandler3(...)
David Majnemer8a1c45d2015-12-12 05:38:55 +00004declare i32 @__C_specific_handler(...)
Joseph Tremoulet71e56762016-01-02 15:22:36 +00005declare void @ProcessCLRException(...)
Joseph Tremouletec182852015-08-28 01:12:35 +00006
7declare void @f()
Joseph Tremouletec182852015-08-28 01:12:35 +00008
David Majnemer3bb88c02015-12-15 21:27:27 +00009declare void @llvm.foo(i32) nounwind
10declare void @llvm.bar() nounwind
11declare i32 @llvm.qux() nounwind
12declare i1 @llvm.baz() nounwind
Joseph Tremouletec182852015-08-28 01:12:35 +000013
14define void @test1() personality i32 (...)* @__CxxFrameHandler3 {
15entry:
16 ; %x def colors: {entry} subset of use colors; must spill
David Majnemer3bb88c02015-12-15 21:27:27 +000017 %x = call i32 @llvm.qux()
Joseph Tremouletec182852015-08-28 01:12:35 +000018 invoke void @f()
David Majnemer8a1c45d2015-12-12 05:38:55 +000019 to label %noreturn unwind label %catch.switch
20catch.switch:
21 %cs = catchswitch within none [label %catch] unwind to caller
Joseph Tremouletec182852015-08-28 01:12:35 +000022catch:
David Majnemer3bb88c02015-12-15 21:27:27 +000023 %cp = catchpad within %cs []
David Majnemer8a1c45d2015-12-12 05:38:55 +000024 br label %noreturn
Joseph Tremouletec182852015-08-28 01:12:35 +000025noreturn:
26 ; %x use colors: {entry, cleanup}
David Majnemer3bb88c02015-12-15 21:27:27 +000027 call void @llvm.foo(i32 %x)
Joseph Tremouletec182852015-08-28 01:12:35 +000028 unreachable
Joseph Tremouletec182852015-08-28 01:12:35 +000029}
30; Need two copies of the call to @h, one under entry and one under catch.
31; Currently we generate a load for each, though we shouldn't need one
32; for the use in entry's copy.
Joseph Tremouletf3aff312015-09-10 16:51:25 +000033; CHECK-LABEL: define void @test1(
Joseph Tremouletec182852015-08-28 01:12:35 +000034; CHECK: entry:
David Majnemer3bb88c02015-12-15 21:27:27 +000035; CHECK: %x = call i32 @llvm.qux()
Joseph Tremouletec182852015-08-28 01:12:35 +000036; CHECK: invoke void @f()
37; CHECK: to label %[[EntryCopy:[^ ]+]] unwind label %catch
David Majnemer8a1c45d2015-12-12 05:38:55 +000038; CHECK: catch.switch:
39; CHECK: %cs = catchswitch within none [label %catch] unwind to caller
Joseph Tremouletec182852015-08-28 01:12:35 +000040; CHECK: catch:
David Majnemer8a1c45d2015-12-12 05:38:55 +000041; CHECK: catchpad within %cs []
David Majnemer3bb88c02015-12-15 21:27:27 +000042; CHECK-NEXT: call void @llvm.foo(i32 %x)
Joseph Tremouletec182852015-08-28 01:12:35 +000043; CHECK: [[EntryCopy]]:
David Majnemer3bb88c02015-12-15 21:27:27 +000044; CHECK: call void @llvm.foo(i32 %x)
Joseph Tremouletec182852015-08-28 01:12:35 +000045
46
David Majnemer784d4a42016-02-01 03:29:38 +000047define void @test2() personality i32 (...)* @__CxxFrameHandler3 {
Joseph Tremouletec182852015-08-28 01:12:35 +000048entry:
49 invoke void @f()
50 to label %exit unwind label %cleanup
51cleanup:
David Majnemer8a1c45d2015-12-12 05:38:55 +000052 cleanuppad within none []
Joseph Tremouletec182852015-08-28 01:12:35 +000053 br label %exit
54exit:
David Majnemer3bb88c02015-12-15 21:27:27 +000055 call void @llvm.bar()
Joseph Tremouletec182852015-08-28 01:12:35 +000056 ret void
57}
58; Need two copies of %exit's call to @f -- the subsequent ret is only
59; valid when coming from %entry, but on the path from %cleanup, this
60; might be a valid call to @f which might dynamically not return.
Joseph Tremouletf3aff312015-09-10 16:51:25 +000061; CHECK-LABEL: define void @test2(
Joseph Tremouletec182852015-08-28 01:12:35 +000062; CHECK: entry:
63; CHECK: invoke void @f()
64; CHECK: to label %[[exit:[^ ]+]] unwind label %cleanup
65; CHECK: cleanup:
David Majnemer8a1c45d2015-12-12 05:38:55 +000066; CHECK: cleanuppad within none []
David Majnemer3bb88c02015-12-15 21:27:27 +000067; CHECK: call void @llvm.bar()
Joseph Tremouletec182852015-08-28 01:12:35 +000068; CHECK-NEXT: unreachable
69; CHECK: [[exit]]:
David Majnemer3bb88c02015-12-15 21:27:27 +000070; CHECK: call void @llvm.bar()
Joseph Tremouletec182852015-08-28 01:12:35 +000071; CHECK-NEXT: ret void
72
73
David Majnemer784d4a42016-02-01 03:29:38 +000074define void @test3() personality i32 (...)* @__CxxFrameHandler3 {
Joseph Tremouletec182852015-08-28 01:12:35 +000075entry:
76 invoke void @f()
David Majnemer8a1c45d2015-12-12 05:38:55 +000077 to label %invoke.cont unwind label %catch.switch
Joseph Tremouletec182852015-08-28 01:12:35 +000078invoke.cont:
79 invoke void @f()
80 to label %exit unwind label %cleanup
David Majnemer8a1c45d2015-12-12 05:38:55 +000081catch.switch:
82 %cs = catchswitch within none [label %catch] unwind to caller
Joseph Tremouletec182852015-08-28 01:12:35 +000083catch:
David Majnemer8a1c45d2015-12-12 05:38:55 +000084 catchpad within %cs []
85 br label %shared
Joseph Tremouletec182852015-08-28 01:12:35 +000086cleanup:
David Majnemer8a1c45d2015-12-12 05:38:55 +000087 cleanuppad within none []
Joseph Tremouletec182852015-08-28 01:12:35 +000088 br label %shared
89shared:
David Majnemer3bb88c02015-12-15 21:27:27 +000090 call void @llvm.bar()
Joseph Tremouletec182852015-08-28 01:12:35 +000091 br label %exit
92exit:
93 ret void
94}
95; Need two copies of %shared's call to @f (similar to @test2 but
96; the two regions here are siblings, not parent-child).
Joseph Tremouletf3aff312015-09-10 16:51:25 +000097; CHECK-LABEL: define void @test3(
Joseph Tremouletec182852015-08-28 01:12:35 +000098; CHECK: invoke void @f()
99; CHECK: invoke void @f()
100; CHECK: to label %[[exit:[^ ]+]] unwind
101; CHECK: catch:
David Majnemer8a1c45d2015-12-12 05:38:55 +0000102; CHECK: catchpad within %cs []
David Majnemer3bb88c02015-12-15 21:27:27 +0000103; CHECK-NEXT: call void @llvm.bar()
Joseph Tremouletec182852015-08-28 01:12:35 +0000104; CHECK-NEXT: unreachable
David Majnemer8a1c45d2015-12-12 05:38:55 +0000105; CHECK: cleanup:
106; CHECK: cleanuppad within none []
David Majnemer3bb88c02015-12-15 21:27:27 +0000107; CHECK: call void @llvm.bar()
Joseph Tremouletec182852015-08-28 01:12:35 +0000108; CHECK-NEXT: unreachable
109; CHECK: [[exit]]:
110; CHECK: ret void
111
112
113define void @test4() personality i32 (...)* @__CxxFrameHandler3 {
114entry:
115 invoke void @f()
David Majnemer8a1c45d2015-12-12 05:38:55 +0000116 to label %shared unwind label %catch.switch
117catch.switch:
118 %cs = catchswitch within none [label %catch] unwind to caller
Joseph Tremouletec182852015-08-28 01:12:35 +0000119catch:
David Majnemer8a1c45d2015-12-12 05:38:55 +0000120 catchpad within %cs []
121 br label %shared
Joseph Tremouletec182852015-08-28 01:12:35 +0000122shared:
David Majnemer3bb88c02015-12-15 21:27:27 +0000123 %x = call i32 @llvm.qux()
124 %i = call i32 @llvm.qux()
Joseph Tremouletec182852015-08-28 01:12:35 +0000125 %zero.trip = icmp eq i32 %i, 0
126 br i1 %zero.trip, label %exit, label %loop
127loop:
128 %i.loop = phi i32 [ %i, %shared ], [ %i.dec, %loop.tail ]
David Majnemer3bb88c02015-12-15 21:27:27 +0000129 %b = call i1 @llvm.baz()
Joseph Tremouletec182852015-08-28 01:12:35 +0000130 br i1 %b, label %left, label %right
131left:
David Majnemer3bb88c02015-12-15 21:27:27 +0000132 %y = call i32 @llvm.qux()
Joseph Tremouletec182852015-08-28 01:12:35 +0000133 br label %loop.tail
134right:
David Majnemer3bb88c02015-12-15 21:27:27 +0000135 call void @llvm.foo(i32 %x)
Joseph Tremouletec182852015-08-28 01:12:35 +0000136 br label %loop.tail
137loop.tail:
138 %i.dec = sub i32 %i.loop, 1
139 %done = icmp eq i32 %i.dec, 0
140 br i1 %done, label %exit, label %loop
141exit:
David Majnemer3bb88c02015-12-15 21:27:27 +0000142 call void @llvm.foo(i32 %x)
Joseph Tremouletec182852015-08-28 01:12:35 +0000143 unreachable
144}
145; Make sure we can clone regions that have internal control
146; flow and SSA values. Here we need two copies of everything
147; from %shared to %exit.
Joseph Tremouletf3aff312015-09-10 16:51:25 +0000148; CHECK-LABEL: define void @test4(
Joseph Tremouletec182852015-08-28 01:12:35 +0000149; CHECK: entry:
David Majnemer8a1c45d2015-12-12 05:38:55 +0000150; CHECK: to label %[[shared_E:[^ ]+]] unwind label %catch.switch
Joseph Tremouletec182852015-08-28 01:12:35 +0000151; CHECK: catch:
David Majnemer8a1c45d2015-12-12 05:38:55 +0000152; CHECK: catchpad within %cs []
David Majnemer3bb88c02015-12-15 21:27:27 +0000153; CHECK: [[x_C:%[^ ]+]] = call i32 @llvm.qux()
154; CHECK: [[i_C:%[^ ]+]] = call i32 @llvm.qux()
Joseph Tremouletec182852015-08-28 01:12:35 +0000155; CHECK: [[zt_C:%[^ ]+]] = icmp eq i32 [[i_C]], 0
156; CHECK: br i1 [[zt_C]], label %[[exit_C:[^ ]+]], label %[[loop_C:[^ ]+]]
157; CHECK: [[shared_E]]:
David Majnemer3bb88c02015-12-15 21:27:27 +0000158; CHECK: [[x_E:%[^ ]+]] = call i32 @llvm.qux()
159; CHECK: [[i_E:%[^ ]+]] = call i32 @llvm.qux()
Joseph Tremouletec182852015-08-28 01:12:35 +0000160; CHECK: [[zt_E:%[^ ]+]] = icmp eq i32 [[i_E]], 0
161; CHECK: br i1 [[zt_E]], label %[[exit_E:[^ ]+]], label %[[loop_E:[^ ]+]]
162; CHECK: [[loop_C]]:
David Majnemer8a1c45d2015-12-12 05:38:55 +0000163; CHECK: [[iloop_C:%[^ ]+]] = phi i32 [ [[i_C]], %catch ], [ [[idec_C:%[^ ]+]], %[[looptail_C:[^ ]+]] ]
David Majnemer3bb88c02015-12-15 21:27:27 +0000164; CHECK: [[b_C:%[^ ]+]] = call i1 @llvm.baz()
Joseph Tremouletec182852015-08-28 01:12:35 +0000165; CHECK: br i1 [[b_C]], label %[[left_C:[^ ]+]], label %[[right_C:[^ ]+]]
166; CHECK: [[loop_E]]:
167; CHECK: [[iloop_E:%[^ ]+]] = phi i32 [ [[i_E]], %[[shared_E]] ], [ [[idec_E:%[^ ]+]], %[[looptail_E:[^ ]+]] ]
David Majnemer3bb88c02015-12-15 21:27:27 +0000168; CHECK: [[b_E:%[^ ]+]] = call i1 @llvm.baz()
Joseph Tremouletec182852015-08-28 01:12:35 +0000169; CHECK: br i1 [[b_E]], label %[[left_E:[^ ]+]], label %[[right_E:[^ ]+]]
170; CHECK: [[left_C]]:
David Majnemer3bb88c02015-12-15 21:27:27 +0000171; CHECK: [[y_C:%[^ ]+]] = call i32 @llvm.qux()
Hans Wennborg4a613702015-08-31 21:10:35 +0000172; CHECK: br label %[[looptail_C]]
Joseph Tremouletec182852015-08-28 01:12:35 +0000173; CHECK: [[left_E]]:
David Majnemer3bb88c02015-12-15 21:27:27 +0000174; CHECK: [[y_E:%[^ ]+]] = call i32 @llvm.qux()
Hans Wennborg4a613702015-08-31 21:10:35 +0000175; CHECK: br label %[[looptail_E]]
Joseph Tremouletec182852015-08-28 01:12:35 +0000176; CHECK: [[right_C]]:
David Majnemer3bb88c02015-12-15 21:27:27 +0000177; CHECK: call void @llvm.foo(i32 [[x_C]])
Joseph Tremouletec182852015-08-28 01:12:35 +0000178; CHECK: br label %[[looptail_C]]
179; CHECK: [[right_E]]:
David Majnemer3bb88c02015-12-15 21:27:27 +0000180; CHECK: call void @llvm.foo(i32 [[x_E]])
Joseph Tremouletec182852015-08-28 01:12:35 +0000181; CHECK: br label %[[looptail_E]]
182; CHECK: [[looptail_C]]:
183; CHECK: [[idec_C]] = sub i32 [[iloop_C]], 1
184; CHECK: [[done_C:%[^ ]+]] = icmp eq i32 [[idec_C]], 0
185; CHECK: br i1 [[done_C]], label %[[exit_C]], label %[[loop_C]]
186; CHECK: [[looptail_E]]:
187; CHECK: [[idec_E]] = sub i32 [[iloop_E]], 1
188; CHECK: [[done_E:%[^ ]+]] = icmp eq i32 [[idec_E]], 0
189; CHECK: br i1 [[done_E]], label %[[exit_E]], label %[[loop_E]]
190; CHECK: [[exit_C]]:
David Majnemer3bb88c02015-12-15 21:27:27 +0000191; CHECK: call void @llvm.foo(i32 [[x_C]])
Joseph Tremouletec182852015-08-28 01:12:35 +0000192; CHECK: unreachable
193; CHECK: [[exit_E]]:
David Majnemer3bb88c02015-12-15 21:27:27 +0000194; CHECK: call void @llvm.foo(i32 [[x_E]])
Joseph Tremouletec182852015-08-28 01:12:35 +0000195; CHECK: unreachable
196
197
David Majnemer8a1c45d2015-12-12 05:38:55 +0000198define void @test5() personality i32 (...)* @__C_specific_handler {
Joseph Tremouletec182852015-08-28 01:12:35 +0000199entry:
200 invoke void @f()
201 to label %exit unwind label %outer
202outer:
David Majnemer8a1c45d2015-12-12 05:38:55 +0000203 %o = cleanuppad within none []
David Majnemer3bb88c02015-12-15 21:27:27 +0000204 %x = call i32 @llvm.qux()
205 invoke void @f() [ "funclet"(token %o) ]
David Majnemer8a1c45d2015-12-12 05:38:55 +0000206 to label %outer.ret unwind label %catch.switch
207catch.switch:
208 %cs = catchswitch within %o [label %inner] unwind to caller
Joseph Tremouletec182852015-08-28 01:12:35 +0000209inner:
David Majnemer8a1c45d2015-12-12 05:38:55 +0000210 %i = catchpad within %cs []
211 catchret from %i to label %outer.post-inner
Joseph Tremouletec182852015-08-28 01:12:35 +0000212outer.post-inner:
David Majnemer3bb88c02015-12-15 21:27:27 +0000213 call void @llvm.foo(i32 %x)
Joseph Tremouletec182852015-08-28 01:12:35 +0000214 br label %outer.ret
215outer.ret:
David Majnemer8a1c45d2015-12-12 05:38:55 +0000216 cleanupret from %o unwind to caller
Joseph Tremouletec182852015-08-28 01:12:35 +0000217exit:
218 ret void
219}
220; Simple nested case (catch-inside-cleanup). Nothing needs
221; to be cloned. The def and use of %x are both in %outer
222; and so don't need to be spilled.
Joseph Tremouletf3aff312015-09-10 16:51:25 +0000223; CHECK-LABEL: define void @test5(
Joseph Tremouletec182852015-08-28 01:12:35 +0000224; CHECK: outer:
David Majnemer3bb88c02015-12-15 21:27:27 +0000225; CHECK: %x = call i32 @llvm.qux()
Joseph Tremouletec182852015-08-28 01:12:35 +0000226; CHECK-NEXT: invoke void @f()
David Majnemer8a1c45d2015-12-12 05:38:55 +0000227; CHECK-NEXT: to label %outer.ret unwind label %catch.switch
Joseph Tremouletec182852015-08-28 01:12:35 +0000228; CHECK: inner:
David Majnemer8a1c45d2015-12-12 05:38:55 +0000229; CHECK-NEXT: %i = catchpad within %cs []
230; CHECK-NEXT: catchret from %i to label %outer.post-inner
Joseph Tremouletec182852015-08-28 01:12:35 +0000231; CHECK: outer.post-inner:
David Majnemer3bb88c02015-12-15 21:27:27 +0000232; CHECK-NEXT: call void @llvm.foo(i32 %x)
Joseph Tremouletec182852015-08-28 01:12:35 +0000233; CHECK-NEXT: br label %outer.ret
234
235
Joseph Tremouletf3aff312015-09-10 16:51:25 +0000236define void @test10() personality i32 (...)* @__CxxFrameHandler3 {
237entry:
238 invoke void @f()
239 to label %unreachable unwind label %inner
240inner:
David Majnemer8a1c45d2015-12-12 05:38:55 +0000241 %cleanup = cleanuppad within none []
Joseph Tremouletf3aff312015-09-10 16:51:25 +0000242 ; make sure we don't overlook this cleanupret and try to process
243 ; successor %outer as a child of inner.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000244 cleanupret from %cleanup unwind label %outer
Joseph Tremouletf3aff312015-09-10 16:51:25 +0000245outer:
David Majnemer8a1c45d2015-12-12 05:38:55 +0000246 %cs = catchswitch within none [label %catch.body] unwind to caller
247
Joseph Tremouletf3aff312015-09-10 16:51:25 +0000248catch.body:
David Majnemer8a1c45d2015-12-12 05:38:55 +0000249 %catch = catchpad within %cs []
250 catchret from %catch to label %exit
Joseph Tremouletf3aff312015-09-10 16:51:25 +0000251exit:
252 ret void
253unreachable:
254 unreachable
255}
256; CHECK-LABEL: define void @test10(
257; CHECK-NEXT: entry:
258; CHECK-NEXT: invoke
259; CHECK-NEXT: to label %unreachable unwind label %inner
260; CHECK: inner:
David Majnemer8a1c45d2015-12-12 05:38:55 +0000261; CHECK-NEXT: %cleanup = cleanuppad within none []
262; CHECK-NEXT: cleanupret from %cleanup unwind label %outer
Joseph Tremouletf3aff312015-09-10 16:51:25 +0000263; CHECK: outer:
David Majnemer8a1c45d2015-12-12 05:38:55 +0000264; CHECK-NEXT: %cs = catchswitch within none [label %catch.body] unwind to caller
Joseph Tremouletf3aff312015-09-10 16:51:25 +0000265; CHECK: catch.body:
David Majnemer8a1c45d2015-12-12 05:38:55 +0000266; CHECK-NEXT: %catch = catchpad within %cs []
267; CHECK-NEXT: catchret from %catch to label %exit
Joseph Tremouletf3aff312015-09-10 16:51:25 +0000268; CHECK: exit:
269; CHECK-NEXT: ret void
Joseph Tremoulet09af67a2015-09-27 01:47:46 +0000270
David Majnemer8a1c45d2015-12-12 05:38:55 +0000271define void @test11() personality i32 (...)* @__C_specific_handler {
Joseph Tremoulet09af67a2015-09-27 01:47:46 +0000272entry:
273 invoke void @f()
274 to label %exit unwind label %cleanup.outer
275cleanup.outer:
David Majnemer8a1c45d2015-12-12 05:38:55 +0000276 %outer = cleanuppad within none []
David Majnemer3bb88c02015-12-15 21:27:27 +0000277 invoke void @f() [ "funclet"(token %outer) ]
Joseph Tremoulet09af67a2015-09-27 01:47:46 +0000278 to label %outer.cont unwind label %cleanup.inner
279outer.cont:
280 br label %merge
281cleanup.inner:
David Majnemer8a1c45d2015-12-12 05:38:55 +0000282 %inner = cleanuppad within %outer []
Joseph Tremoulet09af67a2015-09-27 01:47:46 +0000283 br label %merge
284merge:
David Majnemer3bb88c02015-12-15 21:27:27 +0000285 call void @llvm.bar()
Joseph Tremoulet09af67a2015-09-27 01:47:46 +0000286 unreachable
Joseph Tremoulet09af67a2015-09-27 01:47:46 +0000287exit:
288 ret void
289}
290; merge.end will get cloned for outer and inner, but is implausible
David Majnemer8a1c45d2015-12-12 05:38:55 +0000291; from inner, so the call @f() in inner's copy of merge should be
Joseph Tremoulet09af67a2015-09-27 01:47:46 +0000292; rewritten to call @f()
293; CHECK-LABEL: define void @test11()
David Majnemer8a1c45d2015-12-12 05:38:55 +0000294; CHECK: %inner = cleanuppad within %outer []
David Majnemer3bb88c02015-12-15 21:27:27 +0000295; CHECK-NEXT: call void @llvm.bar()
Joseph Tremoulet09af67a2015-09-27 01:47:46 +0000296; CHECK-NEXT: unreachable
Joseph Tremoulet39234fc2015-10-07 19:29:56 +0000297
Peter Collingbourned4bff302015-11-05 22:03:56 +0000298define void @test12() personality i32 (...)* @__CxxFrameHandler3 !dbg !5 {
Joseph Tremoulet39234fc2015-10-07 19:29:56 +0000299entry:
300 invoke void @f()
301 to label %cont unwind label %left, !dbg !8
302cont:
303 invoke void @f()
304 to label %exit unwind label %right
305left:
David Majnemer8a1c45d2015-12-12 05:38:55 +0000306 cleanuppad within none []
Joseph Tremoulet39234fc2015-10-07 19:29:56 +0000307 br label %join
308right:
David Majnemer8a1c45d2015-12-12 05:38:55 +0000309 cleanuppad within none []
Joseph Tremoulet39234fc2015-10-07 19:29:56 +0000310 br label %join
311join:
312 ; This call will get cloned; make sure we can handle cloning
313 ; instructions with debug metadata attached.
David Majnemer3bb88c02015-12-15 21:27:27 +0000314 call void @llvm.bar(), !dbg !9
Joseph Tremoulet39234fc2015-10-07 19:29:56 +0000315 unreachable
316exit:
317 ret void
318}
319
David Majnemerc289c9f2015-10-07 21:08:25 +0000320; CHECK-LABEL: define void @test13()
321; CHECK: ret void
322define void @test13() personality i32 (...)* @__CxxFrameHandler3 {
323entry:
324 ret void
325
326unreachable:
David Majnemer8a1c45d2015-12-12 05:38:55 +0000327 cleanuppad within none []
David Majnemerc289c9f2015-10-07 21:08:25 +0000328 unreachable
329}
330
Joseph Tremoulet71e56762016-01-02 15:22:36 +0000331define void @test14() personality void (...)* @ProcessCLRException {
332entry:
333 invoke void @f()
334 to label %cont unwind label %cleanup
335cont:
336 invoke void @f()
337 to label %exit unwind label %switch.outer
338cleanup:
339 %cleanpad = cleanuppad within none []
340 invoke void @f() [ "funclet" (token %cleanpad) ]
341 to label %cleanret unwind label %switch.inner
342switch.inner:
343 %cs.inner = catchswitch within %cleanpad [label %pad.inner] unwind to caller
344pad.inner:
345 %cp.inner = catchpad within %cs.inner [i32 1]
346 catchret from %cp.inner to label %join
347cleanret:
348 cleanupret from %cleanpad unwind to caller
349switch.outer:
350 %cs.outer = catchswitch within none [label %pad.outer] unwind to caller
351pad.outer:
352 %cp.outer = catchpad within %cs.outer [i32 2]
353 catchret from %cp.outer to label %join
354join:
355 %phi = phi i32 [ 1, %pad.inner ], [ 2, %pad.outer ]
356 call void @llvm.foo(i32 %phi)
357 unreachable
358exit:
359 ret void
360}
361; Both catchrets target %join, but the catchret from %cp.inner
362; returns to %cleanpad and the catchret from %cp.outer returns to the
363; main function, so %join needs to get cloned and one of the cleanuprets
364; needs to be updated to target the clone
365; CHECK-LABEL: define void @test14()
366; CHECK: catchret from %cp.inner to label %[[Clone1:.+]]
367; CHECK: catchret from %cp.outer to label %[[Clone2:.+]]
368; CHECK: [[Clone1]]:
369; CHECK-NEXT: call void @llvm.foo(i32 1)
370; CHECK-NEXT: unreachable
371; CHECK: [[Clone2]]:
372; CHECK-NEXT: call void @llvm.foo(i32 2)
373; CHECK-NEXT: unreachable
374
Joseph Tremoulet53e9cbd2015-10-16 18:08:16 +0000375;; Debug info (from test12)
376
Joseph Tremoulet39234fc2015-10-07 19:29:56 +0000377; Make sure the DISubprogram doesn't get cloned
378; CHECK-LABEL: !llvm.module.flags
379; CHECK-NOT: !DISubprogram
380; CHECK: !{{[0-9]+}} = distinct !DISubprogram(name: "test12"
381; CHECK-NOT: !DISubprogram
382!llvm.module.flags = !{!0}
383!llvm.dbg.cu = !{!1}
384
385!0 = !{i32 2, !"Debug Info Version", i32 3}
Adrian Prantl75819ae2016-04-15 15:57:41 +0000386!1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !3)
Joseph Tremoulet39234fc2015-10-07 19:29:56 +0000387!2 = !DIFile(filename: "test.cpp", directory: ".")
388!3 = !{}
Adrian Prantl75819ae2016-04-15 15:57:41 +0000389!5 = distinct !DISubprogram(name: "test12", scope: !2, file: !2, type: !6, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !1, variables: !3)
Joseph Tremoulet39234fc2015-10-07 19:29:56 +0000390!6 = !DISubroutineType(types: !7)
391!7 = !{null}
392!8 = !DILocation(line: 1, scope: !5)
393!9 = !DILocation(line: 2, scope: !5)