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