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()
7
8declare void @usei32(i32)
9declare void @usei32i32agg({ i32, i32 })
10
11; Most basic test - we explode the original aggregate into it's elements,
12; and then merge them back together exactly the way they were.
13; We should just return the source aggregate.
14define { i32, i32 } @test0({ i32, i32 } %srcagg) {
15; CHECK-LABEL: @test0(
16; CHECK-NEXT:    ret { i32, i32 } [[SRCAGG:%.*]]
17;
18  %i0 = extractvalue { i32, i32 } %srcagg, 0
19  %i1 = extractvalue { i32, i32 } %srcagg, 1
20  %i2 = insertvalue { i32, i32 } undef, i32 %i0, 0
21  %i3 = insertvalue { i32, i32 } %i2, i32 %i1, 1
22  ret { i32, i32 } %i3
23}
24
25; Arrays are still aggregates
26define [2 x i32] @test1([2 x i32] %srcagg) {
27; CHECK-LABEL: @test1(
28; CHECK-NEXT:    ret [2 x i32] [[SRCAGG:%.*]]
29;
30  %i0 = extractvalue [2 x i32] %srcagg, 0
31  %i1 = extractvalue [2 x i32] %srcagg, 1
32  %i2 = insertvalue [2 x i32] undef, i32 %i0, 0
33  %i3 = insertvalue [2 x i32] %i2, i32 %i1, 1
34  ret [2 x i32] %i3
35}
36
37; Right now we don't deal with case where there are more than 2 elements.
38; FIXME: should we?
39define [3 x i32] @test2([3 x i32] %srcagg) {
40; CHECK-LABEL: @test2(
41; CHECK-NEXT:    [[I0:%.*]] = extractvalue [3 x i32] [[SRCAGG:%.*]], 0
42; CHECK-NEXT:    [[I1:%.*]] = extractvalue [3 x i32] [[SRCAGG]], 1
43; CHECK-NEXT:    [[I2:%.*]] = extractvalue [3 x i32] [[SRCAGG]], 2
44; CHECK-NEXT:    [[I3:%.*]] = insertvalue [3 x i32] undef, i32 [[I0]], 0
45; CHECK-NEXT:    [[I4:%.*]] = insertvalue [3 x i32] [[I3]], i32 [[I1]], 1
46; CHECK-NEXT:    [[I5:%.*]] = insertvalue [3 x i32] [[I4]], i32 [[I2]], 2
47; CHECK-NEXT:    ret [3 x i32] [[I5]]
48;
49  %i0 = extractvalue [3 x i32] %srcagg, 0
50  %i1 = extractvalue [3 x i32] %srcagg, 1
51  %i2 = extractvalue [3 x i32] %srcagg, 2
52  %i3 = insertvalue [3 x i32] undef, i32 %i0, 0
53  %i4 = insertvalue [3 x i32] %i3, i32 %i1, 1
54  %i5 = insertvalue [3 x i32] %i4, i32 %i2, 2
55  ret [3 x i32] %i5
56}
57
58; Likewise, we only deal with a single-level aggregates.
59; FIXME: should we?
60define {{ i32, i32 }} @test3({{ i32, i32 }} %srcagg) {
61; CHECK-LABEL: @test3(
62; CHECK-NEXT:    [[I0:%.*]] = extractvalue { { i32, i32 } } [[SRCAGG:%.*]], 0, 0
63; CHECK-NEXT:    [[I1:%.*]] = extractvalue { { i32, i32 } } [[SRCAGG]], 0, 1
64; CHECK-NEXT:    [[I2:%.*]] = insertvalue { { i32, i32 } } undef, i32 [[I0]], 0, 0
65; CHECK-NEXT:    [[I3:%.*]] = insertvalue { { i32, i32 } } [[I2]], i32 [[I1]], 0, 1
66; CHECK-NEXT:    ret { { i32, i32 } } [[I3]]
67;
68  %i0 = extractvalue {{ i32, i32 }} %srcagg, 0, 0
69  %i1 = extractvalue {{ i32, i32 }} %srcagg, 0, 1
70  %i2 = insertvalue {{ i32, i32 }} undef, i32 %i0, 0, 0
71  %i3 = insertvalue {{ i32, i32 }} %i2, i32 %i1, 0, 1
72  ret {{ i32, i32 }} %i3
73}
74
75; This is fine, however, all elements are on the same level
76define { i32, { i32 } } @test4({ i32, { i32 } } %srcagg) {
77; CHECK-LABEL: @test4(
78; CHECK-NEXT:    ret { i32, { i32 } } [[SRCAGG:%.*]]
79;
80  %i0 = extractvalue { i32, { i32 } } %srcagg, 0
81  %i1 = extractvalue { i32, { i32 } } %srcagg, 1
82  %i2 = insertvalue { i32, { i32 } } undef, i32 %i0, 0
83  %i3 = insertvalue { i32, { i32 } } %i2, { i32 } %i1, 1
84  ret { i32, { i32 } } %i3
85}
86
87; All element of the newly-created aggregate must come from the same base
88; aggregate. Here the second element comes from some other origin.
89define { i32, i32 } @negative_test5({ i32, i32 } %srcagg, i32 %replacement) {
90; CHECK-LABEL: @negative_test5(
91; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32 } [[SRCAGG:%.*]], 0
92; CHECK-NEXT:    [[I2:%.*]] = insertvalue { i32, i32 } undef, i32 [[I0]], 0
93; CHECK-NEXT:    [[I3:%.*]] = insertvalue { i32, i32 } [[I2]], i32 [[REPLACEMENT:%.*]], 1
94; CHECK-NEXT:    ret { i32, i32 } [[I3]]
95;
96  %i0 = extractvalue { i32, i32 } %srcagg, 0
97  ; %i1 = extractvalue { i32, i32 } %srcagg, 1
98  %i2 = insertvalue { i32, i32 } undef, i32 %i0, 0
99  %i3 = insertvalue { i32, i32 } %i2, i32 %replacement, 1
100  ret { i32, i32 } %i3
101}
102
103; Here we don't know the value of second element of %otheragg,
104define { i32, i32 } @negative_test6({ i32, i32 } %srcagg, { i32, i32 } %otheragg) {
105; CHECK-LABEL: @negative_test6(
106; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32 } [[SRCAGG:%.*]], 0
107; CHECK-NEXT:    [[I2:%.*]] = insertvalue { i32, i32 } [[OTHERAGG:%.*]], i32 [[I0]], 0
108; CHECK-NEXT:    ret { i32, i32 } [[I2]]
109;
110  %i0 = extractvalue { i32, i32 } %srcagg, 0
111  ; %i1 = extractvalue { i32, i32 } %srcagg, 1
112  %i2 = insertvalue { i32, i32 } %otheragg, i32 %i0, 0
113  ret { i32, i32 } %i2
114}
115
116; All element of the newly-created aggregate must come from the same base
117; aggregate. Here different elements come from different base aggregates.
118define { i32, i32 } @negative_test7({ i32, i32 } %srcagg0, { i32, i32 } %srcagg1) {
119; CHECK-LABEL: @negative_test7(
120; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32 } [[SRCAGG0:%.*]], 0
121; CHECK-NEXT:    [[I3:%.*]] = extractvalue { i32, i32 } [[SRCAGG1:%.*]], 1
122; CHECK-NEXT:    [[I4:%.*]] = insertvalue { i32, i32 } undef, i32 [[I0]], 0
123; CHECK-NEXT:    [[I5:%.*]] = insertvalue { i32, i32 } [[I4]], i32 [[I3]], 1
124; CHECK-NEXT:    ret { i32, i32 } [[I5]]
125;
126  %i0 = extractvalue { i32, i32 } %srcagg0, 0
127  ; %i1 = extractvalue { i32, i32 } %srcagg0, 1
128
129  ; %i2 = extractvalue { i32, i32 } %srcagg1, 0
130  %i3 = extractvalue { i32, i32 } %srcagg1, 1
131
132  %i4 = insertvalue { i32, i32 } undef, i32 %i0, 0
133  %i5 = insertvalue { i32, i32 } %i4, i32 %i3, 1
134  ret { i32, i32 } %i5
135}
136
137; Here the element order is swapped as compared to the base aggregate.
138define { i32, i32 } @negative_test8({ i32, i32 } %srcagg) {
139; CHECK-LABEL: @negative_test8(
140; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32 } [[SRCAGG:%.*]], 0
141; CHECK-NEXT:    [[I1:%.*]] = extractvalue { i32, i32 } [[SRCAGG]], 1
142; CHECK-NEXT:    [[I2:%.*]] = insertvalue { i32, i32 } undef, i32 [[I0]], 1
143; CHECK-NEXT:    [[I3:%.*]] = insertvalue { i32, i32 } [[I2]], i32 [[I1]], 0
144; CHECK-NEXT:    ret { i32, i32 } [[I3]]
145;
146  %i0 = extractvalue { i32, i32 } %srcagg, 0
147  %i1 = extractvalue { i32, i32 } %srcagg, 1
148  %i2 = insertvalue { i32, i32 } undef, i32 %i0, 1
149  %i3 = insertvalue { i32, i32 } %i2, i32 %i1, 0
150  ret { i32, i32 } %i3
151}
152
153; Here both elements of the new aggregate come from the same element of the old aggregate.
154define { i32, i32 } @negative_test9({ i32, i32 } %srcagg) {
155; CHECK-LABEL: @negative_test9(
156; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32 } [[SRCAGG:%.*]], 0
157; CHECK-NEXT:    [[I2:%.*]] = insertvalue { i32, i32 } undef, i32 [[I0]], 0
158; CHECK-NEXT:    [[I3:%.*]] = insertvalue { i32, i32 } [[I2]], i32 [[I0]], 1
159; CHECK-NEXT:    ret { i32, i32 } [[I3]]
160;
161  %i0 = extractvalue { i32, i32 } %srcagg, 0
162  ; %i1 = extractvalue { i32, i32 } %srcagg, 1
163  %i2 = insertvalue { i32, i32 } undef, i32 %i0, 0
164  %i3 = insertvalue { i32, i32 } %i2, i32 %i0, 1
165  ret { i32, i32 } %i3
166}
167
168; Here the second element of the new aggregate is undef, , so we must keep this as-is, because in %srcagg it might be poison.
169; FIXME: defer to noundef attribute on %srcagg
170define { i32, i32 } @negative_test10({ i32, i32 } %srcagg) {
171; CHECK-LABEL: @negative_test10(
172; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32 } [[SRCAGG:%.*]], 0
173; CHECK-NEXT:    [[I2:%.*]] = insertvalue { i32, i32 } undef, i32 [[I0]], 0
174; CHECK-NEXT:    ret { i32, i32 } [[I2]]
175;
176  %i0 = extractvalue { i32, i32 } %srcagg, 0
177  ; %i1 = extractvalue { i32, i32 } %srcagg, 1
178  %i2 = insertvalue { i32, i32 } undef, i32 %i0, 0
179  ret { i32, i32 } %i2
180}
181
182; Here the second element of the new aggregate is undef, so we must keep this as-is, because in %srcagg it might be poison.
183; FIXME: defer to noundef attribute on %srcagg
184define { i32, i32 } @negative_test11({ i32, i32 } %srcagg) {
185; CHECK-LABEL: @negative_test11(
186; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32 } [[SRCAGG:%.*]], 0
187; CHECK-NEXT:    [[I2:%.*]] = insertvalue { i32, i32 } undef, i32 [[I0]], 0
188; CHECK-NEXT:    [[I3:%.*]] = insertvalue { i32, i32 } [[I2]], i32 undef, 1
189; CHECK-NEXT:    ret { i32, i32 } [[I3]]
190;
191  %i0 = extractvalue { i32, i32 } %srcagg, 0
192  ; %i1 = extractvalue { i32, i32 } %srcagg, 1
193  %i2 = insertvalue { i32, i32 } undef, i32 %i0, 0
194  %i3 = insertvalue { i32, i32 } %i2, i32 undef, 1
195  ret { i32, i32 } %i3
196}
197
198; This fold does not care whether or not intermediate instructions have extra uses.
199define { i32, i32 } @test12({ i32, i32 } %srcagg) {
200; CHECK-LABEL: @test12(
201; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32 } [[SRCAGG:%.*]], 0
202; CHECK-NEXT:    call void @usei32(i32 [[I0]])
203; CHECK-NEXT:    [[I1:%.*]] = extractvalue { i32, i32 } [[SRCAGG]], 1
204; CHECK-NEXT:    call void @usei32(i32 [[I1]])
205; CHECK-NEXT:    [[I2:%.*]] = insertvalue { i32, i32 } undef, i32 [[I0]], 0
206; CHECK-NEXT:    call void @usei32i32agg({ i32, i32 } [[I2]])
207; CHECK-NEXT:    ret { i32, i32 } [[SRCAGG]]
208;
209  %i0 = extractvalue { i32, i32 } %srcagg, 0
210  call void @usei32(i32 %i0)
211  %i1 = extractvalue { i32, i32 } %srcagg, 1
212  call void @usei32(i32 %i1)
213  %i2 = insertvalue { i32, i32 } undef, i32 %i0, 0
214  call void @usei32i32agg({ i32, i32 } %i2)
215  %i3 = insertvalue { i32, i32 } %i2, i32 %i1, 1
216  ret { i32, i32 } %i3
217}
218
219; Even though we originally store %i1 into first element, it is later
220; overwritten with %i0, so all is fine.
221define { i32, i32 } @test13({ i32, i32 } %srcagg) {
222; CHECK-LABEL: @test13(
223; CHECK-NEXT:    ret { i32, i32 } [[SRCAGG:%.*]]
224;
225  %i0 = extractvalue { i32, i32 } %srcagg, 0
226  %i1 = extractvalue { i32, i32 } %srcagg, 1
227  %i2 = insertvalue { i32, i32 } undef, i32 %i1, 0
228  %i3 = insertvalue { i32, i32 } %i2, i32 %i0, 0
229  %i4 = insertvalue { i32, i32 } %i3, i32 %i1, 1
230  ret { i32, i32 } %i4
231}
232
233; The aggregate type must match exactly between the original and recreation.
234define { i32, i32 } @negative_test14({ i32, i32, i32 } %srcagg) {
235; CHECK-LABEL: @negative_test14(
236; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32, i32 } [[SRCAGG:%.*]], 0
237; CHECK-NEXT:    [[I1:%.*]] = extractvalue { i32, i32, i32 } [[SRCAGG]], 1
238; CHECK-NEXT:    [[I2:%.*]] = insertvalue { i32, i32 } undef, i32 [[I0]], 0
239; CHECK-NEXT:    [[I3:%.*]] = insertvalue { i32, i32 } [[I2]], i32 [[I1]], 1
240; CHECK-NEXT:    ret { i32, i32 } [[I3]]
241;
242  %i0 = extractvalue { i32, i32, i32 } %srcagg, 0
243  %i1 = extractvalue { i32, i32, i32 } %srcagg, 1
244  %i2 = insertvalue { i32, i32 } undef, i32 %i0, 0
245  %i3 = insertvalue { i32, i32 } %i2, i32 %i1, 1
246  ret { i32, i32 } %i3
247}
248define { i32, i32 } @negative_test15({ i32, {i32} } %srcagg) {
249; CHECK-LABEL: @negative_test15(
250; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, { i32 } } [[SRCAGG:%.*]], 0
251; CHECK-NEXT:    [[I1:%.*]] = extractvalue { i32, { i32 } } [[SRCAGG]], 1, 0
252; CHECK-NEXT:    [[I2:%.*]] = insertvalue { i32, i32 } undef, i32 [[I0]], 0
253; CHECK-NEXT:    [[I3:%.*]] = insertvalue { i32, i32 } [[I2]], i32 [[I1]], 1
254; CHECK-NEXT:    ret { i32, i32 } [[I3]]
255;
256  %i0 = extractvalue { i32, {i32} } %srcagg, 0
257  %i1 = extractvalue { i32, {i32} } %srcagg, 1, 0
258  %i2 = insertvalue { i32, i32 } undef, i32 %i0, 0
259  %i3 = insertvalue { i32, i32 } %i2, i32 %i1, 1
260  ret { i32, i32 } %i3
261}
262
263; Just because there are predecessors doesn't mean we should look into them.
264define { i32, i32 } @test16({ i32, i32 } %srcagg) {
265; CHECK-LABEL: @test16(
266; CHECK-NEXT:  entry:
267; CHECK-NEXT:    br label [[END:%.*]]
268; CHECK:       end:
269; CHECK-NEXT:    ret { i32, i32 } [[SRCAGG:%.*]]
270;
271entry:
272  br label %end
273end:
274  %i0 = extractvalue { i32, i32 } %srcagg, 0
275  %i1 = extractvalue { i32, i32 } %srcagg, 1
276  %i2 = insertvalue { i32, i32 } undef, i32 %i0, 0
277  %i3 = insertvalue { i32, i32 } %i2, i32 %i1, 1
278  ret { i32, i32 } %i3
279}
280
281; Again, we should first try to perform local reasoning, without looking to predecessors.
282define { i32, i32 } @test17({ i32, i32 } %srcagg0, { i32, i32 } %srcagg1, i1 %c) {
283; CHECK-LABEL: @test17(
284; CHECK-NEXT:  entry:
285; CHECK-NEXT:    br i1 [[C:%.*]], label [[INTERMEDIATE:%.*]], label [[END:%.*]]
286; CHECK:       intermediate:
287; CHECK-NEXT:    br label [[END]]
288; CHECK:       end:
289; CHECK-NEXT:    [[SRCAGG_PHI:%.*]] = phi { i32, i32 } [ [[SRCAGG0:%.*]], [[ENTRY:%.*]] ], [ [[SRCAGG1:%.*]], [[INTERMEDIATE]] ]
290; CHECK-NEXT:    ret { i32, i32 } [[SRCAGG_PHI]]
291;
292entry:
293  br i1 %c, label %intermediate, label %end
294intermediate:
295  br label %end
296end:
297  %srcagg.phi = phi { i32, i32 } [ %srcagg0, %entry ], [ %srcagg1, %intermediate ]
298  %i0 = extractvalue { i32, i32 } %srcagg.phi, 0
299  %i1 = extractvalue { i32, i32 } %srcagg.phi, 1
300  %i2 = insertvalue { i32, i32 } undef, i32 %i0, 0
301  %i3 = insertvalue { i32, i32 } %i2, i32 %i1, 1
302  ret { i32, i32 } %i3
303}
304