xref: /aosp_15_r20/external/llvm/test/CodeGen/WinEH/wineh-demotion.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 Worker
5*9880d681SAndroid Build Coastguard Workerdeclare void @f()
6*9880d681SAndroid Build Coastguard Worker
7*9880d681SAndroid Build Coastguard Workerdeclare i32 @g()
8*9880d681SAndroid Build Coastguard Worker
9*9880d681SAndroid Build Coastguard Workerdeclare void @h(i32)
10*9880d681SAndroid Build Coastguard Worker
11*9880d681SAndroid Build Coastguard Workerdeclare i1 @i()
12*9880d681SAndroid Build Coastguard Worker
13*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.bar() nounwind
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test1(
16*9880d681SAndroid Build Coastguard Workerdefine void @test1(i1 %B) personality i32 (...)* @__CxxFrameHandler3 {
17*9880d681SAndroid Build Coastguard Workerentry:
18*9880d681SAndroid Build Coastguard Worker  ; Spill slot should be inserted here
19*9880d681SAndroid Build Coastguard Worker  ; CHECK: [[Slot:%[^ ]+]] = alloca
20*9880d681SAndroid Build Coastguard Worker  ; Can't store for %phi at these defs because the lifetimes overlap
21*9880d681SAndroid Build Coastguard Worker  ; CHECK-NOT: store
22*9880d681SAndroid Build Coastguard Worker  %x = call i32 @g()
23*9880d681SAndroid Build Coastguard Worker  %y = call i32 @g()
24*9880d681SAndroid Build Coastguard Worker  br i1 %B, label %left, label %right
25*9880d681SAndroid Build Coastguard Workerleft:
26*9880d681SAndroid Build Coastguard Worker  ; CHECK: left:
27*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: store i32 %x, i32* [[Slot]]
28*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: invoke void @f
29*9880d681SAndroid Build Coastguard Worker  invoke void @f()
30*9880d681SAndroid Build Coastguard Worker          to label %exit unwind label %merge
31*9880d681SAndroid Build Coastguard Workerright:
32*9880d681SAndroid Build Coastguard Worker  ; CHECK: right:
33*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: store i32 %y, i32* [[Slot]]
34*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: invoke void @f
35*9880d681SAndroid Build Coastguard Worker  invoke void @f()
36*9880d681SAndroid Build Coastguard Worker          to label %exit unwind label %merge
37*9880d681SAndroid Build Coastguard Workermerge:
38*9880d681SAndroid Build Coastguard Worker  ; CHECK: merge:
39*9880d681SAndroid Build Coastguard Worker  ; CHECK-NOT: = phi
40*9880d681SAndroid Build Coastguard Worker  %phi = phi i32 [ %x, %left ], [ %y, %right ]
41*9880d681SAndroid Build Coastguard Worker  %cs1 = catchswitch within none [label %catch] unwind to caller
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Workercatch:
44*9880d681SAndroid Build Coastguard Worker  %cp = catchpad within %cs1 []
45*9880d681SAndroid Build Coastguard Worker  ; CHECK: catch:
46*9880d681SAndroid Build Coastguard Worker  ; CHECK: [[Reload:%[^ ]+]] = load i32, i32* [[Slot]]
47*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: call void @h(i32 [[Reload]])
48*9880d681SAndroid Build Coastguard Worker  call void @h(i32 %phi) [ "funclet"(token %cp) ]
49*9880d681SAndroid Build Coastguard Worker  catchret from %cp to label %exit
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Workerexit:
52*9880d681SAndroid Build Coastguard Worker  ret void
53*9880d681SAndroid Build Coastguard Worker}
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2(
56*9880d681SAndroid Build Coastguard Workerdefine void @test2(i1 %B) personality i32 (...)* @__CxxFrameHandler3 {
57*9880d681SAndroid Build Coastguard Workerentry:
58*9880d681SAndroid Build Coastguard Worker  br i1 %B, label %left, label %right
59*9880d681SAndroid Build Coastguard Workerleft:
60*9880d681SAndroid Build Coastguard Worker  ; Need two stores here because %x and %y interfere so they need 2 slots
61*9880d681SAndroid Build Coastguard Worker  ; CHECK: left:
62*9880d681SAndroid Build Coastguard Worker  ; CHECK:   store i32 1, i32* [[Slot1:%[^ ]+]]
63*9880d681SAndroid Build Coastguard Worker  ; CHECK:   store i32 1, i32* [[Slot2:%[^ ]+]]
64*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: invoke void @f
65*9880d681SAndroid Build Coastguard Worker  invoke void @f()
66*9880d681SAndroid Build Coastguard Worker          to label %exit unwind label %merge.inner
67*9880d681SAndroid Build Coastguard Workerright:
68*9880d681SAndroid Build Coastguard Worker  ; Need two stores here because %x and %y interfere so they need 2 slots
69*9880d681SAndroid Build Coastguard Worker  ; CHECK: right:
70*9880d681SAndroid Build Coastguard Worker  ; CHECK-DAG:   store i32 2, i32* [[Slot1]]
71*9880d681SAndroid Build Coastguard Worker  ; CHECK-DAG:   store i32 2, i32* [[Slot2]]
72*9880d681SAndroid Build Coastguard Worker  ; CHECK: invoke void @f
73*9880d681SAndroid Build Coastguard Worker  invoke void @f()
74*9880d681SAndroid Build Coastguard Worker          to label %exit unwind label %merge.inner
75*9880d681SAndroid Build Coastguard Workermerge.inner:
76*9880d681SAndroid Build Coastguard Worker  ; CHECK: merge.inner:
77*9880d681SAndroid Build Coastguard Worker  ; CHECK-NOT: = phi
78*9880d681SAndroid Build Coastguard Worker  ; CHECK: catchswitch within none
79*9880d681SAndroid Build Coastguard Worker  %x = phi i32 [ 1, %left ], [ 2, %right ]
80*9880d681SAndroid Build Coastguard Worker  %cs1 = catchswitch within none [label %catch.inner] unwind label %merge.outer
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Workercatch.inner:
83*9880d681SAndroid Build Coastguard Worker  %cpinner = catchpad within %cs1 []
84*9880d681SAndroid Build Coastguard Worker  ; Need just one store here because only %y is affected
85*9880d681SAndroid Build Coastguard Worker  ; CHECK: catch.inner:
86*9880d681SAndroid Build Coastguard Worker  %z = call i32 @g() [ "funclet"(token %cpinner) ]
87*9880d681SAndroid Build Coastguard Worker  ; CHECK:   store i32 %z
88*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: invoke void @f
89*9880d681SAndroid Build Coastguard Worker  invoke void @f() [ "funclet"(token %cpinner) ]
90*9880d681SAndroid Build Coastguard Worker          to label %catchret.inner unwind label %merge.outer
91*9880d681SAndroid Build Coastguard Worker
92*9880d681SAndroid Build Coastguard Workercatchret.inner:
93*9880d681SAndroid Build Coastguard Worker  catchret from %cpinner to label %exit
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Workermerge.outer:
96*9880d681SAndroid Build Coastguard Worker  %y = phi i32 [ %x, %merge.inner ], [ %z, %catch.inner ]
97*9880d681SAndroid Build Coastguard Worker  ; CHECK: merge.outer:
98*9880d681SAndroid Build Coastguard Worker  ; CHECK-NOT: = phi
99*9880d681SAndroid Build Coastguard Worker  ; CHECK: catchswitch within none
100*9880d681SAndroid Build Coastguard Worker  %cs2 = catchswitch within none [label %catch.outer] unwind to caller
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Workercatch.outer:
103*9880d681SAndroid Build Coastguard Worker  %cpouter = catchpad within %cs2 []
104*9880d681SAndroid Build Coastguard Worker  ; CHECK: catch.outer:
105*9880d681SAndroid Build Coastguard Worker  ; CHECK: [[CatchPad:%[^ ]+]] = catchpad within %cs2 []
106*9880d681SAndroid Build Coastguard Worker  ; Need to load x and y from two different slots since they're both live
107*9880d681SAndroid Build Coastguard Worker  ; and can have different values (if we came from catch.inner)
108*9880d681SAndroid Build Coastguard Worker  ; CHECK-DAG: load i32, i32* [[Slot1]]
109*9880d681SAndroid Build Coastguard Worker  ; CHECK-DAG: load i32, i32* [[Slot2]]
110*9880d681SAndroid Build Coastguard Worker  ; CHECK: catchret from [[CatchPad]] to label
111*9880d681SAndroid Build Coastguard Worker  call void @h(i32 %x) [ "funclet"(token %cpouter) ]
112*9880d681SAndroid Build Coastguard Worker  call void @h(i32 %y) [ "funclet"(token %cpouter) ]
113*9880d681SAndroid Build Coastguard Worker  catchret from %cpouter to label %exit
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Workerexit:
116*9880d681SAndroid Build Coastguard Worker  ret void
117*9880d681SAndroid Build Coastguard Worker}
118*9880d681SAndroid Build Coastguard Worker
119*9880d681SAndroid Build Coastguard Worker; test4: don't need stores for %phi.inner, as its only use is to feed %phi.outer
120*9880d681SAndroid Build Coastguard Worker;        %phi.outer needs stores in %left, %right, and %join
121*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test4(
122*9880d681SAndroid Build Coastguard Workerdefine void @test4(i1 %B) personality i32 (...)* @__CxxFrameHandler3 {
123*9880d681SAndroid Build Coastguard Workerentry:
124*9880d681SAndroid Build Coastguard Worker  ; CHECK:      entry:
125*9880d681SAndroid Build Coastguard Worker  ; CHECK:        [[Slot:%[^ ]+]] = alloca
126*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT:   br
127*9880d681SAndroid Build Coastguard Worker  br i1 %B, label %left, label %right
128*9880d681SAndroid Build Coastguard Workerleft:
129*9880d681SAndroid Build Coastguard Worker  ; CHECK: left:
130*9880d681SAndroid Build Coastguard Worker  ; CHECK-NOT: store
131*9880d681SAndroid Build Coastguard Worker  ; CHECK: store i32 %l, i32* [[Slot]]
132*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: invoke void @f
133*9880d681SAndroid Build Coastguard Worker  %l = call i32 @g()
134*9880d681SAndroid Build Coastguard Worker  invoke void @f()
135*9880d681SAndroid Build Coastguard Worker          to label %join unwind label %catchpad.inner
136*9880d681SAndroid Build Coastguard Workerright:
137*9880d681SAndroid Build Coastguard Worker  ; CHECK: right:
138*9880d681SAndroid Build Coastguard Worker  ; CHECK-NOT: store
139*9880d681SAndroid Build Coastguard Worker  ; CHECK: store i32 %r, i32* [[Slot]]
140*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: invoke void @f
141*9880d681SAndroid Build Coastguard Worker  %r = call i32 @g()
142*9880d681SAndroid Build Coastguard Worker  invoke void @f()
143*9880d681SAndroid Build Coastguard Worker          to label %join unwind label %catchpad.inner
144*9880d681SAndroid Build Coastguard Workercatchpad.inner:
145*9880d681SAndroid Build Coastguard Worker   ; CHECK: catchpad.inner:
146*9880d681SAndroid Build Coastguard Worker   ; CHECK-NEXT: catchswitch within none
147*9880d681SAndroid Build Coastguard Worker   %phi.inner = phi i32 [ %l, %left ], [ %r, %right ]
148*9880d681SAndroid Build Coastguard Worker   %cs1 = catchswitch within none [label %catch.inner] unwind label %catchpad.outer
149*9880d681SAndroid Build Coastguard Workercatch.inner:
150*9880d681SAndroid Build Coastguard Worker   %cp1 = catchpad within %cs1 []
151*9880d681SAndroid Build Coastguard Worker   catchret from %cp1 to label %join
152*9880d681SAndroid Build Coastguard Workerjoin:
153*9880d681SAndroid Build Coastguard Worker  ; CHECK: join:
154*9880d681SAndroid Build Coastguard Worker  ; CHECK-NOT: store
155*9880d681SAndroid Build Coastguard Worker  ; CHECK: store i32 %j, i32* [[Slot]]
156*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: invoke void @f
157*9880d681SAndroid Build Coastguard Worker   %j = call i32 @g()
158*9880d681SAndroid Build Coastguard Worker   invoke void @f()
159*9880d681SAndroid Build Coastguard Worker           to label %exit unwind label %catchpad.outer
160*9880d681SAndroid Build Coastguard Worker
161*9880d681SAndroid Build Coastguard Workercatchpad.outer:
162*9880d681SAndroid Build Coastguard Worker   ; CHECK: catchpad.outer:
163*9880d681SAndroid Build Coastguard Worker   ; CHECK-NEXT: catchswitch within none
164*9880d681SAndroid Build Coastguard Worker   %phi.outer = phi i32 [ %phi.inner, %catchpad.inner ], [ %j, %join ]
165*9880d681SAndroid Build Coastguard Worker   %cs2 = catchswitch within none [label %catch.outer] unwind to caller
166*9880d681SAndroid Build Coastguard Workercatch.outer:
167*9880d681SAndroid Build Coastguard Worker   ; CHECK: catch.outer:
168*9880d681SAndroid Build Coastguard Worker   ; CHECK:   [[Reload:%[^ ]+]] = load i32, i32* [[Slot]]
169*9880d681SAndroid Build Coastguard Worker   ; CHECK:   call void @h(i32 [[Reload]])
170*9880d681SAndroid Build Coastguard Worker   %cp2 = catchpad within %cs2 []
171*9880d681SAndroid Build Coastguard Worker   call void @h(i32 %phi.outer) [ "funclet"(token %cp2) ]
172*9880d681SAndroid Build Coastguard Worker   catchret from %cp2 to label %exit
173*9880d681SAndroid Build Coastguard Workerexit:
174*9880d681SAndroid Build Coastguard Worker   ret void
175*9880d681SAndroid Build Coastguard Worker}
176*9880d681SAndroid Build Coastguard Worker
177*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test5(
178*9880d681SAndroid Build Coastguard Workerdefine void @test5() personality i32 (...)* @__CxxFrameHandler3 {
179*9880d681SAndroid Build Coastguard Workerentry:
180*9880d681SAndroid Build Coastguard Worker  ; need store for %phi.cleanup
181*9880d681SAndroid Build Coastguard Worker  ; CHECK:      entry:
182*9880d681SAndroid Build Coastguard Worker  ; CHECK:        store i32 1, i32* [[CleanupSlot:%[^ ]+]]
183*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT:   invoke void @f
184*9880d681SAndroid Build Coastguard Worker  invoke void @f()
185*9880d681SAndroid Build Coastguard Worker          to label %invoke.cont unwind label %cleanup
186*9880d681SAndroid Build Coastguard Worker
187*9880d681SAndroid Build Coastguard Workerinvoke.cont:
188*9880d681SAndroid Build Coastguard Worker  ; need store for %phi.cleanup
189*9880d681SAndroid Build Coastguard Worker  ; CHECK:      invoke.cont:
190*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT:   store i32 2, i32* [[CleanupSlot]]
191*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT:   invoke void @f
192*9880d681SAndroid Build Coastguard Worker  invoke void @f()
193*9880d681SAndroid Build Coastguard Worker          to label %invoke.cont2 unwind label %cleanup
194*9880d681SAndroid Build Coastguard Worker
195*9880d681SAndroid Build Coastguard Workercleanup:
196*9880d681SAndroid Build Coastguard Worker  ; cleanup phi can be loaded at cleanup entry
197*9880d681SAndroid Build Coastguard Worker  ; CHECK: cleanup:
198*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: cleanuppad within none []
199*9880d681SAndroid Build Coastguard Worker  ; CHECK: [[CleanupReload:%[^ ]+]] = load i32, i32* [[CleanupSlot]]
200*9880d681SAndroid Build Coastguard Worker  %phi.cleanup = phi i32 [ 1, %entry ], [ 2, %invoke.cont ]
201*9880d681SAndroid Build Coastguard Worker  %cp = cleanuppad within none []
202*9880d681SAndroid Build Coastguard Worker  %b = call i1 @i() [ "funclet"(token %cp) ]
203*9880d681SAndroid Build Coastguard Worker  br i1 %b, label %left, label %right
204*9880d681SAndroid Build Coastguard Worker
205*9880d681SAndroid Build Coastguard Workerleft:
206*9880d681SAndroid Build Coastguard Worker  ; CHECK: left:
207*9880d681SAndroid Build Coastguard Worker  ; CHECK:   call void @h(i32 [[CleanupReload]]
208*9880d681SAndroid Build Coastguard Worker  call void @h(i32 %phi.cleanup) [ "funclet"(token %cp) ]
209*9880d681SAndroid Build Coastguard Worker  br label %merge
210*9880d681SAndroid Build Coastguard Worker
211*9880d681SAndroid Build Coastguard Workerright:
212*9880d681SAndroid Build Coastguard Worker  ; CHECK: right:
213*9880d681SAndroid Build Coastguard Worker  ; CHECK:   call void @h(i32 [[CleanupReload]]
214*9880d681SAndroid Build Coastguard Worker  call void @h(i32 %phi.cleanup) [ "funclet"(token %cp) ]
215*9880d681SAndroid Build Coastguard Worker  br label %merge
216*9880d681SAndroid Build Coastguard Worker
217*9880d681SAndroid Build Coastguard Workermerge:
218*9880d681SAndroid Build Coastguard Worker  ; need store for %phi.catch
219*9880d681SAndroid Build Coastguard Worker  ; CHECK:      merge:
220*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT:   store i32 [[CleanupReload]], i32* [[CatchSlot:%[^ ]+]]
221*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT:   cleanupret
222*9880d681SAndroid Build Coastguard Worker  cleanupret from %cp unwind label %catchswitch
223*9880d681SAndroid Build Coastguard Worker
224*9880d681SAndroid Build Coastguard Workerinvoke.cont2:
225*9880d681SAndroid Build Coastguard Worker  ; need store for %phi.catch
226*9880d681SAndroid Build Coastguard Worker  ; CHECK:      invoke.cont2:
227*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT:   store i32 3, i32* [[CatchSlot]]
228*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT:   invoke void @f
229*9880d681SAndroid Build Coastguard Worker  invoke void @f()
230*9880d681SAndroid Build Coastguard Worker          to label %exit unwind label %catchswitch
231*9880d681SAndroid Build Coastguard Worker
232*9880d681SAndroid Build Coastguard Workercatchswitch:
233*9880d681SAndroid Build Coastguard Worker  ; CHECK: catchswitch:
234*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: catchswitch within none
235*9880d681SAndroid Build Coastguard Worker  %phi.catch = phi i32 [ %phi.cleanup, %merge ], [ 3, %invoke.cont2 ]
236*9880d681SAndroid Build Coastguard Worker  %cs1 = catchswitch within none [label %catch] unwind to caller
237*9880d681SAndroid Build Coastguard Worker
238*9880d681SAndroid Build Coastguard Workercatch:
239*9880d681SAndroid Build Coastguard Worker  ; CHECK: catch:
240*9880d681SAndroid Build Coastguard Worker  ; CHECK:   catchpad within %cs1
241*9880d681SAndroid Build Coastguard Worker  ; CHECK:   [[CatchReload:%[^ ]+]] = load i32, i32* [[CatchSlot]]
242*9880d681SAndroid Build Coastguard Worker  ; CHECK:   call void @h(i32 [[CatchReload]]
243*9880d681SAndroid Build Coastguard Worker  %cp2 = catchpad within %cs1 []
244*9880d681SAndroid Build Coastguard Worker  call void @h(i32 %phi.catch) [ "funclet"(token %cp2) ]
245*9880d681SAndroid Build Coastguard Worker  catchret from %cp2 to label %exit
246*9880d681SAndroid Build Coastguard Worker
247*9880d681SAndroid Build Coastguard Workerexit:
248*9880d681SAndroid Build Coastguard Worker  ret void
249*9880d681SAndroid Build Coastguard Worker}
250*9880d681SAndroid Build Coastguard Worker
251*9880d681SAndroid Build Coastguard Worker; We used to demote %x, but we don't need to anymore.
252*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test6(
253*9880d681SAndroid Build Coastguard Workerdefine void @test6() personality i32 (...)* @__CxxFrameHandler3 {
254*9880d681SAndroid Build Coastguard Workerentry:
255*9880d681SAndroid Build Coastguard Worker  ; CHECK: entry:
256*9880d681SAndroid Build Coastguard Worker  ; CHECK: %x = invoke i32 @g()
257*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: to label %loop unwind label %to_caller
258*9880d681SAndroid Build Coastguard Worker  %x = invoke i32 @g()
259*9880d681SAndroid Build Coastguard Worker          to label %loop unwind label %to_caller
260*9880d681SAndroid Build Coastguard Workerto_caller:
261*9880d681SAndroid Build Coastguard Worker  %cp1 = cleanuppad within none []
262*9880d681SAndroid Build Coastguard Worker  cleanupret from %cp1 unwind to caller
263*9880d681SAndroid Build Coastguard Workerloop:
264*9880d681SAndroid Build Coastguard Worker  invoke void @f()
265*9880d681SAndroid Build Coastguard Worker          to label %loop unwind label %cleanup
266*9880d681SAndroid Build Coastguard Workercleanup:
267*9880d681SAndroid Build Coastguard Worker  ; CHECK: cleanup:
268*9880d681SAndroid Build Coastguard Worker  ; CHECK:   call void @h(i32 %x)
269*9880d681SAndroid Build Coastguard Worker  %cp2 = cleanuppad within none []
270*9880d681SAndroid Build Coastguard Worker  call void @h(i32 %x) [ "funclet"(token %cp2) ]
271*9880d681SAndroid Build Coastguard Worker  cleanupret from %cp2 unwind to caller
272*9880d681SAndroid Build Coastguard Worker}
273*9880d681SAndroid Build Coastguard Worker
274*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test7(
275*9880d681SAndroid Build Coastguard Workerdefine void @test7() personality i32 (...)* @__CxxFrameHandler3 {
276*9880d681SAndroid Build Coastguard Workerentry:
277*9880d681SAndroid Build Coastguard Worker  ; %x is an EH pad phi, so gets stored in pred here
278*9880d681SAndroid Build Coastguard Worker  ; CHECK: entry:
279*9880d681SAndroid Build Coastguard Worker  ; CHECK:   store i32 1, i32* [[SlotX:%[^ ]+]]
280*9880d681SAndroid Build Coastguard Worker  ; CHECK:   invoke void @f()
281*9880d681SAndroid Build Coastguard Worker  invoke void @f()
282*9880d681SAndroid Build Coastguard Worker     to label %invoke.cont unwind label %catchpad
283*9880d681SAndroid Build Coastguard Workerinvoke.cont:
284*9880d681SAndroid Build Coastguard Worker  ; %x is an EH pad phi, so gets stored in pred here
285*9880d681SAndroid Build Coastguard Worker  ; CHECK: invoke.cont:
286*9880d681SAndroid Build Coastguard Worker  ; CHECK:   store i32 2, i32* [[SlotX]]
287*9880d681SAndroid Build Coastguard Worker  ; CHECK:   invoke void @f()
288*9880d681SAndroid Build Coastguard Worker  invoke void @f()
289*9880d681SAndroid Build Coastguard Worker    to label %exit unwind label %catchpad
290*9880d681SAndroid Build Coastguard Workercatchpad:
291*9880d681SAndroid Build Coastguard Worker  ; %x phi should be eliminated
292*9880d681SAndroid Build Coastguard Worker  ; CHECK: catchpad:
293*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: catchswitch within none
294*9880d681SAndroid Build Coastguard Worker  %x = phi i32 [ 1, %entry ], [ 2, %invoke.cont ]
295*9880d681SAndroid Build Coastguard Worker  %cs1 = catchswitch within none [label %catch] unwind to caller
296*9880d681SAndroid Build Coastguard Workercatch:
297*9880d681SAndroid Build Coastguard Worker  ; CHECK: catch:
298*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: %[[CatchPad:[^ ]+]] = catchpad within %cs1 []
299*9880d681SAndroid Build Coastguard Worker  %cp = catchpad within %cs1 []
300*9880d681SAndroid Build Coastguard Worker  %b = call i1 @i() [ "funclet"(token %cp) ]
301*9880d681SAndroid Build Coastguard Worker  br i1 %b, label %left, label %right
302*9880d681SAndroid Build Coastguard Workerleft:
303*9880d681SAndroid Build Coastguard Worker  ; Edge from %left to %join needs to be split so that
304*9880d681SAndroid Build Coastguard Worker  ; the load of %x can be inserted *after* the catchret
305*9880d681SAndroid Build Coastguard Worker  ; CHECK: left:
306*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: catchret from %[[CatchPad]] to label %[[SplitLeft:[^ ]+]]
307*9880d681SAndroid Build Coastguard Worker  catchret from %cp to label %join
308*9880d681SAndroid Build Coastguard Worker  ; CHECK: [[SplitLeft]]:
309*9880d681SAndroid Build Coastguard Worker  ; CHECK:   [[LoadX:%[^ ]+]] = load i32, i32* [[SlotX]]
310*9880d681SAndroid Build Coastguard Worker  ; CHECK:   br label %join
311*9880d681SAndroid Build Coastguard Workerright:
312*9880d681SAndroid Build Coastguard Worker  ; Edge from %right to %join needs to be split so that
313*9880d681SAndroid Build Coastguard Worker  ; the load of %y can be inserted *after* the catchret
314*9880d681SAndroid Build Coastguard Worker  ; CHECK: right:
315*9880d681SAndroid Build Coastguard Worker  ; CHECK:   %y = call i32 @g()
316*9880d681SAndroid Build Coastguard Worker  ; CHECK:   catchret from %[[CatchPad]] to label %join
317*9880d681SAndroid Build Coastguard Worker  %y = call i32 @g() [ "funclet"(token %cp) ]
318*9880d681SAndroid Build Coastguard Worker  catchret from %cp to label %join
319*9880d681SAndroid Build Coastguard Workerjoin:
320*9880d681SAndroid Build Coastguard Worker  ; CHECK: join:
321*9880d681SAndroid Build Coastguard Worker  ; CHECK:   %phi = phi i32 [ [[LoadX]], %[[SplitLeft]] ], [ %y, %right ]
322*9880d681SAndroid Build Coastguard Worker  %phi = phi i32 [ %x, %left ], [ %y, %right ]
323*9880d681SAndroid Build Coastguard Worker  call void @h(i32 %phi)
324*9880d681SAndroid Build Coastguard Worker  br label %exit
325*9880d681SAndroid Build Coastguard Workerexit:
326*9880d681SAndroid Build Coastguard Worker  ret void
327*9880d681SAndroid Build Coastguard Worker}
328*9880d681SAndroid Build Coastguard Worker
329*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test8(
330*9880d681SAndroid Build Coastguard Workerdefine void @test8() personality i32 (...)* @__CxxFrameHandler3 { entry:
331*9880d681SAndroid Build Coastguard Worker  invoke void @f()
332*9880d681SAndroid Build Coastguard Worker          to label %done unwind label %cleanup1
333*9880d681SAndroid Build Coastguard Worker  invoke void @f()
334*9880d681SAndroid Build Coastguard Worker          to label %done unwind label %cleanup2
335*9880d681SAndroid Build Coastguard Worker
336*9880d681SAndroid Build Coastguard Workerdone:
337*9880d681SAndroid Build Coastguard Worker  ret void
338*9880d681SAndroid Build Coastguard Worker
339*9880d681SAndroid Build Coastguard Workercleanup1:
340*9880d681SAndroid Build Coastguard Worker  ; CHECK: [[CleanupPad1:%[^ ]+]] = cleanuppad within none []
341*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: call void @llvm.bar()
342*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: cleanupret from [[CleanupPad1]]
343*9880d681SAndroid Build Coastguard Worker  %cp0 = cleanuppad within none []
344*9880d681SAndroid Build Coastguard Worker  br label %cleanupexit
345*9880d681SAndroid Build Coastguard Worker
346*9880d681SAndroid Build Coastguard Workercleanup2:
347*9880d681SAndroid Build Coastguard Worker  ; CHECK: cleanuppad within none []
348*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: call void @llvm.bar()
349*9880d681SAndroid Build Coastguard Worker  ; CHECK-NEXT: unreachable
350*9880d681SAndroid Build Coastguard Worker  %cp1 = cleanuppad within none []
351*9880d681SAndroid Build Coastguard Worker  br label %cleanupexit
352*9880d681SAndroid Build Coastguard Worker
353*9880d681SAndroid Build Coastguard Workercleanupexit:
354*9880d681SAndroid Build Coastguard Worker  call void @llvm.bar()
355*9880d681SAndroid Build Coastguard Worker  cleanupret from %cp0 unwind label %cleanup2
356*9880d681SAndroid Build Coastguard Worker}
357