Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / SCCP / range-and.ll
blobef8758fcba9e223d49cff9425b7e3ea0d0710a91
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --verbose
2 ; RUN: opt -S -passes=sccp %s | FileCheck %s
4 declare void @use(i1)
6 define void @and_range_limit(i64 %a) {
7 ; CHECK-LABEL: @and_range_limit(
8 ; CHECK-NEXT:    [[R:%.*]] = and i64 [[A:%.*]], 255
9 ; CHECK-NEXT:    [[C_0:%.*]] = icmp slt i64 [[R]], 15
10 ; CHECK-NEXT:    call void @use(i1 [[C_0]])
11 ; CHECK-NEXT:    call void @use(i1 true)
12 ; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i64 [[R]], 100
13 ; CHECK-NEXT:    call void @use(i1 [[C_2]])
14 ; CHECK-NEXT:    call void @use(i1 false)
15 ; CHECK-NEXT:    [[C_4:%.*]] = icmp ne i64 [[R]], 100
16 ; CHECK-NEXT:    call void @use(i1 [[C_4]])
17 ; CHECK-NEXT:    call void @use(i1 true)
18 ; CHECK-NEXT:    ret void
20   %r = and i64 %a, 255
21   %c.0 = icmp slt i64 %r, 15
22   call void @use(i1 %c.0)
23   %c.1 = icmp slt i64 %r, 256
24   call void @use(i1 %c.1)
25   %c.2 = icmp eq i64 %r, 100
26   call void @use(i1 %c.2)
27   %c.3 = icmp eq i64 %r, 300
28   call void @use(i1 %c.3)
29   %c.4 = icmp ne i64 %r, 100
30   call void @use(i1 %c.4)
31   %c.5 = icmp ne i64 %r, 300
32   call void @use(i1 %c.5)
33   ret void
36 ; Below are test cases for PR44949.
38 ; We can remove `%res = and i64 %p, 255`, because %r = 0 and we can eliminate
39 ; %p as well.
40 define i64 @constant_and_undef(i1 %c1, i64 %a) {
41 ; CHECK-LABEL: @constant_and_undef(
42 ; CHECK-NEXT:  entry:
43 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
44 ; CHECK:       bb1:
45 ; CHECK-NEXT:    br label [[BB3:%.*]]
46 ; CHECK:       bb2:
47 ; CHECK-NEXT:    br label [[BB3]]
48 ; CHECK:       bb3:
49 ; CHECK-NEXT:    ret i64 0
51 entry:
52   br i1 %c1, label %bb1, label %bb2
54 bb1:
55   br label %bb3
57 bb2:
58   %r = and i64 %a, 0
59   br label %bb3
61 bb3:
62   %p = phi i64 [ undef, %bb1 ], [ %r, %bb2 ]
63   %res = and i64 %p, 255
64   ret i64 %res
67 ; Check that we go to overdefined when merging a constant range with undef. We
68 ; cannot remove '%res = and i64 %p, 255'.
69 define i64 @constant_range_and_undef(i1 %cond, i64 %a) {
70 ; CHECK-LABEL: @constant_range_and_undef(
71 ; CHECK-NEXT:  entry:
72 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
73 ; CHECK:       bb1:
74 ; CHECK-NEXT:    br label [[BB3:%.*]]
75 ; CHECK:       bb2:
76 ; CHECK-NEXT:    [[R:%.*]] = and i64 [[A:%.*]], 255
77 ; CHECK-NEXT:    br label [[BB3]]
78 ; CHECK:       bb3:
79 ; CHECK-NEXT:    [[P:%.*]] = phi i64 [ undef, [[BB1]] ], [ [[R]], [[BB2]] ]
80 ; CHECK-NEXT:    [[RES:%.*]] = and i64 [[P]], 255
81 ; CHECK-NEXT:    ret i64 [[RES]]
83 entry:
84   br i1 %cond, label %bb1, label %bb2
86 bb1:
87   br label %bb3
89 bb2:
90   %r = and i64 %a, 255
91   br label %bb3
93 bb3:
94   %p = phi i64 [ undef, %bb1 ], [ %r, %bb2 ]
95   %res = and i64 %p, 255
96   ret i64 %res
99 ; Same as @constant_range_and_undef, with the undef coming from the other
100 ; block.
101 define i64 @constant_range_and_undef_switched_incoming(i1 %cond, i64 %a) {
102 ; CHECK-LABEL: @constant_range_and_undef_switched_incoming(
103 ; CHECK-NEXT:  entry:
104 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
105 ; CHECK:       bb1:
106 ; CHECK-NEXT:    [[R:%.*]] = and i64 [[A:%.*]], 255
107 ; CHECK-NEXT:    br label [[BB3:%.*]]
108 ; CHECK:       bb2:
109 ; CHECK-NEXT:    br label [[BB3]]
110 ; CHECK:       bb3:
111 ; CHECK-NEXT:    [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ undef, [[BB2]] ]
112 ; CHECK-NEXT:    [[RES:%.*]] = and i64 [[P]], 255
113 ; CHECK-NEXT:    ret i64 [[RES]]
115 entry:
116   br i1 %cond, label %bb1, label %bb2
118 bb1:
119   %r = and i64 %a, 255
120   br label %bb3
122 bb2:
123   br label %bb3
125 bb3:
126   %p = phi i64 [ %r, %bb1 ], [ undef, %bb2 ]
127   %res = and i64 %p, 255
128   ret i64 %res
131 define i64 @constant_range_and_255_100(i1 %cond, i64 %a) {
132 ; CHECK-LABEL: @constant_range_and_255_100(
133 ; CHECK-NEXT:  entry:
134 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
135 ; CHECK:       bb1:
136 ; CHECK-NEXT:    [[R_1:%.*]] = and i64 [[A:%.*]], 100
137 ; CHECK-NEXT:    br label [[BB3:%.*]]
138 ; CHECK:       bb2:
139 ; CHECK-NEXT:    [[R_2:%.*]] = and i64 [[A]], 255
140 ; CHECK-NEXT:    br label [[BB3]]
141 ; CHECK:       bb3:
142 ; CHECK-NEXT:    [[P:%.*]] = phi i64 [ [[R_1]], [[BB1]] ], [ [[R_2]], [[BB2]] ]
143 ; CHECK-NEXT:    [[P_AND:%.*]] = and i64 [[P]], 255
144 ; CHECK-NEXT:    call void @use(i1 true)
145 ; CHECK-NEXT:    ret i64 [[P_AND]]
147 entry:
148   br i1 %cond, label %bb1, label %bb2
150 bb1:
151   %r.1 = and i64 %a, 100
152   br label %bb3
154 bb2:
155   %r.2 = and i64 %a, 255
156   br label %bb3
158 bb3:
159   %p = phi i64 [ %r.1, %bb1 ], [ %r.2, %bb2 ]
160   %p.and = and i64 %p, 255
161   %c = icmp ult i64 %p.and, 256
162   call void @use(i1 %c)
163   ret i64 %p.and
167 define i64 @constant_range_and_undef2(i1 %c1, i1 %c2, i64 %a) {
168 ; CHECK-LABEL: @constant_range_and_undef2(
169 ; CHECK-NEXT:  entry:
170 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
171 ; CHECK:       bb1:
172 ; CHECK-NEXT:    [[V1:%.*]] = add i64 undef, undef
173 ; CHECK-NEXT:    br label [[BB3:%.*]]
174 ; CHECK:       bb2:
175 ; CHECK-NEXT:    [[V2:%.*]] = and i64 [[A:%.*]], 255
176 ; CHECK-NEXT:    br label [[BB3]]
177 ; CHECK:       bb3:
178 ; CHECK-NEXT:    [[P:%.*]] = phi i64 [ [[V1]], [[BB1]] ], [ [[V2]], [[BB2]] ]
179 ; CHECK-NEXT:    br i1 [[C2:%.*]], label [[BB4:%.*]], label [[BB5:%.*]]
180 ; CHECK:       bb4:
181 ; CHECK-NEXT:    br label [[BB6:%.*]]
182 ; CHECK:       bb5:
183 ; CHECK-NEXT:    [[V3:%.*]] = and i64 [[A]], 255
184 ; CHECK-NEXT:    br label [[BB6]]
185 ; CHECK:       bb6:
186 ; CHECK-NEXT:    [[P2:%.*]] = phi i64 [ [[P]], [[BB4]] ], [ [[V3]], [[BB5]] ]
187 ; CHECK-NEXT:    [[RES:%.*]] = and i64 [[P2]], 255
188 ; CHECK-NEXT:    ret i64 [[RES]]
190 entry:
191   br i1 %c1, label %bb1, label %bb2
193 bb1:
194   %v1 = add i64 undef, undef
195   br label %bb3
197 bb2:
198   %v2 = and i64 %a, 255
199   br label %bb3
201 bb3:
202   %p = phi i64 [ %v1, %bb1 ], [ %v2, %bb2 ]
203   br i1 %c2, label %bb4, label %bb5
205 bb4:
206   br label %bb6
208 bb5:
209   %v3 = and i64 %a, 255
210   br label %bb6
212 bb6:
213   %p2 = phi i64 [ %p, %bb4 ], [ %v3, %bb5 ]
214   %res = and i64 %p2, 255
215   ret i64 %res
218 define i1 @constant_range_and_undef_3(i1 %cond, i64 %a) {
219 ; CHECK-LABEL: @constant_range_and_undef_3(
220 ; CHECK-NEXT:  entry:
221 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
222 ; CHECK:       bb1:
223 ; CHECK-NEXT:    br label [[BB3:%.*]]
224 ; CHECK:       bb2:
225 ; CHECK-NEXT:    [[R:%.*]] = and i64 [[A:%.*]], 255
226 ; CHECK-NEXT:    br label [[BB3]]
227 ; CHECK:       bb3:
228 ; CHECK-NEXT:    [[P:%.*]] = phi i64 [ undef, [[BB1]] ], [ [[R]], [[BB2]] ]
229 ; CHECK-NEXT:    ret i1 true
231 entry:
232   br i1 %cond, label %bb1, label %bb2
234 bb1:
235   br label %bb3
237 bb2:
238   %r = and i64 %a, 255
239   br label %bb3
241 bb3:
242   %p = phi i64 [ undef, %bb1 ], [ %r, %bb2 ]
243   %c = icmp ult i64 %p, 256
244   ret i1 %c
247 define i1 @constant_range_and_undef_3_switched_incoming(i1 %cond, i64 %a) {
248 ; CHECK-LABEL: @constant_range_and_undef_3_switched_incoming(
249 ; CHECK-NEXT:  entry:
250 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
251 ; CHECK:       bb1:
252 ; CHECK-NEXT:    [[R:%.*]] = and i64 [[A:%.*]], 255
253 ; CHECK-NEXT:    br label [[BB3:%.*]]
254 ; CHECK:       bb2:
255 ; CHECK-NEXT:    br label [[BB3]]
256 ; CHECK:       bb3:
257 ; CHECK-NEXT:    [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ undef, [[BB2]] ]
258 ; CHECK-NEXT:    ret i1 true
260 entry:
261   br i1 %cond, label %bb1, label %bb2
263 bb1:
264   %r = and i64 %a, 255
265   br label %bb3
267 bb2:
268   br label %bb3
270 bb3:
271   %p = phi i64 [ %r, %bb1 ], [ undef, %bb2 ]
272   %c = icmp ult i64 %p, 256
273   ret i1 %c
276 ; Same as @constant_range_and_undef, but with 3 incoming
277 ; values: undef, a constant and a constant range.
278 define i64 @constant_range_and_undef_3_incoming_v1(i1 %c1, i1 %c2, i64 %a) {
279 ; CHECK-LABEL: @constant_range_and_undef_3_incoming_v1(
280 ; CHECK-NEXT:  entry:
281 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
282 ; CHECK:       bb1:
283 ; CHECK-NEXT:    [[R:%.*]] = and i64 [[A:%.*]], 255
284 ; CHECK-NEXT:    br label [[BB4:%.*]]
285 ; CHECK:       bb2:
286 ; CHECK-NEXT:    br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB4]]
287 ; CHECK:       bb3:
288 ; CHECK-NEXT:    br label [[BB4]]
289 ; CHECK:       bb4:
290 ; CHECK-NEXT:    [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ 10, [[BB2]] ], [ undef, [[BB3]] ]
291 ; CHECK-NEXT:    [[RES:%.*]] = and i64 [[P]], 255
292 ; CHECK-NEXT:    ret i64 [[RES]]
294 entry:
295   br i1 %c1, label %bb1, label %bb2
297 bb1:
298   %r = and i64 %a, 255
299   br label %bb4
301 bb2:
302   br i1 %c2, label %bb3, label %bb4
304 bb3:
305   br label %bb4
307 bb4:
308   %p = phi i64 [ %r, %bb1 ], [ 10, %bb2], [ undef, %bb3 ]
309   %res = and i64 %p, 255
310   ret i64 %res
313 ; Same as @constant_range_and_undef_3_incoming_v1, but with different order of
314 ; incoming values.
315 define i64 @constant_range_and_undef_3_incoming_v2(i1 %c1, i1 %c2, i64 %a) {
316 ; CHECK-LABEL: @constant_range_and_undef_3_incoming_v2(
317 ; CHECK-NEXT:  entry:
318 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
319 ; CHECK:       bb1:
320 ; CHECK-NEXT:    br label [[BB4:%.*]]
321 ; CHECK:       bb2:
322 ; CHECK-NEXT:    br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB4]]
323 ; CHECK:       bb3:
324 ; CHECK-NEXT:    [[R:%.*]] = and i64 [[A:%.*]], 255
325 ; CHECK-NEXT:    br label [[BB4]]
326 ; CHECK:       bb4:
327 ; CHECK-NEXT:    [[P:%.*]] = phi i64 [ undef, [[BB1]] ], [ 10, [[BB2]] ], [ [[R]], [[BB3]] ]
328 ; CHECK-NEXT:    [[RES:%.*]] = and i64 [[P]], 255
329 ; CHECK-NEXT:    ret i64 [[RES]]
331 entry:
332   br i1 %c1, label %bb1, label %bb2
334 bb1:
335   br label %bb4
337 bb2:
338   br i1 %c2, label %bb3, label %bb4
340 bb3:
341   %r = and i64 %a, 255
342   br label %bb4
344 bb4:
345   %p = phi i64 [ undef, %bb1 ], [ 10, %bb2], [ %r, %bb3 ]
346   %res = and i64 %p, 255
347   ret i64 %res
350 ; Same as @constant_range_and_undef_3_incoming_v1, but with different order of
351 ; incoming values.
352 define i64 @constant_range_and_undef_3_incoming_v3(i1 %c1, i1 %c2, i64 %a) {
353 ; CHECK-LABEL: @constant_range_and_undef_3_incoming_v3(
354 ; CHECK-NEXT:  entry:
355 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
356 ; CHECK:       bb1:
357 ; CHECK-NEXT:    [[R:%.*]] = and i64 [[A:%.*]], 255
358 ; CHECK-NEXT:    br label [[BB4:%.*]]
359 ; CHECK:       bb2:
360 ; CHECK-NEXT:    br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB4]]
361 ; CHECK:       bb3:
362 ; CHECK-NEXT:    br label [[BB4]]
363 ; CHECK:       bb4:
364 ; CHECK-NEXT:    [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ undef, [[BB2]] ], [ 10, [[BB3]] ]
365 ; CHECK-NEXT:    [[RES:%.*]] = and i64 [[P]], 255
366 ; CHECK-NEXT:    ret i64 [[RES]]
368 entry:
369   br i1 %c1, label %bb1, label %bb2
371 bb1:
372   %r = and i64 %a, 255
373   br label %bb4
375 bb2:
376   br i1 %c2, label %bb3, label %bb4
378 bb3:
379   br label %bb4
381 bb4:
382   %p = phi i64 [ %r, %bb1 ], [ undef, %bb2], [ 10, %bb3 ]
383   %res = and i64 %p, 255
384   ret i64 %res
388 define i64 @constant_range_and_phi_constant_undef(i1 %c1, i1 %c2, i64 %a) {
389 ; CHECK-LABEL: @constant_range_and_phi_constant_undef(
390 ; CHECK-NEXT:  entry:
391 ; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
392 ; CHECK:       bb1:
393 ; CHECK-NEXT:    [[R:%.*]] = and i64 [[A:%.*]], 255
394 ; CHECK-NEXT:    br label [[BB5:%.*]]
395 ; CHECK:       bb2:
396 ; CHECK-NEXT:    br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
397 ; CHECK:       bb3:
398 ; CHECK-NEXT:    br label [[BB4]]
399 ; CHECK:       bb4:
400 ; CHECK-NEXT:    br label [[BB5]]
401 ; CHECK:       bb5:
402 ; CHECK-NEXT:    [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ 10, [[BB4]] ]
403 ; CHECK-NEXT:    [[RES:%.*]] = and i64 [[P]], 255
404 ; CHECK-NEXT:    ret i64 [[RES]]
406 entry:
407   br i1 %c1, label %bb1, label %bb2
409 bb1:
410   %r = and i64 %a, 255
411   br label %bb5
413 bb2:
414   br i1 %c2, label %bb3, label %bb4
416 bb3:
417   br label %bb4
419 bb4:
420   %p.1 = phi i64 [ 10, %bb2 ], [ undef, %bb3]
421   br label %bb5
423 bb5:
424   %p = phi i64 [ %r, %bb1 ], [ %p.1, %bb4]
425   %res = and i64 %p, 255
426   ret i64 %res