• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -instcombine < %s | FileCheck %s
3
4declare void @foo()
5declare void @bar()
6declare void @baz()
7declare void @qux()
8declare void @quux()
9
10declare i1 @geni1()
11
12declare void @usei32(i32)
13declare void @usei32i32agg({ i32, i32 })
14
15; Most basic test - diamond structure
16define { 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]]
30;
31entry:
32  br i1 %c, label %left, label %right
33
34left:
35  %i0 = extractvalue { i32, i32 } %agg_left, 0
36  %i2 = extractvalue { i32, i32 } %agg_left, 1
37  call void @foo()
38  br label %end
39
40right:
41  %i3 = extractvalue { i32, i32 } %agg_right, 0
42  %i4 = extractvalue { i32, i32 } %agg_right, 1
43  call void @bar()
44  br label %end
45
46end:
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
53}
54
55; Second element is coming from wrong aggregate
56define { 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]]
75;
76entry:
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
82
83left:
84  call void @foo()
85  br label %end
86
87right:
88  call void @bar()
89  br label %end
90
91end:
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
98}
99
100; When coming from %left, elements are swapped
101define { 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]]
122;
123entry:
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
129
130left:
131  call void @foo()
132  br label %end
133
134right:
135  call void @bar()
136  br label %end
137
138end:
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
145}
146
147; FIXME: we should probably be able to handle multiple levels of PHI indirection
148define { 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]]
167;
168entry:
169  br i1 %c0, label %bb0.dispatch, label %bb10
170
171bb0.dispatch:
172  br i1 %c1, label %bb00, label %bb01
173
174bb00:
175  %i0 = extractvalue { i32, i32 } %agg_00, 0
176  %i1 = extractvalue { i32, i32 } %agg_00, 1
177  br label %bb0.merge
178
179bb01:
180  %i2 = extractvalue { i32, i32 } %agg_01, 0
181  %i3 = extractvalue { i32, i32 } %agg_01, 1
182  br label %bb0.merge
183
184bb0.merge:
185  %i4 = phi i32 [ %i0, %bb00 ], [ %i2, %bb01 ]
186  %i5 = phi i32 [ %i1, %bb00 ], [ %i3, %bb01 ]
187  br label %end
188
189bb10:
190  %i6 = extractvalue { i32, i32 } %agg_10, 0
191  %i7 = extractvalue { i32, i32 } %agg_10, 1
192  br label %end
193
194end:
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
201}
202
203; Not sure what should happen for cycles.
204define { 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]]
228;
229entry:
230  br i1 %c0, label %left, label %right
231
232left:
233  %i0 = extractvalue { i32, i32 } %agg_left, 0
234  %i2 = extractvalue { i32, i32 } %agg_left, 1
235  call void @foo()
236  br label %middle
237
238right:
239  %i3 = extractvalue { i32, i32 } %agg_right, 0
240  %i4 = extractvalue { i32, i32 } %agg_right, 1
241  call void @bar()
242  br label %middle
243
244middle:
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
252
253end:
254  ret { i32, i32 } %i8
255}
256
257; But here since we start without an explicit self-cycle, we already manage to fold it.
258define { 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]]
275;
276entry:
277  br i1 %c0, label %left, label %right
278
279left:
280  %i0 = extractvalue { i32, i32 } %agg_left, 0
281  %i2 = extractvalue { i32, i32 } %agg_left, 1
282  call void @foo()
283  br label %middle
284
285right:
286  %i3 = extractvalue { i32, i32 } %agg_right, 0
287  %i4 = extractvalue { i32, i32 } %agg_right, 1
288  call void @bar()
289  br label %middle
290
291middle:
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
301
302end:
303  ret { i32, i32 } %i8
304}
305
306; Diamond structure, but with "padding" block before the use.
307define { 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]]
327;
328entry:
329  br i1 %c0, label %left, label %right
330
331left:
332  %i0 = extractvalue { i32, i32 } %agg_left, 0
333  %i2 = extractvalue { i32, i32 } %agg_left, 1
334  call void @foo()
335  br label %merge
336
337right:
338  %i3 = extractvalue { i32, i32 } %agg_right, 0
339  %i4 = extractvalue { i32, i32 } %agg_right, 1
340  call void @bar()
341  br label %merge
342
343merge:
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
348
349passthrough:
350  call void @qux()
351  br label %end
352
353end:
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
358}
359
360; All the definitions of the aggregate elements must happen in the same block.
361define { 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]]
384;
385entry:
386  %i0 = extractvalue { i32, i32 } %agg_left, 0
387  call void @usei32(i32 %i0)
388  br i1 %c0, label %left, label %right
389
390left:
391  %i1 = extractvalue { i32, i32 } %agg_left, 1
392  call void @usei32(i32 %i1)
393  br label %merge
394
395right:
396  %i2 = extractvalue { i32, i32 } %agg_right, 1
397  call void @usei32(i32 %i2)
398  br label %merge
399
400merge:
401  %i3 = phi i32 [ %i1, %left ], [ %i2, %right ]
402  call void @bar()
403  br label %end
404
405end:
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
410}
411
412; Most basic test - diamond structure, but with a switch, which results in multiple duplicate predecessors
413define { 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]]
435;
436entry:
437  br i1 %c, label %left, label %right
438
439left:
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  ]
447
448right:
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  ]
456
457impossible:
458  unreachable
459
460end:
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
467}
468
469; The insertion of first element could have been split/hoisted into the predecessors.
470define { 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]]
484;
485entry:
486  br i1 %c, label %left, label %right
487
488left:
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
494
495right:
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
501
502end:
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
508}
509