[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Transforms / InstCombine / phi-of-insertvalues.ll
blobd6961b8b7ba1afee28f92e42d44dc356570ef82e
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -instcombine < %s | FileCheck %s
4 declare void @usei32i32agg({ i32, i32 })
6 ; If we have a phi of insertvalues, we can sink it,
7 ; Here, we only need a PHI for inserted values.
8 define { i32, i32 } @test0({ i32, i32 } %agg, i32 %val_left, i32 %val_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:    [[VAL_LEFT_PN:%.*]] = phi i32 [ [[VAL_LEFT:%.*]], [[LEFT]] ], [ [[VAL_RIGHT:%.*]], [[RIGHT]] ]
18 ; CHECK-NEXT:    [[R:%.*]] = insertvalue { i32, i32 } [[AGG:%.*]], i32 [[VAL_LEFT_PN]], 0
19 ; CHECK-NEXT:    ret { i32, i32 } [[R]]
21 entry:
22   br i1 %c, label %left, label %right
24 left:
25   %i0 = insertvalue { i32, i32 } %agg, i32 %val_left, 0
26   br label %end
28 right:
29   %i1 = insertvalue { i32, i32 } %agg, i32 %val_right, 0
30   br label %end
32 end:
33   %r = phi { i32, i32 } [ %i0, %left ], [ %i1, %right ]
34   ret { i32, i32 } %r
37 ; But only if the insertvalues have no extra uses
38 define { i32, i32 } @test1_extrause0({ i32, i32 } %agg, i32 %val_left, i32 %val_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:%.*]] = insertvalue { i32, i32 } [[AGG:%.*]], i32 [[VAL_LEFT:%.*]], 0
44 ; CHECK-NEXT:    call void @usei32i32agg({ i32, i32 } [[I0]])
45 ; CHECK-NEXT:    br label [[END:%.*]]
46 ; CHECK:       right:
47 ; CHECK-NEXT:    [[I1:%.*]] = insertvalue { i32, i32 } [[AGG]], i32 [[VAL_RIGHT:%.*]], 0
48 ; CHECK-NEXT:    br label [[END]]
49 ; CHECK:       end:
50 ; CHECK-NEXT:    [[R:%.*]] = phi { i32, i32 } [ [[I0]], [[LEFT]] ], [ [[I1]], [[RIGHT]] ]
51 ; CHECK-NEXT:    ret { i32, i32 } [[R]]
53 entry:
54   br i1 %c, label %left, label %right
56 left:
57   %i0 = insertvalue { i32, i32 } %agg, i32 %val_left, 0
58   call void  @usei32i32agg({ i32, i32 } %i0 )
59   br label %end
61 right:
62   %i1 = insertvalue { i32, i32 } %agg, i32 %val_right, 0
63   br label %end
65 end:
66   %r = phi { i32, i32 } [ %i0, %left ], [ %i1, %right ]
67   ret { i32, i32 } %r
69 define { i32, i32 } @test2_extrause1({ i32, i32 } %agg, i32 %val_left, i32 %val_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:%.*]] = insertvalue { i32, i32 } [[AGG:%.*]], i32 [[VAL_LEFT:%.*]], 0
75 ; CHECK-NEXT:    br label [[END:%.*]]
76 ; CHECK:       right:
77 ; CHECK-NEXT:    [[I1:%.*]] = insertvalue { i32, i32 } [[AGG]], i32 [[VAL_RIGHT:%.*]], 0
78 ; CHECK-NEXT:    call void @usei32i32agg({ i32, i32 } [[I1]])
79 ; CHECK-NEXT:    br label [[END]]
80 ; CHECK:       end:
81 ; CHECK-NEXT:    [[R:%.*]] = phi { i32, i32 } [ [[I0]], [[LEFT]] ], [ [[I1]], [[RIGHT]] ]
82 ; CHECK-NEXT:    ret { i32, i32 } [[R]]
84 entry:
85   br i1 %c, label %left, label %right
87 left:
88   %i0 = insertvalue { i32, i32 } %agg, i32 %val_left, 0
89   br label %end
91 right:
92   %i1 = insertvalue { i32, i32 } %agg, i32 %val_right, 0
93   call void  @usei32i32agg({ i32, i32 } %i1 )
94   br label %end
96 end:
97   %r = phi { i32, i32 } [ %i0, %left ], [ %i1, %right ]
98   ret { i32, i32 } %r
100 define { i32, i32 } @test3_extrause2({ i32, i32 } %agg, i32 %val_left, i32 %val_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:%.*]] = insertvalue { i32, i32 } [[AGG:%.*]], i32 [[VAL_LEFT:%.*]], 0
106 ; CHECK-NEXT:    call void @usei32i32agg({ i32, i32 } [[I0]])
107 ; CHECK-NEXT:    br label [[END:%.*]]
108 ; CHECK:       right:
109 ; CHECK-NEXT:    [[I1:%.*]] = insertvalue { i32, i32 } [[AGG]], i32 [[VAL_RIGHT:%.*]], 0
110 ; CHECK-NEXT:    call void @usei32i32agg({ i32, i32 } [[I1]])
111 ; CHECK-NEXT:    br label [[END]]
112 ; CHECK:       end:
113 ; CHECK-NEXT:    [[R:%.*]] = phi { i32, i32 } [ [[I0]], [[LEFT]] ], [ [[I1]], [[RIGHT]] ]
114 ; CHECK-NEXT:    ret { i32, i32 } [[R]]
116 entry:
117   br i1 %c, label %left, label %right
119 left:
120   %i0 = insertvalue { i32, i32 } %agg, i32 %val_left, 0
121   call void  @usei32i32agg({ i32, i32 } %i0 )
122   br label %end
124 right:
125   %i1 = insertvalue { i32, i32 } %agg, i32 %val_right, 0
126   call void  @usei32i32agg({ i32, i32 } %i1 )
127   br label %end
129 end:
130   %r = phi { i32, i32 } [ %i0, %left ], [ %i1, %right ]
131   ret { i32, i32 } %r
134 ; Here, we only need a PHI for base aggregate
135 define { i32, i32 } @test4({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i32 %val, 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:    br label [[END:%.*]]
141 ; CHECK:       right:
142 ; CHECK-NEXT:    br label [[END]]
143 ; CHECK:       end:
144 ; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [ [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ]
145 ; CHECK-NEXT:    [[R:%.*]] = insertvalue { i32, i32 } [[AGG_LEFT_PN]], i32 [[VAL:%.*]], 0
146 ; CHECK-NEXT:    ret { i32, i32 } [[R]]
148 entry:
149   br i1 %c, label %left, label %right
151 left:
152   %i0 = insertvalue { i32, i32 } %agg_left, i32 %val, 0
153   br label %end
155 right:
156   %i1 = insertvalue { i32, i32 } %agg_right, i32 %val, 0
157   br label %end
159 end:
160   %r = phi { i32, i32 } [ %i0, %left ], [ %i1, %right ]
161   ret { i32, i32 } %r
164 ; Here, we need a PHI for both the base and the inserted value
165 define { i32, i32 } @test5({ i32, i32 } %agg_left, { i32, i32 } %agg_right, i32 %val_left, i32 %val_right, i1 %c) {
166 ; CHECK-LABEL: @test5(
167 ; CHECK-NEXT:  entry:
168 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
169 ; CHECK:       left:
170 ; CHECK-NEXT:    br label [[END:%.*]]
171 ; CHECK:       right:
172 ; CHECK-NEXT:    br label [[END]]
173 ; CHECK:       end:
174 ; CHECK-NEXT:    [[AGG_LEFT_PN:%.*]] = phi { i32, i32 } [ [[AGG_LEFT:%.*]], [[LEFT]] ], [ [[AGG_RIGHT:%.*]], [[RIGHT]] ]
175 ; CHECK-NEXT:    [[VAL_LEFT_PN:%.*]] = phi i32 [ [[VAL_LEFT:%.*]], [[LEFT]] ], [ [[VAL_RIGHT:%.*]], [[RIGHT]] ]
176 ; CHECK-NEXT:    [[R:%.*]] = insertvalue { i32, i32 } [[AGG_LEFT_PN]], i32 [[VAL_LEFT_PN]], 0
177 ; CHECK-NEXT:    ret { i32, i32 } [[R]]
179 entry:
180   br i1 %c, label %left, label %right
182 left:
183   %i0 = insertvalue { i32, i32 } %agg_left, i32 %val_left, 0
184   br label %end
186 right:
187   %i1 = insertvalue { i32, i32 } %agg_right, i32 %val_right, 0
188   br label %end
190 end:
191   %r = phi { i32, i32 } [ %i0, %left ], [ %i1, %right ]
192   ret { i32, i32 } %r
195 ; But the indicies must match
196 define { i32, i32 } @test6({ i32, i32 } %agg, i32 %val_left, i32 %val_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:%.*]] = insertvalue { i32, i32 } [[AGG:%.*]], i32 [[VAL_LEFT:%.*]], 0
202 ; CHECK-NEXT:    br label [[END:%.*]]
203 ; CHECK:       right:
204 ; CHECK-NEXT:    [[I1:%.*]] = insertvalue { i32, i32 } [[AGG]], i32 [[VAL_RIGHT:%.*]], 1
205 ; CHECK-NEXT:    br label [[END]]
206 ; CHECK:       end:
207 ; CHECK-NEXT:    [[R:%.*]] = phi { i32, i32 } [ [[I0]], [[LEFT]] ], [ [[I1]], [[RIGHT]] ]
208 ; CHECK-NEXT:    ret { i32, i32 } [[R]]
210 entry:
211   br i1 %c, label %left, label %right
213 left:
214   %i0 = insertvalue { i32, i32 } %agg, i32 %val_left, 0
215   br label %end
217 right:
218   %i1 = insertvalue { i32, i32 } %agg, i32 %val_right, 1
219   br label %end
221 end:
222   %r = phi { i32, i32 } [ %i0, %left ], [ %i1, %right ]
223   ret { i32, i32 } %r
226 ; More complex aggregates are fine, too, as long as indicies match.
227 define {{ i32, i32 }, { i32, i32 }} @test7({{ i32, i32 }, { i32, i32 }} %agg, i32 %val_left, i32 %val_right, i1 %c) {
228 ; CHECK-LABEL: @test7(
229 ; CHECK-NEXT:  entry:
230 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
231 ; CHECK:       left:
232 ; CHECK-NEXT:    br label [[END:%.*]]
233 ; CHECK:       right:
234 ; CHECK-NEXT:    br label [[END]]
235 ; CHECK:       end:
236 ; CHECK-NEXT:    [[VAL_LEFT_PN:%.*]] = phi i32 [ [[VAL_LEFT:%.*]], [[LEFT]] ], [ [[VAL_RIGHT:%.*]], [[RIGHT]] ]
237 ; CHECK-NEXT:    [[R:%.*]] = insertvalue { { i32, i32 }, { i32, i32 } } [[AGG:%.*]], i32 [[VAL_LEFT_PN]], 0, 0
238 ; CHECK-NEXT:    ret { { i32, i32 }, { i32, i32 } } [[R]]
240 entry:
241   br i1 %c, label %left, label %right
243 left:
244   %i0 = insertvalue {{ i32, i32 }, { i32, i32 }} %agg, i32 %val_left, 0, 0
245   br label %end
247 right:
248   %i1 = insertvalue {{ i32, i32 }, { i32, i32 }} %agg, i32 %val_right, 0, 0
249   br label %end
251 end:
252   %r = phi {{ i32, i32 }, { i32, i32 }} [ %i0, %left ], [ %i1, %right ]
253   ret {{ i32, i32 }, { i32, i32 }} %r
256 ; The indicies must fully match, on all levels.
257 define {{ i32, i32 }, { i32, i32 }} @test8({{ i32, i32 }, { i32, i32 }} %agg, i32 %val_left, i32 %val_right, i1 %c) {
258 ; CHECK-LABEL: @test8(
259 ; CHECK-NEXT:  entry:
260 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
261 ; CHECK:       left:
262 ; CHECK-NEXT:    [[I0:%.*]] = insertvalue { { i32, i32 }, { i32, i32 } } [[AGG:%.*]], i32 [[VAL_LEFT:%.*]], 0, 0
263 ; CHECK-NEXT:    br label [[END:%.*]]
264 ; CHECK:       right:
265 ; CHECK-NEXT:    [[I1:%.*]] = insertvalue { { i32, i32 }, { i32, i32 } } [[AGG]], i32 [[VAL_RIGHT:%.*]], 0, 1
266 ; CHECK-NEXT:    br label [[END]]
267 ; CHECK:       end:
268 ; CHECK-NEXT:    [[R:%.*]] = phi { { i32, i32 }, { i32, i32 } } [ [[I0]], [[LEFT]] ], [ [[I1]], [[RIGHT]] ]
269 ; CHECK-NEXT:    ret { { i32, i32 }, { i32, i32 } } [[R]]
271 entry:
272   br i1 %c, label %left, label %right
274 left:
275   %i0 = insertvalue {{ i32, i32 }, { i32, i32 }} %agg, i32 %val_left, 0, 0
276   br label %end
278 right:
279   %i1 = insertvalue {{ i32, i32 }, { i32, i32 }} %agg, i32 %val_right, 0, 1
280   br label %end
282 end:
283   %r = phi {{ i32, i32 }, { i32, i32 }} [ %i0, %left ], [ %i1, %right ]
284   ret {{ i32, i32 }, { i32, i32 }} %r
287 ; It is fine if there are multiple uses of the PHI's value, as long as they are all in the PHI node itself
288 define { i32, i32 } @test9({ i32, i32 } %agg, i32 %val_left, i32 %val_right, i1 %c0, i1 %c1) {
289 ; CHECK-LABEL: @test9(
290 ; CHECK-NEXT:  entry:
291 ; CHECK-NEXT:    br i1 [[C0:%.*]], label [[END:%.*]], label [[DISPATCH:%.*]]
292 ; CHECK:       dispatch:
293 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
294 ; CHECK:       left:
295 ; CHECK-NEXT:    br label [[END]]
296 ; CHECK:       right:
297 ; CHECK-NEXT:    br label [[END]]
298 ; CHECK:       end:
299 ; CHECK-NEXT:    [[VAL_LEFT_PN:%.*]] = phi i32 [ [[VAL_LEFT:%.*]], [[ENTRY:%.*]] ], [ [[VAL_LEFT]], [[LEFT]] ], [ [[VAL_RIGHT:%.*]], [[RIGHT]] ]
300 ; CHECK-NEXT:    [[R:%.*]] = insertvalue { i32, i32 } [[AGG:%.*]], i32 [[VAL_LEFT_PN]], 0
301 ; CHECK-NEXT:    ret { i32, i32 } [[R]]
303 entry:
304   %i0 = insertvalue { i32, i32 } %agg, i32 %val_left, 0
305   %i1 = insertvalue { i32, i32 } %agg, i32 %val_right, 0
306   br i1 %c0, label %end, label %dispatch
308 dispatch:
309   br i1 %c1, label %left, label %right
311 left:
312   br label %end
314 right:
315   br label %end
317 end:
318   %r = phi { i32, i32 } [ %i0, %entry ], [ %i0, %left ], [ %i1, %right ]
319   ret { i32, i32 } %r
321 ; Which isn't the case here, there is a legitimate external use.
322 define { i32, i32 } @test10({ i32, i32 } %agg, i32 %val_left, i32 %val_right, i1 %c0, i1 %c1) {
323 ; CHECK-LABEL: @test10(
324 ; CHECK-NEXT:  entry:
325 ; CHECK-NEXT:    [[I0:%.*]] = insertvalue { i32, i32 } [[AGG:%.*]], i32 [[VAL_LEFT:%.*]], 0
326 ; CHECK-NEXT:    [[I1:%.*]] = insertvalue { i32, i32 } [[AGG]], i32 [[VAL_RIGHT:%.*]], 0
327 ; CHECK-NEXT:    call void @usei32i32agg({ i32, i32 } [[I0]])
328 ; CHECK-NEXT:    br i1 [[C0:%.*]], label [[END:%.*]], label [[DISPATCH:%.*]]
329 ; CHECK:       dispatch:
330 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
331 ; CHECK:       left:
332 ; CHECK-NEXT:    br label [[END]]
333 ; CHECK:       right:
334 ; CHECK-NEXT:    br label [[END]]
335 ; CHECK:       end:
336 ; CHECK-NEXT:    [[R:%.*]] = phi { i32, i32 } [ [[I0]], [[ENTRY:%.*]] ], [ [[I0]], [[LEFT]] ], [ [[I1]], [[RIGHT]] ]
337 ; CHECK-NEXT:    ret { i32, i32 } [[R]]
339 entry:
340   %i0 = insertvalue { i32, i32 } %agg, i32 %val_left, 0
341   %i1 = insertvalue { i32, i32 } %agg, i32 %val_right, 0
342   call void @usei32i32agg({ i32, i32 } %i0)
343   br i1 %c0, label %end, label %dispatch
345 dispatch:
346   br i1 %c1, label %left, label %right
348 left:
349   br label %end
351 right:
352   br label %end
354 end:
355   %r = phi { i32, i32 } [ %i0, %entry ], [ %i0, %left ], [ %i1, %right ]
356   ret { i32, i32 } %r