1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --verbose
2 ; RUN: opt -S -passes=sccp %s | FileCheck %s
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
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)
36 ; Below are test cases for PR44949.
38 ; We can remove `%res = and i64 %p, 255`, because %r = 0 and we can eliminate
40 define i64 @constant_and_undef(i1 %c1, i64 %a) {
41 ; CHECK-LABEL: @constant_and_undef(
43 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
45 ; CHECK-NEXT: br label [[BB3:%.*]]
47 ; CHECK-NEXT: br label [[BB3]]
49 ; CHECK-NEXT: ret i64 0
52 br i1 %c1, label %bb1, label %bb2
62 %p = phi i64 [ undef, %bb1 ], [ %r, %bb2 ]
63 %res = and i64 %p, 255
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(
72 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
74 ; CHECK-NEXT: br label [[BB3:%.*]]
76 ; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255
77 ; CHECK-NEXT: br label [[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]]
84 br i1 %cond, label %bb1, label %bb2
94 %p = phi i64 [ undef, %bb1 ], [ %r, %bb2 ]
95 %res = and i64 %p, 255
99 ; Same as @constant_range_and_undef, with the undef coming from the other
101 define i64 @constant_range_and_undef_switched_incoming(i1 %cond, i64 %a) {
102 ; CHECK-LABEL: @constant_range_and_undef_switched_incoming(
104 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
106 ; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255
107 ; CHECK-NEXT: br label [[BB3:%.*]]
109 ; CHECK-NEXT: br label [[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]]
116 br i1 %cond, label %bb1, label %bb2
126 %p = phi i64 [ %r, %bb1 ], [ undef, %bb2 ]
127 %res = and i64 %p, 255
131 define i64 @constant_range_and_255_100(i1 %cond, i64 %a) {
132 ; CHECK-LABEL: @constant_range_and_255_100(
134 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
136 ; CHECK-NEXT: [[R_1:%.*]] = and i64 [[A:%.*]], 100
137 ; CHECK-NEXT: br label [[BB3:%.*]]
139 ; CHECK-NEXT: [[R_2:%.*]] = and i64 [[A]], 255
140 ; CHECK-NEXT: br label [[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]]
148 br i1 %cond, label %bb1, label %bb2
151 %r.1 = and i64 %a, 100
155 %r.2 = and i64 %a, 255
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)
167 define i64 @constant_range_and_undef2(i1 %c1, i1 %c2, i64 %a) {
168 ; CHECK-LABEL: @constant_range_and_undef2(
170 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
172 ; CHECK-NEXT: [[V1:%.*]] = add i64 undef, undef
173 ; CHECK-NEXT: br label [[BB3:%.*]]
175 ; CHECK-NEXT: [[V2:%.*]] = and i64 [[A:%.*]], 255
176 ; CHECK-NEXT: br label [[BB3]]
178 ; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[V1]], [[BB1]] ], [ [[V2]], [[BB2]] ]
179 ; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB4:%.*]], label [[BB5:%.*]]
181 ; CHECK-NEXT: br label [[BB6:%.*]]
183 ; CHECK-NEXT: [[V3:%.*]] = and i64 [[A]], 255
184 ; CHECK-NEXT: br label [[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]]
191 br i1 %c1, label %bb1, label %bb2
194 %v1 = add i64 undef, undef
198 %v2 = and i64 %a, 255
202 %p = phi i64 [ %v1, %bb1 ], [ %v2, %bb2 ]
203 br i1 %c2, label %bb4, label %bb5
209 %v3 = and i64 %a, 255
213 %p2 = phi i64 [ %p, %bb4 ], [ %v3, %bb5 ]
214 %res = and i64 %p2, 255
218 define i1 @constant_range_and_undef_3(i1 %cond, i64 %a) {
219 ; CHECK-LABEL: @constant_range_and_undef_3(
221 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
223 ; CHECK-NEXT: br label [[BB3:%.*]]
225 ; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255
226 ; CHECK-NEXT: br label [[BB3]]
228 ; CHECK-NEXT: [[P:%.*]] = phi i64 [ undef, [[BB1]] ], [ [[R]], [[BB2]] ]
229 ; CHECK-NEXT: ret i1 true
232 br i1 %cond, label %bb1, label %bb2
242 %p = phi i64 [ undef, %bb1 ], [ %r, %bb2 ]
243 %c = icmp ult i64 %p, 256
247 define i1 @constant_range_and_undef_3_switched_incoming(i1 %cond, i64 %a) {
248 ; CHECK-LABEL: @constant_range_and_undef_3_switched_incoming(
250 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
252 ; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255
253 ; CHECK-NEXT: br label [[BB3:%.*]]
255 ; CHECK-NEXT: br label [[BB3]]
257 ; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ undef, [[BB2]] ]
258 ; CHECK-NEXT: ret i1 true
261 br i1 %cond, label %bb1, label %bb2
271 %p = phi i64 [ %r, %bb1 ], [ undef, %bb2 ]
272 %c = icmp ult i64 %p, 256
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(
281 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
283 ; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255
284 ; CHECK-NEXT: br label [[BB4:%.*]]
286 ; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB4]]
288 ; CHECK-NEXT: br label [[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]]
295 br i1 %c1, label %bb1, label %bb2
302 br i1 %c2, label %bb3, label %bb4
308 %p = phi i64 [ %r, %bb1 ], [ 10, %bb2], [ undef, %bb3 ]
309 %res = and i64 %p, 255
313 ; Same as @constant_range_and_undef_3_incoming_v1, but with different order of
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(
318 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
320 ; CHECK-NEXT: br label [[BB4:%.*]]
322 ; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB4]]
324 ; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255
325 ; CHECK-NEXT: br label [[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]]
332 br i1 %c1, label %bb1, label %bb2
338 br i1 %c2, label %bb3, label %bb4
345 %p = phi i64 [ undef, %bb1 ], [ 10, %bb2], [ %r, %bb3 ]
346 %res = and i64 %p, 255
350 ; Same as @constant_range_and_undef_3_incoming_v1, but with different order of
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(
355 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
357 ; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255
358 ; CHECK-NEXT: br label [[BB4:%.*]]
360 ; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB4]]
362 ; CHECK-NEXT: br label [[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]]
369 br i1 %c1, label %bb1, label %bb2
376 br i1 %c2, label %bb3, label %bb4
382 %p = phi i64 [ %r, %bb1 ], [ undef, %bb2], [ 10, %bb3 ]
383 %res = and i64 %p, 255
388 define i64 @constant_range_and_phi_constant_undef(i1 %c1, i1 %c2, i64 %a) {
389 ; CHECK-LABEL: @constant_range_and_phi_constant_undef(
391 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
393 ; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255
394 ; CHECK-NEXT: br label [[BB5:%.*]]
396 ; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
398 ; CHECK-NEXT: br label [[BB4]]
400 ; CHECK-NEXT: br label [[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]]
407 br i1 %c1, label %bb1, label %bb2
414 br i1 %c2, label %bb3, label %bb4
420 %p.1 = phi i64 [ 10, %bb2 ], [ undef, %bb3]
424 %p = phi i64 [ %r, %bb1 ], [ %p.1, %bb4]
425 %res = and i64 %p, 255