[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / InstCombine / phi-of-extractvalues.ll
blob020b98407984d0c75bb72179cf1d2ef74d3b5718
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -instcombine < %s | FileCheck %s
4 declare void @usei32(i32)
6 ; If we have a phi of extractvalues, we can sink it,
7 ; Here, we only need a PHI for extracted values.
8 define i32 @test0({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c) {
9 ; CHECK-LABEL: @test0(
10 ; CHECK-NEXT:  entry:
11 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
12 ; CHECK:       left:
13 ; CHECK-NEXT:    br label [[END:%.*]]
14 ; CHECK:       right:
15 ; CHECK-NEXT:    br label [[END]]
16 ; CHECK:       end:
17 ; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [ [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ]
18 ; CHECK-NEXT:    [[R:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT_PN]], 0
19 ; CHECK-NEXT:    ret i32 [[R]]
21 entry:
22   br i1 %c, label %left, label %right
24 left:
25   %i0 = extractvalue { i32, i32 } %agg_left, 0
26   br label %end
28 right:
29   %i1 = extractvalue { i32, i32 } %agg_right, 0
30   br label %end
32 end:
33   %r = phi i32 [ %i0, %left ], [ %i1, %right ]
34   ret i32 %r
37 ; But only if the extractvalues have no extra uses
38 define i32 @test1_extrause0({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c) {
39 ; CHECK-LABEL: @test1_extrause0(
40 ; CHECK-NEXT:  entry:
41 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
42 ; CHECK:       left:
43 ; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT:%.*]], 0
44 ; CHECK-NEXT:    call void @usei32(i32 [[I0]])
45 ; CHECK-NEXT:    br label [[END:%.*]]
46 ; CHECK:       right:
47 ; CHECK-NEXT:    [[I1:%.*]] = extractvalue { i32, i32 } [[AGG_RIGHT:%.*]], 0
48 ; CHECK-NEXT:    br label [[END]]
49 ; CHECK:       end:
50 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[I0]], [[LEFT]] ], [ [[I1]], [[RIGHT]] ]
51 ; CHECK-NEXT:    ret i32 [[R]]
53 entry:
54   br i1 %c, label %left, label %right
56 left:
57   %i0 = extractvalue { i32, i32 } %agg_left, 0
58   call void  @usei32(i32 %i0)
59   br label %end
61 right:
62   %i1 = extractvalue { i32, i32 } %agg_right, 0
63   br label %end
65 end:
66   %r = phi i32 [ %i0, %left ], [ %i1, %right ]
67   ret i32 %r
69 define i32 @test2_extrause1({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c) {
70 ; CHECK-LABEL: @test2_extrause1(
71 ; CHECK-NEXT:  entry:
72 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
73 ; CHECK:       left:
74 ; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT:%.*]], 0
75 ; CHECK-NEXT:    br label [[END:%.*]]
76 ; CHECK:       right:
77 ; CHECK-NEXT:    [[I1:%.*]] = extractvalue { i32, i32 } [[AGG_RIGHT:%.*]], 0
78 ; CHECK-NEXT:    call void @usei32(i32 [[I1]])
79 ; CHECK-NEXT:    br label [[END]]
80 ; CHECK:       end:
81 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[I0]], [[LEFT]] ], [ [[I1]], [[RIGHT]] ]
82 ; CHECK-NEXT:    ret i32 [[R]]
84 entry:
85   br i1 %c, label %left, label %right
87 left:
88   %i0 = extractvalue { i32, i32 } %agg_left, 0
89   br label %end
91 right:
92   %i1 = extractvalue { i32, i32 } %agg_right, 0
93   call void  @usei32(i32 %i1)
94   br label %end
96 end:
97   %r = phi i32 [ %i0, %left ], [ %i1, %right ]
98   ret i32 %r
100 define i32 @test3_extrause2({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c) {
101 ; CHECK-LABEL: @test3_extrause2(
102 ; CHECK-NEXT:  entry:
103 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
104 ; CHECK:       left:
105 ; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT:%.*]], 0
106 ; CHECK-NEXT:    call void @usei32(i32 [[I0]])
107 ; CHECK-NEXT:    br label [[END:%.*]]
108 ; CHECK:       right:
109 ; CHECK-NEXT:    [[I1:%.*]] = extractvalue { i32, i32 } [[AGG_RIGHT:%.*]], 0
110 ; CHECK-NEXT:    call void @usei32(i32 [[I1]])
111 ; CHECK-NEXT:    br label [[END]]
112 ; CHECK:       end:
113 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[I0]], [[LEFT]] ], [ [[I1]], [[RIGHT]] ]
114 ; CHECK-NEXT:    ret i32 [[R]]
116 entry:
117   br i1 %c, label %left, label %right
119 left:
120   %i0 = extractvalue { i32, i32 } %agg_left, 0
121   call void  @usei32(i32 %i0)
122   br label %end
124 right:
125   %i1 = extractvalue { i32, i32 } %agg_right, 0
126   call void  @usei32(i32 %i1)
127   br label %end
129 end:
130   %r = phi i32 [ %i0, %left ], [ %i1, %right ]
131   ret i32 %r
134 ; But the indicies must match
135 define i32 @test4({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c) {
136 ; CHECK-LABEL: @test4(
137 ; CHECK-NEXT:  entry:
138 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
139 ; CHECK:       left:
140 ; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT:%.*]], 0
141 ; CHECK-NEXT:    br label [[END:%.*]]
142 ; CHECK:       right:
143 ; CHECK-NEXT:    [[I1:%.*]] = extractvalue { i32, i32 } [[AGG_RIGHT:%.*]], 1
144 ; CHECK-NEXT:    br label [[END]]
145 ; CHECK:       end:
146 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[I0]], [[LEFT]] ], [ [[I1]], [[RIGHT]] ]
147 ; CHECK-NEXT:    ret i32 [[R]]
149 entry:
150   br i1 %c, label %left, label %right
152 left:
153   %i0 = extractvalue { i32, i32 } %agg_left, 0
154   br label %end
156 right:
157   %i1 = extractvalue { i32, i32 } %agg_right, 1
158   br label %end
160 end:
161   %r = phi i32 [ %i0, %left ], [ %i1, %right ]
162   ret i32 %r
165 ; More complex aggregates are fine, too, as long as indicies match.
166 define i32 @test5({{ i32, i32 }, { i32, i32 }} %agg_left, {{ i32, i32 }, { i32, i32 }} %agg_right, i1 %c) {
167 ; CHECK-LABEL: @test5(
168 ; CHECK-NEXT:  entry:
169 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
170 ; CHECK:       left:
171 ; CHECK-NEXT:    br label [[END:%.*]]
172 ; CHECK:       right:
173 ; CHECK-NEXT:    br label [[END]]
174 ; CHECK:       end:
175 ; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { { i32, i32 }, { i32, i32 } } [ [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ]
176 ; CHECK-NEXT:    [[R:%.*]] = extractvalue { { i32, i32 }, { i32, i32 } } [[AGG_LEFT_PN]], 0, 0
177 ; CHECK-NEXT:    ret i32 [[R]]
179 entry:
180   br i1 %c, label %left, label %right
182 left:
183   %i0 = extractvalue {{ i32, i32 }, { i32, i32 }} %agg_left, 0, 0
184   br label %end
186 right:
187   %i1 = extractvalue {{ i32, i32 }, { i32, i32 }} %agg_right, 0, 0
188   br label %end
190 end:
191   %r = phi i32 [ %i0, %left ], [ %i1, %right ]
192   ret i32 %r
195 ; The indicies must fully match, on all levels.
196 define i32 @test6({{ i32, i32 }, { i32, i32 }} %agg_left, {{ i32, i32 }, { i32, i32 }} %agg_right, i1 %c) {
197 ; CHECK-LABEL: @test6(
198 ; CHECK-NEXT:  entry:
199 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
200 ; CHECK:       left:
201 ; CHECK-NEXT:    [[I0:%.*]] = extractvalue { { i32, i32 }, { i32, i32 } } [[AGG_LEFT:%.*]], 0, 0
202 ; CHECK-NEXT:    br label [[END:%.*]]
203 ; CHECK:       right:
204 ; CHECK-NEXT:    [[I1:%.*]] = extractvalue { { i32, i32 }, { i32, i32 } } [[AGG_RIGHT:%.*]], 0, 1
205 ; CHECK-NEXT:    br label [[END]]
206 ; CHECK:       end:
207 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[I0]], [[LEFT]] ], [ [[I1]], [[RIGHT]] ]
208 ; CHECK-NEXT:    ret i32 [[R]]
210 entry:
211   br i1 %c, label %left, label %right
213 left:
214   %i0 = extractvalue {{ i32, i32 }, { i32, i32 }} %agg_left, 0, 0
215   br label %end
217 right:
218   %i1 = extractvalue {{ i32, i32 }, { i32, i32 }} %agg_right, 0, 1
219   br label %end
221 end:
222   %r = phi i32 [ %i0, %left ], [ %i1, %right ]
223   ret i32 %r
225 define i32 @test7({{ i32, i32 }, { i32, i32 }} %agg_left, {{ i32, i32 }, { i32, i32 }} %agg_right, i1 %c) {
226 ; CHECK-LABEL: @test7(
227 ; CHECK-NEXT:  entry:
228 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
229 ; CHECK:       left:
230 ; CHECK-NEXT:    [[I0:%.*]] = extractvalue { { i32, i32 }, { i32, i32 } } [[AGG_LEFT:%.*]], 0, 0
231 ; CHECK-NEXT:    br label [[END:%.*]]
232 ; CHECK:       right:
233 ; CHECK-NEXT:    [[I1:%.*]] = extractvalue { { i32, i32 }, { i32, i32 } } [[AGG_RIGHT:%.*]], 1, 0
234 ; CHECK-NEXT:    br label [[END]]
235 ; CHECK:       end:
236 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[I0]], [[LEFT]] ], [ [[I1]], [[RIGHT]] ]
237 ; CHECK-NEXT:    ret i32 [[R]]
239 entry:
240   br i1 %c, label %left, label %right
242 left:
243   %i0 = extractvalue {{ i32, i32 }, { i32, i32 }} %agg_left, 0, 0
244   br label %end
246 right:
247   %i1 = extractvalue {{ i32, i32 }, { i32, i32 }} %agg_right, 1, 0
248   br label %end
250 end:
251   %r = phi i32 [ %i0, %left ], [ %i1, %right ]
252   ret i32 %r
254 define i32 @test8({{ i32, i32 }, { i32, i32 }} %agg_left, {{ i32, i32 }, { i32, i32 }} %agg_right, i1 %c) {
255 ; CHECK-LABEL: @test8(
256 ; CHECK-NEXT:  entry:
257 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
258 ; CHECK:       left:
259 ; CHECK-NEXT:    [[I0:%.*]] = extractvalue { { i32, i32 }, { i32, i32 } } [[AGG_LEFT:%.*]], 0, 0
260 ; CHECK-NEXT:    br label [[END:%.*]]
261 ; CHECK:       right:
262 ; CHECK-NEXT:    [[I1:%.*]] = extractvalue { { i32, i32 }, { i32, i32 } } [[AGG_RIGHT:%.*]], 1, 1
263 ; CHECK-NEXT:    br label [[END]]
264 ; CHECK:       end:
265 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[I0]], [[LEFT]] ], [ [[I1]], [[RIGHT]] ]
266 ; CHECK-NEXT:    ret i32 [[R]]
268 entry:
269   br i1 %c, label %left, label %right
271 left:
272   %i0 = extractvalue {{ i32, i32 }, { i32, i32 }} %agg_left, 0, 0
273   br label %end
275 right:
276   %i1 = extractvalue {{ i32, i32 }, { i32, i32 }} %agg_right, 1, 1
277   br label %end
279 end:
280   %r = phi i32 [ %i0, %left ], [ %i1, %right ]
281   ret i32 %r
284 ; Also, unlike PHI-of-insertvalues, here the base aggregates of extractvalue
285 ; can have different types, and just checking the indicies is not enough.
286 define i32 @test9({ i32, i32 } %agg_left, { i32, { i32, i32 } } %agg_right, i1 %c) {
287 ; CHECK-LABEL: @test9(
288 ; CHECK-NEXT:  entry:
289 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
290 ; CHECK:       left:
291 ; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT:%.*]], 0
292 ; CHECK-NEXT:    br label [[END:%.*]]
293 ; CHECK:       right:
294 ; CHECK-NEXT:    [[I1:%.*]] = extractvalue { i32, { i32, i32 } } [[AGG_RIGHT:%.*]], 0
295 ; CHECK-NEXT:    br label [[END]]
296 ; CHECK:       end:
297 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[I0]], [[LEFT]] ], [ [[I1]], [[RIGHT]] ]
298 ; CHECK-NEXT:    ret i32 [[R]]
300 entry:
301   br i1 %c, label %left, label %right
303 left:
304   %i0 = extractvalue { i32, i32 } %agg_left, 0
305   br label %end
307 right:
308   %i1 = extractvalue { i32, { i32, i32 } } %agg_right, 0
309   br label %end
311 end:
312   %r = phi i32 [ %i0, %left ], [ %i1, %right ]
313   ret i32 %r
316 ; It is fine if there are multiple uses of the PHI's value, as long as they are all in the PHI node itself
317 define i32 @test10({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c0, i1 %c1) {
318 ; CHECK-LABEL: @test10(
319 ; CHECK-NEXT:  entry:
320 ; CHECK-NEXT:    br i1 [[C0:%.*]], label [[END:%.*]], label [[DISPATCH:%.*]]
321 ; CHECK:       dispatch:
322 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
323 ; CHECK:       left:
324 ; CHECK-NEXT:    br label [[END]]
325 ; CHECK:       right:
326 ; CHECK-NEXT:    br label [[END]]
327 ; CHECK:       end:
328 ; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [ [[AGG_LEFT:%.*]], [[ENTRY:%.*]] ], [ [[AGG_LEFT]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ]
329 ; CHECK-NEXT:    [[R:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT_PN]], 0
330 ; CHECK-NEXT:    ret i32 [[R]]
332 entry:
333   %i0 = extractvalue { i32, i32 } %agg_left, 0
334   %i1 = extractvalue { i32, i32 } %agg_right, 0
335   br i1 %c0, label %end, label %dispatch
337 dispatch:
338   br i1 %c1, label %left, label %right
340 left:
341   br label %end
343 right:
344   br label %end
346 end:
347   %r = phi i32 [ %i0, %entry ], [ %i0, %left ], [ %i1, %right ]
348   ret i32 %r
350 ; Which isn't the case here, there is a legitimate external use.
351 define i32 @test11({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i1 %c0, i1 %c1) {
352 ; CHECK-LABEL: @test11(
353 ; CHECK-NEXT:  entry:
354 ; CHECK-NEXT:    [[I0:%.*]] = extractvalue { i32, i32 } [[AGG_LEFT:%.*]], 0
355 ; CHECK-NEXT:    [[I1:%.*]] = extractvalue { i32, i32 } [[AGG_RIGHT:%.*]], 0
356 ; CHECK-NEXT:    call void @usei32(i32 [[I0]])
357 ; CHECK-NEXT:    br i1 [[C0:%.*]], label [[END:%.*]], label [[DISPATCH:%.*]]
358 ; CHECK:       dispatch:
359 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
360 ; CHECK:       left:
361 ; CHECK-NEXT:    br label [[END]]
362 ; CHECK:       right:
363 ; CHECK-NEXT:    br label [[END]]
364 ; CHECK:       end:
365 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[I0]], [[ENTRY:%.*]] ], [ [[I0]], [[LEFT]] ], [ [[I1]], [[RIGHT]] ]
366 ; CHECK-NEXT:    ret i32 [[R]]
368 entry:
369   %i0 = extractvalue { i32, i32 } %agg_left, 0
370   %i1 = extractvalue { i32, i32 } %agg_right, 0
371   call void @usei32(i32 %i0)
372   br i1 %c0, label %end, label %dispatch
374 dispatch:
375   br i1 %c1, label %left, label %right
377 left:
378   br label %end
380 right:
381   br label %end
383 end:
384   %r = phi i32 [ %i0, %entry ], [ %i0, %left ], [ %i1, %right ]
385   ret i32 %r