Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / InstCombine / phi-aware-aggregate-reconstruction.ll
blob6b7ac445839d256b9c26200d8ace4c3f244ebe04
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
4 declare void @foo()
5 declare void @bar()
6 declare void @baz()
7 declare void @qux()
8 declare void @quux()
10 declare i1 @geni1()
12 declare void @usei32(i32)
13 declare void @usei32i32agg({ i32, i32 })
15 ; Most basic test - diamond structure
16 define { i32, i32 } @test0({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c) {
17 ; CHECK-LABEL: @test0(
18 ; CHECK-NEXT:  entry:
19 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
20 ; CHECK:       left:
21 ; CHECK-NEXT:    call void @foo()
22 ; CHECK-NEXT:    br label [[END:%.*]]
23 ; CHECK:       right:
24 ; CHECK-NEXT:    call void @bar()
25 ; CHECK-NEXT:    br label [[END]]
26 ; CHECK:       end:
27 ; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [ [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ]
28 ; CHECK-NEXT:    call void @baz()
29 ; CHECK-NEXT:    ret { i32, i32 } [[AGG_LEFT_PN]]
31 entry:
32   br i1 %c, label %left, label %right
34 left:
35   %i0 = extractvalue { i32, i32 } %agg_left, 0
36   %i2 = extractvalue { i32, i32 } %agg_left, 1
37   call void @foo()
38   br label %end
40 right:
41   %i3 = extractvalue { i32, i32 } %agg_right, 0
42   %i4 = extractvalue { i32, i32 } %agg_right, 1
43   call void @bar()
44   br label %end
46 end:
47   %i5 = phi i32 [ %i0, %left ], [ %i3, %right ]
48   %i6 = phi i32 [ %i2, %left ], [ %i4, %right ]
49   call void @baz()
50   %i7 = insertvalue { i32, i32 } undef, i32 %i5, 0
51   %i8 = insertvalue { i32, i32 } %i7, i32 %i6, 1
52   ret { i32, i32 } %i8
55 ; Second element is coming from wrong aggregate
56 define { i32, i32 } @negative_test1({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c) {
57 ; CHECK-LABEL: @negative_test1(
58 ; CHECK-NEXT:  entry:
59 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
60 ; CHECK:       left:
61 ; CHECK-NEXT:    call void @foo()
62 ; CHECK-NEXT:    br label [[END:%.*]]
63 ; CHECK:       right:
64 ; CHECK-NEXT:    call void @bar()
65 ; CHECK-NEXT:    br label [[END]]
66 ; CHECK:       end:
67 ; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [ [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ]
68 ; CHECK-NEXT:    [[AGG_RIGHT_PN:%.*]] = phi { i32, i32 } [ [[AGG_RIGHT]], [[LEFT]] ], [ [[AGG_LEFT]], [[RIGHT]] ]
69 ; CHECK-NEXT:    [[I6:%.*]] = extractvalue { i32, i32 } [[AGG_RIGHT_PN]], 1
70 ; CHECK-NEXT:    [[I5:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT_PN]], 0
71 ; CHECK-NEXT:    call void @baz()
72 ; CHECK-NEXT:    [[I7:%.*]] = insertvalue { i32, i32 } undef, i32 [[I5]], 0
73 ; CHECK-NEXT:    [[I8:%.*]] = insertvalue { i32, i32 } [[I7]], i32 [[I6]], 1
74 ; CHECK-NEXT:    ret { i32, i32 } [[I8]]
76 entry:
77   %i0 = extractvalue { i32, i32 } %agg_left, 0
78   %i2 = extractvalue { i32, i32 } %agg_left, 1
79   %i3 = extractvalue { i32, i32 } %agg_right, 0
80   %i4 = extractvalue { i32, i32 } %agg_right, 1
81   br i1 %c, label %left, label %right
83 left:
84   call void @foo()
85   br label %end
87 right:
88   call void @bar()
89   br label %end
91 end:
92   %i5 = phi i32 [ %i0, %left ], [ %i3, %right ]
93   %i6 = phi i32 [ %i4, %left ], [ %i2, %right ]
94   call void @baz()
95   %i7 = insertvalue { i32, i32 } undef, i32 %i5, 0
96   %i8 = insertvalue { i32, i32 } %i7, i32 %i6, 1
97   ret { i32, i32 } %i8
100 ; When coming from %left, elements are swapped
101 define { i32, i32 } @negative_test2({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c) {
102 ; CHECK-LABEL: @negative_test2(
103 ; CHECK-NEXT:  entry:
104 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
105 ; CHECK:       left:
106 ; CHECK-NEXT:    [[I2:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT:%.*]], 1
107 ; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT]], 0
108 ; CHECK-NEXT:    call void @foo()
109 ; CHECK-NEXT:    br label [[END:%.*]]
110 ; CHECK:       right:
111 ; CHECK-NEXT:    [[I4:%.*]] = extractvalue { i32, i32 } [[AGG_RIGHT:%.*]], 1
112 ; CHECK-NEXT:    [[I3:%.*]] = extractvalue { i32, i32 } [[AGG_RIGHT]], 0
113 ; CHECK-NEXT:    call void @bar()
114 ; CHECK-NEXT:    br label [[END]]
115 ; CHECK:       end:
116 ; CHECK-NEXT:    [[I5:%.*]] = phi i32 [ [[I2]], [[LEFT]] ], [ [[I3]], [[RIGHT]] ]
117 ; CHECK-NEXT:    [[I6:%.*]] = phi i32 [ [[I0]], [[LEFT]] ], [ [[I4]], [[RIGHT]] ]
118 ; CHECK-NEXT:    call void @baz()
119 ; CHECK-NEXT:    [[I7:%.*]] = insertvalue { i32, i32 } undef, i32 [[I5]], 0
120 ; CHECK-NEXT:    [[I8:%.*]] = insertvalue { i32, i32 } [[I7]], i32 [[I6]], 1
121 ; CHECK-NEXT:    ret { i32, i32 } [[I8]]
123 entry:
124   %i0 = extractvalue { i32, i32 } %agg_left, 0
125   %i2 = extractvalue { i32, i32 } %agg_left, 1
126   %i3 = extractvalue { i32, i32 } %agg_right, 0
127   %i4 = extractvalue { i32, i32 } %agg_right, 1
128   br i1 %c, label %left, label %right
130 left:
131   call void @foo()
132   br label %end
134 right:
135   call void @bar()
136   br label %end
138 end:
139   %i5 = phi i32 [ %i2, %left ], [ %i3, %right ]
140   %i6 = phi i32 [ %i0, %left ], [ %i4, %right ]
141   call void @baz()
142   %i7 = insertvalue { i32, i32 } undef, i32 %i5, 0
143   %i8 = insertvalue { i32, i32 } %i7, i32 %i6, 1
144   ret { i32, i32 } %i8
147 ; FIXME: we should probably be able to handle multiple levels of PHI indirection
148 define { i32, i32 } @test3({ i32, i32 } %agg_00, { i32, i32 } %agg_01, { i32, i32 } %agg_10, i1 %c0, i1 %c1) {
149 ; CHECK-LABEL: @test3(
150 ; CHECK-NEXT:  entry:
151 ; CHECK-NEXT:    br i1 [[C0:%.*]], label [[BB0_DISPATCH:%.*]], label [[BB10:%.*]]
152 ; CHECK:       bb0.dispatch:
153 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB00:%.*]], label [[BB01:%.*]]
154 ; CHECK:       bb00:
155 ; CHECK-NEXT:    br label [[BB0_MERGE:%.*]]
156 ; CHECK:       bb01:
157 ; CHECK-NEXT:    br label [[BB0_MERGE]]
158 ; CHECK:       bb0.merge:
159 ; CHECK-NEXT:    [[AGG_00_PN:%.*]] = phi { i32, i32 } [ [[AGG_00:%.*]], [[BB00]] ], [ [[AGG_01:%.*]], [[BB01]] ]
160 ; CHECK-NEXT:    br label [[END:%.*]]
161 ; CHECK:       bb10:
162 ; CHECK-NEXT:    br label [[END]]
163 ; CHECK:       end:
164 ; CHECK-NEXT:    [[AGG_00_PN_PN:%.*]] = phi { i32, i32 } [ [[AGG_00_PN]], [[BB0_MERGE]] ], [ [[AGG_10:%.*]], [[BB10]] ]
165 ; CHECK-NEXT:    call void @baz()
166 ; CHECK-NEXT:    ret { i32, i32 } [[AGG_00_PN_PN]]
168 entry:
169   br i1 %c0, label %bb0.dispatch, label %bb10
171 bb0.dispatch:
172   br i1 %c1, label %bb00, label %bb01
174 bb00:
175   %i0 = extractvalue { i32, i32 } %agg_00, 0
176   %i1 = extractvalue { i32, i32 } %agg_00, 1
177   br label %bb0.merge
179 bb01:
180   %i2 = extractvalue { i32, i32 } %agg_01, 0
181   %i3 = extractvalue { i32, i32 } %agg_01, 1
182   br label %bb0.merge
184 bb0.merge:
185   %i4 = phi i32 [ %i0, %bb00 ], [ %i2, %bb01 ]
186   %i5 = phi i32 [ %i1, %bb00 ], [ %i3, %bb01 ]
187   br label %end
189 bb10:
190   %i6 = extractvalue { i32, i32 } %agg_10, 0
191   %i7 = extractvalue { i32, i32 } %agg_10, 1
192   br label %end
194 end:
195   %i8 = phi i32 [ %i4, %bb0.merge ], [ %i6, %bb10 ]
196   %i9 = phi i32 [ %i5, %bb0.merge ], [ %i7, %bb10 ]
197   call void @baz()
198   %i10 = insertvalue { i32, i32 } undef, i32 %i8, 0
199   %i11 = insertvalue { i32, i32 } %i10, i32 %i9, 1
200   ret { i32, i32 } %i11
203 ; Not sure what should happen for cycles.
204 define { i32, i32 } @test4({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c0) {
205 ; CHECK-LABEL: @test4(
206 ; CHECK-NEXT:  entry:
207 ; CHECK-NEXT:    br i1 [[C0:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
208 ; CHECK:       left:
209 ; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT:%.*]], 0
210 ; CHECK-NEXT:    [[I2:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT]], 1
211 ; CHECK-NEXT:    call void @foo()
212 ; CHECK-NEXT:    br label [[MIDDLE:%.*]]
213 ; CHECK:       right:
214 ; CHECK-NEXT:    [[I3:%.*]] = extractvalue { i32, i32 } [[AGG_RIGHT:%.*]], 0
215 ; CHECK-NEXT:    [[I4:%.*]] = extractvalue { i32, i32 } [[AGG_RIGHT]], 1
216 ; CHECK-NEXT:    call void @bar()
217 ; CHECK-NEXT:    br label [[MIDDLE]]
218 ; CHECK:       middle:
219 ; CHECK-NEXT:    [[I5:%.*]] = phi i32 [ [[I0]], [[LEFT]] ], [ [[I3]], [[RIGHT]] ], [ [[I5]], [[MIDDLE]] ]
220 ; CHECK-NEXT:    [[I6:%.*]] = phi i32 [ [[I2]], [[LEFT]] ], [ [[I4]], [[RIGHT]] ], [ [[I6]], [[MIDDLE]] ]
221 ; CHECK-NEXT:    call void @baz()
222 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @geni1()
223 ; CHECK-NEXT:    br i1 [[C1]], label [[END:%.*]], label [[MIDDLE]]
224 ; CHECK:       end:
225 ; CHECK-NEXT:    [[I7:%.*]] = insertvalue { i32, i32 } undef, i32 [[I5]], 0
226 ; CHECK-NEXT:    [[I8:%.*]] = insertvalue { i32, i32 } [[I7]], i32 [[I6]], 1
227 ; CHECK-NEXT:    ret { i32, i32 } [[I8]]
229 entry:
230   br i1 %c0, label %left, label %right
232 left:
233   %i0 = extractvalue { i32, i32 } %agg_left, 0
234   %i2 = extractvalue { i32, i32 } %agg_left, 1
235   call void @foo()
236   br label %middle
238 right:
239   %i3 = extractvalue { i32, i32 } %agg_right, 0
240   %i4 = extractvalue { i32, i32 } %agg_right, 1
241   call void @bar()
242   br label %middle
244 middle:
245   %i5 = phi i32 [ %i0, %left ], [ %i3, %right ], [ %i5, %middle ]
246   %i6 = phi i32 [ %i2, %left ], [ %i4, %right ], [ %i6, %middle ]
247   call void @baz()
248   %i7 = insertvalue { i32, i32 } undef, i32 %i5, 0
249   %i8 = insertvalue { i32, i32 } %i7, i32 %i6, 1
250   %c1 = call i1 @geni1()
251   br i1 %c1, label %end, label %middle
253 end:
254   ret { i32, i32 } %i8
257 ; But here since we start without an explicit self-cycle, we already manage to fold it.
258 define { i32, i32 } @test5({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c0) {
259 ; CHECK-LABEL: @test5(
260 ; CHECK-NEXT:  entry:
261 ; CHECK-NEXT:    br i1 [[C0:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
262 ; CHECK:       left:
263 ; CHECK-NEXT:    call void @foo()
264 ; CHECK-NEXT:    br label [[MIDDLE:%.*]]
265 ; CHECK:       right:
266 ; CHECK-NEXT:    call void @bar()
267 ; CHECK-NEXT:    br label [[MIDDLE]]
268 ; CHECK:       middle:
269 ; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [ [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ], [ [[AGG_LEFT_PN]], [[MIDDLE]] ]
270 ; CHECK-NEXT:    call void @baz()
271 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @geni1()
272 ; CHECK-NEXT:    br i1 [[C1]], label [[END:%.*]], label [[MIDDLE]]
273 ; CHECK:       end:
274 ; CHECK-NEXT:    ret { i32, i32 } [[AGG_LEFT_PN]]
276 entry:
277   br i1 %c0, label %left, label %right
279 left:
280   %i0 = extractvalue { i32, i32 } %agg_left, 0
281   %i2 = extractvalue { i32, i32 } %agg_left, 1
282   call void @foo()
283   br label %middle
285 right:
286   %i3 = extractvalue { i32, i32 } %agg_right, 0
287   %i4 = extractvalue { i32, i32 } %agg_right, 1
288   call void @bar()
289   br label %middle
291 middle:
292   %i5 = phi i32 [ %i0, %left ], [ %i3, %right ], [ %i9, %middle ]
293   %i6 = phi i32 [ %i2, %left ], [ %i4, %right ], [ %i10, %middle ]
294   call void @baz()
295   %i7 = insertvalue { i32, i32 } undef, i32 %i5, 0
296   %i8 = insertvalue { i32, i32 } %i7, i32 %i6, 1
297   %i9 = extractvalue { i32, i32 } %i8, 0
298   %i10 = extractvalue { i32, i32 } %i8, 1
299   %c1 = call i1 @geni1()
300   br i1 %c1, label %end, label %middle
302 end:
303   ret { i32, i32 } %i8
306 ; Diamond structure, but with "padding" block before the use.
307 define { i32, i32 } @test6({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c0, i1 %c1) {
308 ; CHECK-LABEL: @test6(
309 ; CHECK-NEXT:  entry:
310 ; CHECK-NEXT:    br i1 [[C0:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
311 ; CHECK:       left:
312 ; CHECK-NEXT:    call void @foo()
313 ; CHECK-NEXT:    br label [[MERGE:%.*]]
314 ; CHECK:       right:
315 ; CHECK-NEXT:    call void @bar()
316 ; CHECK-NEXT:    br label [[MERGE]]
317 ; CHECK:       merge:
318 ; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [ [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ]
319 ; CHECK-NEXT:    call void @baz()
320 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[END:%.*]], label [[PASSTHROUGH:%.*]]
321 ; CHECK:       passthrough:
322 ; CHECK-NEXT:    call void @qux()
323 ; CHECK-NEXT:    br label [[END]]
324 ; CHECK:       end:
325 ; CHECK-NEXT:    call void @quux()
326 ; CHECK-NEXT:    ret { i32, i32 } [[AGG_LEFT_PN]]
328 entry:
329   br i1 %c0, label %left, label %right
331 left:
332   %i0 = extractvalue { i32, i32 } %agg_left, 0
333   %i2 = extractvalue { i32, i32 } %agg_left, 1
334   call void @foo()
335   br label %merge
337 right:
338   %i3 = extractvalue { i32, i32 } %agg_right, 0
339   %i4 = extractvalue { i32, i32 } %agg_right, 1
340   call void @bar()
341   br label %merge
343 merge:
344   %i5 = phi i32 [ %i0, %left ], [ %i3, %right ]
345   %i6 = phi i32 [ %i2, %left ], [ %i4, %right ]
346   call void @baz()
347   br i1 %c1, label %end, label %passthrough
349 passthrough:
350   call void @qux()
351   br label %end
353 end:
354   call void @quux()
355   %i7 = insertvalue { i32, i32 } undef, i32 %i5, 0
356   %i8 = insertvalue { i32, i32 } %i7, i32 %i6, 1
357   ret { i32, i32 } %i8
360 ; All the definitions of the aggregate elements must happen in the same block.
361 define { i32, i32 } @negative_test7({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c0, i1 %c1) {
362 ; CHECK-LABEL: @negative_test7(
363 ; CHECK-NEXT:  entry:
364 ; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT:%.*]], 0
365 ; CHECK-NEXT:    call void @usei32(i32 [[I0]])
366 ; CHECK-NEXT:    br i1 [[C0:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
367 ; CHECK:       left:
368 ; CHECK-NEXT:    [[I1:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT]], 1
369 ; CHECK-NEXT:    call void @usei32(i32 [[I1]])
370 ; CHECK-NEXT:    br label [[MERGE:%.*]]
371 ; CHECK:       right:
372 ; CHECK-NEXT:    [[I2:%.*]] = extractvalue { i32, i32 } [[AGG_RIGHT:%.*]], 1
373 ; CHECK-NEXT:    call void @usei32(i32 [[I2]])
374 ; CHECK-NEXT:    br label [[MERGE]]
375 ; CHECK:       merge:
376 ; CHECK-NEXT:    [[I3:%.*]] = phi i32 [ [[I1]], [[LEFT]] ], [ [[I2]], [[RIGHT]] ]
377 ; CHECK-NEXT:    call void @bar()
378 ; CHECK-NEXT:    br label [[END:%.*]]
379 ; CHECK:       end:
380 ; CHECK-NEXT:    call void @baz()
381 ; CHECK-NEXT:    [[I7:%.*]] = insertvalue { i32, i32 } undef, i32 [[I0]], 0
382 ; CHECK-NEXT:    [[I8:%.*]] = insertvalue { i32, i32 } [[I7]], i32 [[I3]], 1
383 ; CHECK-NEXT:    ret { i32, i32 } [[I8]]
385 entry:
386   %i0 = extractvalue { i32, i32 } %agg_left, 0
387   call void @usei32(i32 %i0)
388   br i1 %c0, label %left, label %right
390 left:
391   %i1 = extractvalue { i32, i32 } %agg_left, 1
392   call void @usei32(i32 %i1)
393   br label %merge
395 right:
396   %i2 = extractvalue { i32, i32 } %agg_right, 1
397   call void @usei32(i32 %i2)
398   br label %merge
400 merge:
401   %i3 = phi i32 [ %i1, %left ], [ %i2, %right ]
402   call void @bar()
403   br label %end
405 end:
406   call void @baz()
407   %i7 = insertvalue { i32, i32 } undef, i32 %i0, 0
408   %i8 = insertvalue { i32, i32 } %i7, i32 %i3, 1
409   ret { i32, i32 } %i8
412 ; Most basic test - diamond structure, but with a switch, which results in multiple duplicate predecessors
413 define { i32, i32 } @test8({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c, i32 %val_left, i32 %val_right) {
414 ; CHECK-LABEL: @test8(
415 ; CHECK-NEXT:  entry:
416 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
417 ; CHECK:       left:
418 ; CHECK-NEXT:    call void @foo()
419 ; CHECK-NEXT:    switch i32 [[VAL_LEFT:%.*]], label [[IMPOSSIBLE:%.*]] [
420 ; CHECK-NEXT:    i32 -42, label [[END:%.*]]
421 ; CHECK-NEXT:    i32 42, label [[END]]
422 ; CHECK-NEXT:    ]
423 ; CHECK:       right:
424 ; CHECK-NEXT:    call void @bar()
425 ; CHECK-NEXT:    switch i32 [[VAL_RIGHT:%.*]], label [[IMPOSSIBLE]] [
426 ; CHECK-NEXT:    i32 42, label [[END]]
427 ; CHECK-NEXT:    i32 -42, label [[END]]
428 ; CHECK-NEXT:    ]
429 ; CHECK:       impossible:
430 ; CHECK-NEXT:    unreachable
431 ; CHECK:       end:
432 ; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [ [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_LEFT]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ], [ [[AGG_RIGHT]], [[RIGHT]] ]
433 ; CHECK-NEXT:    call void @baz()
434 ; CHECK-NEXT:    ret { i32, i32 } [[AGG_LEFT_PN]]
436 entry:
437   br i1 %c, label %left, label %right
439 left:
440   %i0 = extractvalue { i32, i32 } %agg_left, 0
441   %i2 = extractvalue { i32, i32 } %agg_left, 1
442   call void @foo()
443   switch i32 %val_left, label %impossible [
444   i32 -42, label %end
445   i32 42, label %end
446   ]
448 right:
449   %i3 = extractvalue { i32, i32 } %agg_right, 0
450   %i4 = extractvalue { i32, i32 } %agg_right, 1
451   call void @bar()
452   switch i32 %val_right, label %impossible [
453   i32 42, label %end
454   i32 -42, label %end
455   ]
457 impossible:
458   unreachable
460 end:
461   %i5 = phi i32 [ %i0, %left ], [ %i0, %left ], [ %i3, %right ], [ %i3, %right ]
462   %i6 = phi i32 [ %i2, %left ], [ %i2, %left ], [ %i4, %right ], [ %i4, %right ]
463   call void @baz()
464   %i7 = insertvalue { i32, i32 } undef, i32 %i5, 0
465   %i8 = insertvalue { i32, i32 } %i7, i32 %i6, 1
466   ret { i32, i32 } %i8
469 ; The insertion of first element could have been split/hoisted into the predecessors.
470 define { i32, i32 } @test9({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c) {
471 ; CHECK-LABEL: @test9(
472 ; CHECK-NEXT:  entry:
473 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
474 ; CHECK:       left:
475 ; CHECK-NEXT:    call void @foo()
476 ; CHECK-NEXT:    br label [[END:%.*]]
477 ; CHECK:       right:
478 ; CHECK-NEXT:    call void @bar()
479 ; CHECK-NEXT:    br label [[END]]
480 ; CHECK:       end:
481 ; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [ [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ]
482 ; CHECK-NEXT:    call void @baz()
483 ; CHECK-NEXT:    ret { i32, i32 } [[AGG_LEFT_PN]]
485 entry:
486   br i1 %c, label %left, label %right
488 left:
489   %i0 = extractvalue { i32, i32 } %agg_left, 0
490   %i1 = extractvalue { i32, i32 } %agg_left, 1
491   %i2 = insertvalue { i32, i32 } undef, i32 %i0, 0
492   call void @foo()
493   br label %end
495 right:
496   %i3 = extractvalue { i32, i32 } %agg_right, 0
497   %i4 = extractvalue { i32, i32 } %agg_right, 1
498   %i5 = insertvalue { i32, i32 } undef, i32 %i3, 0
499   call void @bar()
500   br label %end
502 end:
503   %i6 = phi { i32, i32 } [ %i2, %left ], [ %i5, %right ]
504   %i7 = phi i32 [ %i1, %left ], [ %i4, %right ]
505   call void @baz()
506   %i8 = insertvalue { i32, i32 } %i6, i32 %i7, 1
507   ret { i32, i32 } %i8