xref: /llvm-project/llvm/test/Transforms/InstCombine/fold-aggregate-reconstruction.ll (revision 9424f3dcc5a3f1dada99831b87b0b502a7667d48)
1*9424f3dcSweiguozhi; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2*9424f3dcSweiguozhi; RUN: opt -S -passes=instcombine < %s | FileCheck %s
3*9424f3dcSweiguozhi
4*9424f3dcSweiguozhideclare {ptr, i64} @bar(i64)
5*9424f3dcSweiguozhi
6*9424f3dcSweiguozhi; Basic test.
7*9424f3dcSweiguozhidefine {ptr, i64} @test1(i1 %cond1, ptr %p1, ptr %p2) {
8*9424f3dcSweiguozhi; CHECK-LABEL: define { ptr, i64 } @test1(
9*9424f3dcSweiguozhi; CHECK-SAME: i1 [[COND1:%.*]], ptr [[P1:%.*]], ptr [[P2:%.*]]) {
10*9424f3dcSweiguozhi; CHECK-NEXT:    br i1 [[COND1]], label %[[BBB1:.*]], label %[[BBB2:.*]]
11*9424f3dcSweiguozhi; CHECK:       [[BBB1]]:
12*9424f3dcSweiguozhi; CHECK-NEXT:    [[CALL1:%.*]] = call { ptr, i64 } @bar(i64 0)
13*9424f3dcSweiguozhi; CHECK-NEXT:    br label %[[EXIT:.*]]
14*9424f3dcSweiguozhi; CHECK:       [[BBB2]]:
15*9424f3dcSweiguozhi; CHECK-NEXT:    [[VAL21:%.*]] = load ptr, ptr [[P1]], align 8
16*9424f3dcSweiguozhi; CHECK-NEXT:    [[VAL22:%.*]] = load i64, ptr [[P2]], align 4
17*9424f3dcSweiguozhi; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { ptr, i64 } poison, ptr [[VAL21]], 0
18*9424f3dcSweiguozhi; CHECK-NEXT:    [[TMP2:%.*]] = insertvalue { ptr, i64 } [[TMP1]], i64 [[VAL22]], 1
19*9424f3dcSweiguozhi; CHECK-NEXT:    br label %[[EXIT]]
20*9424f3dcSweiguozhi; CHECK:       [[EXIT]]:
21*9424f3dcSweiguozhi; CHECK-NEXT:    [[RES_MERGED:%.*]] = phi { ptr, i64 } [ [[CALL1]], %[[BBB1]] ], [ [[TMP2]], %[[BBB2]] ]
22*9424f3dcSweiguozhi; CHECK-NEXT:    ret { ptr, i64 } [[RES_MERGED]]
23*9424f3dcSweiguozhi;
24*9424f3dcSweiguozhi  br i1 %cond1, label %bbb1, label %bbb2
25*9424f3dcSweiguozhi
26*9424f3dcSweiguozhibbb1:
27*9424f3dcSweiguozhi  %call1 = call {ptr, i64} @bar(i64 0)
28*9424f3dcSweiguozhi  %val11 = extractvalue { ptr, i64 } %call1, 0
29*9424f3dcSweiguozhi  %val12 = extractvalue { ptr, i64 } %call1, 1
30*9424f3dcSweiguozhi  br label %exit
31*9424f3dcSweiguozhi
32*9424f3dcSweiguozhibbb2:
33*9424f3dcSweiguozhi  %val21 = load ptr, ptr %p1
34*9424f3dcSweiguozhi  %val22 = load i64, ptr %p2
35*9424f3dcSweiguozhi  br label %exit
36*9424f3dcSweiguozhi
37*9424f3dcSweiguozhiexit:
38*9424f3dcSweiguozhi  %val1 = phi ptr [%val11, %bbb1], [%val21, %bbb2]
39*9424f3dcSweiguozhi  %val2 = phi i64 [%val12, %bbb1], [%val22, %bbb2]
40*9424f3dcSweiguozhi  %tmp = insertvalue { ptr, i64 } poison, ptr %val1, 0
41*9424f3dcSweiguozhi  %res = insertvalue { ptr, i64 } %tmp, i64 %val2, 1
42*9424f3dcSweiguozhi  ret {ptr, i64} %res
43*9424f3dcSweiguozhi}
44*9424f3dcSweiguozhi
45*9424f3dcSweiguozhi; Test with more predecessors.
46*9424f3dcSweiguozhidefine {ptr, i64} @test2(i1 %cond1, i1 %cond2, ptr %p1, ptr %p2) {
47*9424f3dcSweiguozhi; CHECK-LABEL: define { ptr, i64 } @test2(
48*9424f3dcSweiguozhi; CHECK-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]], ptr [[P1:%.*]], ptr [[P2:%.*]]) {
49*9424f3dcSweiguozhi; CHECK-NEXT:    br i1 [[COND1]], label %[[BBB1:.*]], label %[[BBB4:.*]]
50*9424f3dcSweiguozhi; CHECK:       [[BBB1]]:
51*9424f3dcSweiguozhi; CHECK-NEXT:    br i1 [[COND2]], label %[[BBB2:.*]], label %[[BBB3:.*]]
52*9424f3dcSweiguozhi; CHECK:       [[BBB2]]:
53*9424f3dcSweiguozhi; CHECK-NEXT:    [[CALL1:%.*]] = call { ptr, i64 } @bar(i64 0)
54*9424f3dcSweiguozhi; CHECK-NEXT:    br label %[[EXIT:.*]]
55*9424f3dcSweiguozhi; CHECK:       [[BBB3]]:
56*9424f3dcSweiguozhi; CHECK-NEXT:    [[CALL2:%.*]] = call { ptr, i64 } @bar(i64 1)
57*9424f3dcSweiguozhi; CHECK-NEXT:    br label %[[EXIT]]
58*9424f3dcSweiguozhi; CHECK:       [[BBB4]]:
59*9424f3dcSweiguozhi; CHECK-NEXT:    [[VAL31:%.*]] = load ptr, ptr [[P1]], align 8
60*9424f3dcSweiguozhi; CHECK-NEXT:    [[VAL32:%.*]] = load i64, ptr [[P2]], align 4
61*9424f3dcSweiguozhi; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { ptr, i64 } poison, ptr [[VAL31]], 0
62*9424f3dcSweiguozhi; CHECK-NEXT:    [[TMP2:%.*]] = insertvalue { ptr, i64 } [[TMP1]], i64 [[VAL32]], 1
63*9424f3dcSweiguozhi; CHECK-NEXT:    br label %[[EXIT]]
64*9424f3dcSweiguozhi; CHECK:       [[EXIT]]:
65*9424f3dcSweiguozhi; CHECK-NEXT:    [[RES_MERGED:%.*]] = phi { ptr, i64 } [ [[CALL1]], %[[BBB2]] ], [ [[CALL2]], %[[BBB3]] ], [ [[TMP2]], %[[BBB4]] ]
66*9424f3dcSweiguozhi; CHECK-NEXT:    ret { ptr, i64 } [[RES_MERGED]]
67*9424f3dcSweiguozhi;
68*9424f3dcSweiguozhi  br i1 %cond1, label %bbb1, label %bbb4
69*9424f3dcSweiguozhi
70*9424f3dcSweiguozhibbb1:
71*9424f3dcSweiguozhi  br i1 %cond2, label %bbb2, label %bbb3
72*9424f3dcSweiguozhi
73*9424f3dcSweiguozhibbb2:
74*9424f3dcSweiguozhi  %call1 = call {ptr, i64} @bar(i64 0)
75*9424f3dcSweiguozhi  %val11 = extractvalue { ptr, i64 } %call1, 0
76*9424f3dcSweiguozhi  %val12 = extractvalue { ptr, i64 } %call1, 1
77*9424f3dcSweiguozhi  br label %exit
78*9424f3dcSweiguozhi
79*9424f3dcSweiguozhibbb3:
80*9424f3dcSweiguozhi  %call2 = call {ptr, i64} @bar(i64 1)
81*9424f3dcSweiguozhi  %val21 = extractvalue { ptr, i64 } %call2, 0
82*9424f3dcSweiguozhi  %val22 = extractvalue { ptr, i64 } %call2, 1
83*9424f3dcSweiguozhi  br label %exit
84*9424f3dcSweiguozhi
85*9424f3dcSweiguozhibbb4:
86*9424f3dcSweiguozhi  %val31 = load ptr, ptr %p1
87*9424f3dcSweiguozhi  %val32 = load i64, ptr %p2
88*9424f3dcSweiguozhi  br label %exit
89*9424f3dcSweiguozhi
90*9424f3dcSweiguozhiexit:
91*9424f3dcSweiguozhi  %val1 = phi ptr [%val11, %bbb2], [%val21, %bbb3], [%val31, %bbb4]
92*9424f3dcSweiguozhi  %val2 = phi i64 [%val12, %bbb2], [%val22, %bbb3], [%val32, %bbb4]
93*9424f3dcSweiguozhi  %tmp = insertvalue { ptr, i64 } poison, ptr %val1, 0
94*9424f3dcSweiguozhi  %res = insertvalue { ptr, i64 } %tmp, i64 %val2, 1
95*9424f3dcSweiguozhi  ret {ptr, i64} %res
96*9424f3dcSweiguozhi}
97*9424f3dcSweiguozhi
98*9424f3dcSweiguozhi; Test with multiple PHI instructions.
99*9424f3dcSweiguozhidefine {ptr, i64} @test3(i1 %cond1, i1 %cond2, ptr %val31, i64 %val32) {
100*9424f3dcSweiguozhi; CHECK-LABEL: define { ptr, i64 } @test3(
101*9424f3dcSweiguozhi; CHECK-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]], ptr [[VAL31:%.*]], i64 [[VAL32:%.*]]) {
102*9424f3dcSweiguozhi; CHECK-NEXT:    br i1 [[COND1]], label %[[BBB1:.*]], label %[[BBB4:.*]]
103*9424f3dcSweiguozhi; CHECK:       [[BBB1]]:
104*9424f3dcSweiguozhi; CHECK-NEXT:    br i1 [[COND2]], label %[[BBB2:.*]], label %[[BBB3:.*]]
105*9424f3dcSweiguozhi; CHECK:       [[BBB2]]:
106*9424f3dcSweiguozhi; CHECK-NEXT:    [[CALL1:%.*]] = call { ptr, i64 } @bar(i64 0)
107*9424f3dcSweiguozhi; CHECK-NEXT:    br label %[[EXIT:.*]]
108*9424f3dcSweiguozhi; CHECK:       [[BBB3]]:
109*9424f3dcSweiguozhi; CHECK-NEXT:    [[CALL2:%.*]] = call { ptr, i64 } @bar(i64 1)
110*9424f3dcSweiguozhi; CHECK-NEXT:    br label %[[BBB5:.*]]
111*9424f3dcSweiguozhi; CHECK:       [[BBB4]]:
112*9424f3dcSweiguozhi; CHECK-NEXT:    [[CALL3:%.*]] = call { ptr, i64 } @bar(i64 2)
113*9424f3dcSweiguozhi; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { ptr, i64 } poison, ptr [[VAL31]], 0
114*9424f3dcSweiguozhi; CHECK-NEXT:    [[TMP2:%.*]] = insertvalue { ptr, i64 } [[TMP1]], i64 [[VAL32]], 1
115*9424f3dcSweiguozhi; CHECK-NEXT:    br label %[[BBB5]]
116*9424f3dcSweiguozhi; CHECK:       [[BBB5]]:
117*9424f3dcSweiguozhi; CHECK-NEXT:    [[DOTMERGED:%.*]] = phi { ptr, i64 } [ [[CALL2]], %[[BBB3]] ], [ [[TMP2]], %[[BBB4]] ]
118*9424f3dcSweiguozhi; CHECK-NEXT:    br label %[[EXIT]]
119*9424f3dcSweiguozhi; CHECK:       [[EXIT]]:
120*9424f3dcSweiguozhi; CHECK-NEXT:    [[RES_MERGED:%.*]] = phi { ptr, i64 } [ [[CALL1]], %[[BBB2]] ], [ [[DOTMERGED]], %[[BBB5]] ]
121*9424f3dcSweiguozhi; CHECK-NEXT:    ret { ptr, i64 } [[RES_MERGED]]
122*9424f3dcSweiguozhi;
123*9424f3dcSweiguozhi  br i1 %cond1, label %bbb1, label %bbb4
124*9424f3dcSweiguozhi
125*9424f3dcSweiguozhibbb1:
126*9424f3dcSweiguozhi  br i1 %cond2, label %bbb2, label %bbb3
127*9424f3dcSweiguozhi
128*9424f3dcSweiguozhibbb2:
129*9424f3dcSweiguozhi  %call1 = call {ptr, i64} @bar(i64 0)
130*9424f3dcSweiguozhi  %val11 = extractvalue { ptr, i64 } %call1, 0
131*9424f3dcSweiguozhi  %val12 = extractvalue { ptr, i64 } %call1, 1
132*9424f3dcSweiguozhi  br label %exit
133*9424f3dcSweiguozhi
134*9424f3dcSweiguozhibbb3:
135*9424f3dcSweiguozhi  %call2 = call {ptr, i64} @bar(i64 1)
136*9424f3dcSweiguozhi  %val21 = extractvalue { ptr, i64 } %call2, 0
137*9424f3dcSweiguozhi  %val22 = extractvalue { ptr, i64 } %call2, 1
138*9424f3dcSweiguozhi  br label %bbb5
139*9424f3dcSweiguozhi
140*9424f3dcSweiguozhibbb4:
141*9424f3dcSweiguozhi  %call3 = call {ptr, i64} @bar(i64 2)
142*9424f3dcSweiguozhi  br label %bbb5
143*9424f3dcSweiguozhi
144*9424f3dcSweiguozhibbb5:
145*9424f3dcSweiguozhi  %val41 = phi ptr [%val21, %bbb3], [%val31, %bbb4]
146*9424f3dcSweiguozhi  %val42 = phi i64 [%val22, %bbb3], [%val32, %bbb4]
147*9424f3dcSweiguozhi  br label %exit
148*9424f3dcSweiguozhi
149*9424f3dcSweiguozhiexit:
150*9424f3dcSweiguozhi  %val1 = phi ptr [%val11, %bbb2], [%val41, %bbb5]
151*9424f3dcSweiguozhi  %val2 = phi i64 [%val12, %bbb2], [%val42, %bbb5]
152*9424f3dcSweiguozhi  %tmp = insertvalue { ptr, i64 } poison, ptr %val1, 0
153*9424f3dcSweiguozhi  %res = insertvalue { ptr, i64 } %tmp, i64 %val2, 1
154*9424f3dcSweiguozhi  ret {ptr, i64} %res
155*9424f3dcSweiguozhi}
156*9424f3dcSweiguozhi
157*9424f3dcSweiguozhi; Negative test, bbb4 has multiple successors, so we don't add insertvalue to it.
158*9424f3dcSweiguozhidefine {ptr, i64} @test4(i1 %cond1, i1 %cond2, ptr %p1, ptr %p2) {
159*9424f3dcSweiguozhi; CHECK-LABEL: define { ptr, i64 } @test4(
160*9424f3dcSweiguozhi; CHECK-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]], ptr [[P1:%.*]], ptr [[P2:%.*]]) {
161*9424f3dcSweiguozhi; CHECK-NEXT:    br i1 [[COND1]], label %[[BBB1:.*]], label %[[BBB4:.*]]
162*9424f3dcSweiguozhi; CHECK:       [[BBB1]]:
163*9424f3dcSweiguozhi; CHECK-NEXT:    br i1 [[COND2]], label %[[BBB2:.*]], label %[[BBB3:.*]]
164*9424f3dcSweiguozhi; CHECK:       [[BBB2]]:
165*9424f3dcSweiguozhi; CHECK-NEXT:    [[CALL1:%.*]] = call { ptr, i64 } @bar(i64 0)
166*9424f3dcSweiguozhi; CHECK-NEXT:    [[VAL11:%.*]] = extractvalue { ptr, i64 } [[CALL1]], 0
167*9424f3dcSweiguozhi; CHECK-NEXT:    [[VAL12:%.*]] = extractvalue { ptr, i64 } [[CALL1]], 1
168*9424f3dcSweiguozhi; CHECK-NEXT:    br label %[[EXIT:.*]]
169*9424f3dcSweiguozhi; CHECK:       [[BBB3]]:
170*9424f3dcSweiguozhi; CHECK-NEXT:    [[CALL2:%.*]] = call { ptr, i64 } @bar(i64 1)
171*9424f3dcSweiguozhi; CHECK-NEXT:    [[VAL21:%.*]] = extractvalue { ptr, i64 } [[CALL2]], 0
172*9424f3dcSweiguozhi; CHECK-NEXT:    [[VAL22:%.*]] = extractvalue { ptr, i64 } [[CALL2]], 1
173*9424f3dcSweiguozhi; CHECK-NEXT:    br label %[[EXIT]]
174*9424f3dcSweiguozhi; CHECK:       [[BBB4]]:
175*9424f3dcSweiguozhi; CHECK-NEXT:    [[VAL31:%.*]] = load ptr, ptr [[P1]], align 8
176*9424f3dcSweiguozhi; CHECK-NEXT:    [[VAL32:%.*]] = load i64, ptr [[P2]], align 4
177*9424f3dcSweiguozhi; CHECK-NEXT:    [[COND3_NOT:%.*]] = icmp eq i64 [[VAL32]], 0
178*9424f3dcSweiguozhi; CHECK-NEXT:    br i1 [[COND3_NOT]], label %[[EXIT]], label %[[BBB4]]
179*9424f3dcSweiguozhi; CHECK:       [[EXIT]]:
180*9424f3dcSweiguozhi; CHECK-NEXT:    [[VAL1:%.*]] = phi ptr [ [[VAL11]], %[[BBB2]] ], [ [[VAL21]], %[[BBB3]] ], [ [[VAL31]], %[[BBB4]] ]
181*9424f3dcSweiguozhi; CHECK-NEXT:    [[VAL2:%.*]] = phi i64 [ [[VAL12]], %[[BBB2]] ], [ [[VAL22]], %[[BBB3]] ], [ [[VAL32]], %[[BBB4]] ]
182*9424f3dcSweiguozhi; CHECK-NEXT:    [[TMP:%.*]] = insertvalue { ptr, i64 } poison, ptr [[VAL1]], 0
183*9424f3dcSweiguozhi; CHECK-NEXT:    [[RES:%.*]] = insertvalue { ptr, i64 } [[TMP]], i64 [[VAL2]], 1
184*9424f3dcSweiguozhi; CHECK-NEXT:    ret { ptr, i64 } [[RES]]
185*9424f3dcSweiguozhi;
186*9424f3dcSweiguozhi  br i1 %cond1, label %bbb1, label %bbb4
187*9424f3dcSweiguozhi
188*9424f3dcSweiguozhibbb1:
189*9424f3dcSweiguozhi  br i1 %cond2, label %bbb2, label %bbb3
190*9424f3dcSweiguozhi
191*9424f3dcSweiguozhibbb2:
192*9424f3dcSweiguozhi  %call1 = call {ptr, i64} @bar(i64 0)
193*9424f3dcSweiguozhi  %val11 = extractvalue { ptr, i64 } %call1, 0
194*9424f3dcSweiguozhi  %val12 = extractvalue { ptr, i64 } %call1, 1
195*9424f3dcSweiguozhi  br label %exit
196*9424f3dcSweiguozhi
197*9424f3dcSweiguozhibbb3:
198*9424f3dcSweiguozhi  %call2 = call {ptr, i64} @bar(i64 1)
199*9424f3dcSweiguozhi  %val21 = extractvalue { ptr, i64 } %call2, 0
200*9424f3dcSweiguozhi  %val22 = extractvalue { ptr, i64 } %call2, 1
201*9424f3dcSweiguozhi  br label %exit
202*9424f3dcSweiguozhi
203*9424f3dcSweiguozhibbb4:
204*9424f3dcSweiguozhi  %val31 = load ptr, ptr %p1
205*9424f3dcSweiguozhi  %val32 = load i64, ptr %p2
206*9424f3dcSweiguozhi  %cond3 = icmp ne i64 %val32, 0
207*9424f3dcSweiguozhi  br i1 %cond3, label %bbb4, label %exit
208*9424f3dcSweiguozhi
209*9424f3dcSweiguozhiexit:
210*9424f3dcSweiguozhi  %val1 = phi ptr [%val11, %bbb2], [%val21, %bbb3], [%val31, %bbb4]
211*9424f3dcSweiguozhi  %val2 = phi i64 [%val12, %bbb2], [%val22, %bbb3], [%val32, %bbb4]
212*9424f3dcSweiguozhi  %tmp = insertvalue { ptr, i64 } poison, ptr %val1, 0
213*9424f3dcSweiguozhi  %res = insertvalue { ptr, i64 } %tmp, i64 %val2, 1
214*9424f3dcSweiguozhi  ret {ptr, i64} %res
215*9424f3dcSweiguozhi}
216*9424f3dcSweiguozhi
217*9424f3dcSweiguozhi; Negative test, %.elt2 is defined in bb %end, it can't be accessed from %then,
218*9424f3dcSweiguozhi; so we can't add insertvalue to %then.
219*9424f3dcSweiguozhidefine { ptr, i64 } @test5({ ptr, i64 } %src, ptr %pointer, i1 %cond) {
220*9424f3dcSweiguozhi; CHECK-LABEL: define { ptr, i64 } @test5(
221*9424f3dcSweiguozhi; CHECK-SAME: { ptr, i64 } [[SRC:%.*]], ptr [[POINTER:%.*]], i1 [[COND:%.*]]) {
222*9424f3dcSweiguozhi; CHECK-NEXT:  [[ENTRY:.*:]]
223*9424f3dcSweiguozhi; CHECK-NEXT:    br i1 [[COND]], label %[[THEN:.*]], label %[[ELSE:.*]]
224*9424f3dcSweiguozhi; CHECK:       [[THEN]]:
225*9424f3dcSweiguozhi; CHECK-NEXT:    store ptr null, ptr [[POINTER]], align 8
226*9424f3dcSweiguozhi; CHECK-NEXT:    br label %[[END:.*]]
227*9424f3dcSweiguozhi; CHECK:       [[ELSE]]:
228*9424f3dcSweiguozhi; CHECK-NEXT:    [[DOTELT1:%.*]] = extractvalue { ptr, i64 } [[SRC]], 0
229*9424f3dcSweiguozhi; CHECK-NEXT:    br label %[[END]]
230*9424f3dcSweiguozhi; CHECK:       [[END]]:
231*9424f3dcSweiguozhi; CHECK-NEXT:    [[TMP6:%.*]] = phi ptr [ [[DOTELT1]], %[[ELSE]] ], [ null, %[[THEN]] ]
232*9424f3dcSweiguozhi; CHECK-NEXT:    [[DOTELT2:%.*]] = extractvalue { ptr, i64 } [[SRC]], 1
233*9424f3dcSweiguozhi; CHECK-NEXT:    [[TMP7:%.*]] = insertvalue { ptr, i64 } zeroinitializer, ptr [[TMP6]], 0
234*9424f3dcSweiguozhi; CHECK-NEXT:    [[TMP8:%.*]] = insertvalue { ptr, i64 } [[TMP7]], i64 [[DOTELT2]], 1
235*9424f3dcSweiguozhi; CHECK-NEXT:    ret { ptr, i64 } [[TMP8]]
236*9424f3dcSweiguozhi;
237*9424f3dcSweiguozhientry:
238*9424f3dcSweiguozhi  br i1 %cond, label %then, label %else
239*9424f3dcSweiguozhi
240*9424f3dcSweiguozhithen:
241*9424f3dcSweiguozhi  store ptr null, ptr %pointer, align 8
242*9424f3dcSweiguozhi  br label %end
243*9424f3dcSweiguozhi
244*9424f3dcSweiguozhielse:
245*9424f3dcSweiguozhi  %.elt1 = extractvalue { ptr, i64 } %src, 0
246*9424f3dcSweiguozhi  br label %end
247*9424f3dcSweiguozhi
248*9424f3dcSweiguozhiend:
249*9424f3dcSweiguozhi  %elt = phi ptr [ %.elt1, %else ], [ null, %then ]
250*9424f3dcSweiguozhi  %.elt2 = extractvalue { ptr, i64 } %src, 1
251*9424f3dcSweiguozhi  %agg1 = insertvalue { ptr, i64 } zeroinitializer, ptr %elt, 0
252*9424f3dcSweiguozhi  %res = insertvalue { ptr, i64 } %agg1, i64 %.elt2, 1
253*9424f3dcSweiguozhi  ret { ptr, i64 } %res
254*9424f3dcSweiguozhi}
255*9424f3dcSweiguozhi
256*9424f3dcSweiguozhi; Negative test, we should not add insertvalue to inner loops.
257*9424f3dcSweiguozhidefine { i64, ptr } @test6({ i64, ptr } %agg1, i1 %cond1, i1 %cond2, { i64, ptr } %agg3) {
258*9424f3dcSweiguozhi; CHECK-LABEL: define { i64, ptr } @test6(
259*9424f3dcSweiguozhi; CHECK-SAME: { i64, ptr } [[AGG1:%.*]], i1 [[COND1:%.*]], i1 [[COND2:%.*]], { i64, ptr } [[AGG3:%.*]]) {
260*9424f3dcSweiguozhi; CHECK-NEXT:  [[ENTRY:.*]]:
261*9424f3dcSweiguozhi; CHECK-NEXT:    [[F10:%.*]] = extractvalue { i64, ptr } [[AGG1]], 0
262*9424f3dcSweiguozhi; CHECK-NEXT:    [[F11:%.*]] = extractvalue { i64, ptr } [[AGG1]], 1
263*9424f3dcSweiguozhi; CHECK-NEXT:    br label %[[HEADER:.*]]
264*9424f3dcSweiguozhi; CHECK:       [[HEADER]]:
265*9424f3dcSweiguozhi; CHECK-NEXT:    [[DOTSROA_01_0:%.*]] = phi i64 [ [[F10]], %[[ENTRY]] ], [ [[DOTSROA_01_1:%.*]], %[[LATCH:.*]] ]
266*9424f3dcSweiguozhi; CHECK-NEXT:    [[DOTSROA_3_0:%.*]] = phi ptr [ [[F11]], %[[ENTRY]] ], [ [[DOTSROA_3_1:%.*]], %[[LATCH]] ]
267*9424f3dcSweiguozhi; CHECK-NEXT:    br i1 [[COND1]], label %[[CHECK:.*]], label %[[EXIT:.*]]
268*9424f3dcSweiguozhi; CHECK:       [[CHECK]]:
269*9424f3dcSweiguozhi; CHECK-NEXT:    br i1 [[COND2]], label %[[THEN:.*]], label %[[ELSE:.*]]
270*9424f3dcSweiguozhi; CHECK:       [[THEN]]:
271*9424f3dcSweiguozhi; CHECK-NEXT:    [[F30:%.*]] = extractvalue { i64, ptr } [[AGG3]], 0
272*9424f3dcSweiguozhi; CHECK-NEXT:    [[F31:%.*]] = extractvalue { i64, ptr } [[AGG3]], 1
273*9424f3dcSweiguozhi; CHECK-NEXT:    br label %[[LATCH]]
274*9424f3dcSweiguozhi; CHECK:       [[ELSE]]:
275*9424f3dcSweiguozhi; CHECK-NEXT:    br label %[[LATCH]]
276*9424f3dcSweiguozhi; CHECK:       [[LATCH]]:
277*9424f3dcSweiguozhi; CHECK-NEXT:    [[DOTSROA_01_1]] = phi i64 [ [[F30]], %[[THEN]] ], [ [[DOTSROA_01_0]], %[[ELSE]] ]
278*9424f3dcSweiguozhi; CHECK-NEXT:    [[DOTSROA_3_1]] = phi ptr [ [[F31]], %[[THEN]] ], [ [[DOTSROA_3_0]], %[[ELSE]] ]
279*9424f3dcSweiguozhi; CHECK-NEXT:    br label %[[HEADER]]
280*9424f3dcSweiguozhi; CHECK:       [[EXIT]]:
281*9424f3dcSweiguozhi; CHECK-NEXT:    [[DOTFCA_0_INSERT:%.*]] = insertvalue { i64, ptr } zeroinitializer, i64 [[DOTSROA_01_0]], 0
282*9424f3dcSweiguozhi; CHECK-NEXT:    [[DOTFCA_1_INSERT:%.*]] = insertvalue { i64, ptr } [[DOTFCA_0_INSERT]], ptr [[DOTSROA_3_0]], 1
283*9424f3dcSweiguozhi; CHECK-NEXT:    ret { i64, ptr } [[DOTFCA_1_INSERT]]
284*9424f3dcSweiguozhi;
285*9424f3dcSweiguozhientry:
286*9424f3dcSweiguozhi  %f10 = extractvalue { i64, ptr } %agg1, 0
287*9424f3dcSweiguozhi  %f11 = extractvalue { i64, ptr } %agg1, 1
288*9424f3dcSweiguozhi  br label %header
289*9424f3dcSweiguozhi
290*9424f3dcSweiguozhiheader:
291*9424f3dcSweiguozhi  %.sroa.01.0 = phi i64 [ %f10, %entry ], [ %.sroa.01.1, %latch ]
292*9424f3dcSweiguozhi  %.sroa.3.0 = phi ptr [ %f11, %entry ], [ %.sroa.3.1, %latch ]
293*9424f3dcSweiguozhi  br i1 %cond1, label %check, label %exit
294*9424f3dcSweiguozhi
295*9424f3dcSweiguozhicheck:
296*9424f3dcSweiguozhi  br i1 %cond2, label %then, label %else
297*9424f3dcSweiguozhi
298*9424f3dcSweiguozhithen:
299*9424f3dcSweiguozhi  %f30 = extractvalue { i64, ptr } %agg3, 0
300*9424f3dcSweiguozhi  %f31 = extractvalue { i64, ptr } %agg3, 1
301*9424f3dcSweiguozhi  br label %latch
302*9424f3dcSweiguozhi
303*9424f3dcSweiguozhielse:
304*9424f3dcSweiguozhi  br label %latch
305*9424f3dcSweiguozhi
306*9424f3dcSweiguozhilatch:
307*9424f3dcSweiguozhi  %.sroa.01.1 = phi i64 [ %f30, %then ], [ %.sroa.01.0, %else ]
308*9424f3dcSweiguozhi  %.sroa.3.1 = phi ptr [ %f31, %then ], [ %.sroa.3.0, %else ]
309*9424f3dcSweiguozhi  br label %header
310*9424f3dcSweiguozhi
311*9424f3dcSweiguozhiexit:
312*9424f3dcSweiguozhi  %.fca.0.insert = insertvalue { i64, ptr } zeroinitializer, i64 %.sroa.01.0, 0
313*9424f3dcSweiguozhi  %.fca.1.insert = insertvalue { i64, ptr } %.fca.0.insert, ptr %.sroa.3.0, 1
314*9424f3dcSweiguozhi  ret { i64, ptr } %.fca.1.insert
315*9424f3dcSweiguozhi}
316*9424f3dcSweiguozhi
317*9424f3dcSweiguozhi; Negative test, don't construct constant aggregate.
318*9424f3dcSweiguozhidefine {ptr, i64} @test7(i1 %cond1, ptr %p1) {
319*9424f3dcSweiguozhi; CHECK-LABEL: define { ptr, i64 } @test7(
320*9424f3dcSweiguozhi; CHECK-SAME: i1 [[COND1:%.*]], ptr [[P1:%.*]]) {
321*9424f3dcSweiguozhi; CHECK-NEXT:    br i1 [[COND1]], label %[[BBB1:.*]], label %[[BBB2:.*]]
322*9424f3dcSweiguozhi; CHECK:       [[BBB1]]:
323*9424f3dcSweiguozhi; CHECK-NEXT:    [[CALL1:%.*]] = call { ptr, i64 } @bar(i64 0)
324*9424f3dcSweiguozhi; CHECK-NEXT:    [[VAL11:%.*]] = extractvalue { ptr, i64 } [[CALL1]], 0
325*9424f3dcSweiguozhi; CHECK-NEXT:    [[VAL12:%.*]] = extractvalue { ptr, i64 } [[CALL1]], 1
326*9424f3dcSweiguozhi; CHECK-NEXT:    br label %[[EXIT:.*]]
327*9424f3dcSweiguozhi; CHECK:       [[BBB2]]:
328*9424f3dcSweiguozhi; CHECK-NEXT:    br label %[[EXIT]]
329*9424f3dcSweiguozhi; CHECK:       [[EXIT]]:
330*9424f3dcSweiguozhi; CHECK-NEXT:    [[VAL1:%.*]] = phi ptr [ [[VAL11]], %[[BBB1]] ], [ undef, %[[BBB2]] ]
331*9424f3dcSweiguozhi; CHECK-NEXT:    [[VAL2:%.*]] = phi i64 [ [[VAL12]], %[[BBB1]] ], [ 1, %[[BBB2]] ]
332*9424f3dcSweiguozhi; CHECK-NEXT:    [[TMP:%.*]] = insertvalue { ptr, i64 } poison, ptr [[VAL1]], 0
333*9424f3dcSweiguozhi; CHECK-NEXT:    [[RES:%.*]] = insertvalue { ptr, i64 } [[TMP]], i64 [[VAL2]], 1
334*9424f3dcSweiguozhi; CHECK-NEXT:    ret { ptr, i64 } [[RES]]
335*9424f3dcSweiguozhi;
336*9424f3dcSweiguozhi  br i1 %cond1, label %bbb1, label %bbb2
337*9424f3dcSweiguozhi
338*9424f3dcSweiguozhibbb1:
339*9424f3dcSweiguozhi  %call1 = call {ptr, i64} @bar(i64 0)
340*9424f3dcSweiguozhi  %val11 = extractvalue { ptr, i64 } %call1, 0
341*9424f3dcSweiguozhi  %val12 = extractvalue { ptr, i64 } %call1, 1
342*9424f3dcSweiguozhi  br label %exit
343*9424f3dcSweiguozhi
344*9424f3dcSweiguozhibbb2:
345*9424f3dcSweiguozhi  br label %exit
346*9424f3dcSweiguozhi
347*9424f3dcSweiguozhiexit:
348*9424f3dcSweiguozhi  %val1 = phi ptr [%val11, %bbb1], [undef, %bbb2]
349*9424f3dcSweiguozhi  %val2 = phi i64 [%val12, %bbb1], [1, %bbb2]
350*9424f3dcSweiguozhi  %tmp = insertvalue { ptr, i64 } poison, ptr %val1, 0
351*9424f3dcSweiguozhi  %res = insertvalue { ptr, i64 } %tmp, i64 %val2, 1
352*9424f3dcSweiguozhi  ret {ptr, i64} %res
353*9424f3dcSweiguozhi}
354