1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=correlated-propagation %s | FileCheck %s
4 ; Test case for PR44949.
8 ; We can remove `%res = and i64 %p, 255`, because %r = 0 and we can eliminate
10 define i64 @constant_and_undef(i1 %c1, i64 %a) {
11 ; CHECK-LABEL: @constant_and_undef(
13 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
15 ; CHECK-NEXT: br label [[BB3:%.*]]
17 ; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 0
18 ; CHECK-NEXT: br label [[BB3]]
20 ; CHECK-NEXT: call void @use(i1 false)
21 ; CHECK-NEXT: call void @use(i1 true)
22 ; CHECK-NEXT: ret i64 0
25 br i1 %c1, label %bb1, label %bb2
35 %p = phi i64 [ undef, %bb1 ], [ %r, %bb2 ]
36 %res = and i64 %p, 255
37 %f.1 = icmp eq i64 %p, 1
38 call void @use(i1 %f.1)
39 %t.1 = icmp eq i64 %p, 0
40 call void @use(i1 %t.1)
44 ; Check that we go to overdefined when merging a constant range with undef. We
45 ; cannot remove '%res = and i64 %p, 255'.
46 define i64 @constant_range_and_undef(i1 %cond, i64 %a) {
47 ; CHECK-LABEL: @constant_range_and_undef(
49 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
51 ; CHECK-NEXT: br label [[BB3:%.*]]
53 ; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255
54 ; CHECK-NEXT: br label [[BB3]]
56 ; CHECK-NEXT: [[P:%.*]] = phi i64 [ undef, [[BB1]] ], [ [[R]], [[BB2]] ]
57 ; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 255
58 ; CHECK-NEXT: br label [[EXIT:%.*]]
60 ; CHECK-NEXT: call void @use(i1 false)
61 ; CHECK-NEXT: call void @use(i1 true)
62 ; CHECK-NEXT: ret i64 [[RES]]
65 br i1 %cond, label %bb1, label %bb2
75 %p = phi i64 [ undef, %bb1 ], [ %r, %bb2 ]
76 %res = and i64 %p, 255
79 exit: ; CVP only simplifies based on ranges for non-local conditions.
80 %f.1 = icmp eq i64 %p, 256
81 call void @use(i1 %f.1)
82 %t.1 = icmp ne i64 %p, 256
83 call void @use(i1 %t.1)
87 define i64 @constant_range_and_undef2(i1 %c1, i1 %c2, i64 %a) {
88 ; CHECK-LABEL: @constant_range_and_undef2(
90 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
92 ; CHECK-NEXT: [[V1:%.*]] = add i64 undef, undef
93 ; CHECK-NEXT: br label [[BB3:%.*]]
95 ; CHECK-NEXT: [[V2:%.*]] = and i64 [[A:%.*]], 255
96 ; CHECK-NEXT: br label [[BB3]]
98 ; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[V1]], [[BB1]] ], [ [[V2]], [[BB2]] ]
99 ; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB4:%.*]], label [[BB5:%.*]]
101 ; CHECK-NEXT: br label [[BB6:%.*]]
103 ; CHECK-NEXT: [[V3:%.*]] = and i64 [[A]], 255
104 ; CHECK-NEXT: br label [[BB6]]
106 ; CHECK-NEXT: [[P2:%.*]] = phi i64 [ [[P]], [[BB4]] ], [ [[V3]], [[BB5]] ]
107 ; CHECK-NEXT: [[RES:%.*]] = and i64 [[P2]], 255
108 ; CHECK-NEXT: br label [[EXIT:%.*]]
110 ; CHECK-NEXT: [[F_1:%.*]] = icmp eq i64 [[P]], 256
111 ; CHECK-NEXT: call void @use(i1 [[F_1]])
112 ; CHECK-NEXT: [[T_1:%.*]] = icmp ne i64 [[P]], 256
113 ; CHECK-NEXT: call void @use(i1 [[T_1]])
114 ; CHECK-NEXT: ret i64 [[RES]]
117 br i1 %c1, label %bb1, label %bb2
120 %v1 = add i64 undef, undef
124 %v2 = and i64 %a, 255
128 %p = phi i64 [ %v1, %bb1 ], [ %v2, %bb2 ]
129 br i1 %c2, label %bb4, label %bb5
135 %v3 = and i64 %a, 255
139 %p2 = phi i64 [ %p, %bb4 ], [ %v3, %bb5 ]
140 %res = and i64 %p2, 255
143 exit: ; CVP only simplifies based on ranges for non-local conditions.
144 %f.1 = icmp eq i64 %p, 256
145 call void @use(i1 %f.1)
146 %t.1 = icmp ne i64 %p, 256
147 call void @use(i1 %t.1)
151 define i1 @constant_range_and_undef_3(i1 %cond, i64 %a) {
152 ; CHECK-LABEL: @constant_range_and_undef_3(
154 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
156 ; CHECK-NEXT: br label [[BB3:%.*]]
158 ; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255
159 ; CHECK-NEXT: br label [[BB3]]
161 ; CHECK-NEXT: [[P:%.*]] = phi i64 [ undef, [[BB1]] ], [ [[R]], [[BB2]] ]
162 ; CHECK-NEXT: br label [[EXIT:%.*]]
164 ; CHECK-NEXT: call void @use(i1 false)
165 ; CHECK-NEXT: call void @use(i1 true)
166 ; CHECK-NEXT: ret i1 true
169 br i1 %cond, label %bb1, label %bb2
179 %p = phi i64 [ undef, %bb1 ], [ %r, %bb2 ]
182 exit: ; CVP only simplifies based on ranges for non-local conditions.
183 %c = icmp ult i64 %p, 256
184 %f.1 = icmp eq i64 %p, 256
185 call void @use(i1 %f.1)
186 %t.1 = icmp ne i64 %p, 256
187 call void @use(i1 %t.1)
191 ; Same as @constant_range_and_undef, but with 3 incoming
192 ; values: undef, a constant and a constant range.
193 define i64 @constant_range_and_undef_3_incoming_v1(i1 %c1, i1 %c2, i64 %a) {
194 ; CHECK-LABEL: @constant_range_and_undef_3_incoming_v1(
196 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
198 ; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255
199 ; CHECK-NEXT: br label [[BB4:%.*]]
201 ; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB4]]
203 ; CHECK-NEXT: br label [[BB4]]
205 ; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ 10, [[BB2]] ], [ undef, [[BB3]] ]
206 ; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 255
207 ; CHECK-NEXT: br label [[EXIT:%.*]]
209 ; CHECK-NEXT: call void @use(i1 false)
210 ; CHECK-NEXT: call void @use(i1 true)
211 ; CHECK-NEXT: ret i64 [[RES]]
214 br i1 %c1, label %bb1, label %bb2
221 br i1 %c2, label %bb3, label %bb4
227 %p = phi i64 [ %r, %bb1 ], [ 10, %bb2], [ undef, %bb3 ]
228 %res = and i64 %p, 255
231 exit: ; CVP only simplifies based on ranges for non-local conditions.
232 %f.1 = icmp eq i64 %p, 256
233 call void @use(i1 %f.1)
234 %t.1 = icmp ne i64 %p, 256
235 call void @use(i1 %t.1)
239 ; Same as @constant_range_and_undef_3_incoming_v1, but with different order of
241 define i64 @constant_range_and_undef_3_incoming_v2(i1 %c1, i1 %c2, i64 %a) {
242 ; CHECK-LABEL: @constant_range_and_undef_3_incoming_v2(
244 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
246 ; CHECK-NEXT: br label [[BB4:%.*]]
248 ; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB4]]
250 ; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255
251 ; CHECK-NEXT: br label [[BB4]]
253 ; CHECK-NEXT: [[P:%.*]] = phi i64 [ undef, [[BB1]] ], [ 10, [[BB2]] ], [ [[R]], [[BB3]] ]
254 ; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 255
255 ; CHECK-NEXT: br label [[EXIT:%.*]]
257 ; CHECK-NEXT: call void @use(i1 false)
258 ; CHECK-NEXT: call void @use(i1 true)
259 ; CHECK-NEXT: ret i64 [[RES]]
262 br i1 %c1, label %bb1, label %bb2
268 br i1 %c2, label %bb3, label %bb4
275 %p = phi i64 [ undef, %bb1 ], [ 10, %bb2], [ %r, %bb3 ]
276 %res = and i64 %p, 255
279 exit: ; CVP only simplifies based on ranges for non-local conditions.
280 %f.1 = icmp eq i64 %p, 256
281 call void @use(i1 %f.1)
282 %t.1 = icmp ne i64 %p, 256
283 call void @use(i1 %t.1)
287 ; Same as @constant_range_and_undef_3_incoming_v1, but with different order of
289 define i64 @constant_range_and_undef_3_incoming_v3(i1 %c1, i1 %c2, i64 %a) {
290 ; CHECK-LABEL: @constant_range_and_undef_3_incoming_v3(
292 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
294 ; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255
295 ; CHECK-NEXT: br label [[BB4:%.*]]
297 ; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB4]]
299 ; CHECK-NEXT: br label [[BB4]]
301 ; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ undef, [[BB2]] ], [ 10, [[BB3]] ]
302 ; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 255
303 ; CHECK-NEXT: br label [[EXIT:%.*]]
305 ; CHECK-NEXT: call void @use(i1 false)
306 ; CHECK-NEXT: call void @use(i1 true)
307 ; CHECK-NEXT: ret i64 [[RES]]
310 br i1 %c1, label %bb1, label %bb2
317 br i1 %c2, label %bb3, label %bb4
323 %p = phi i64 [ %r, %bb1 ], [ undef, %bb2], [ 10, %bb3 ]
324 %res = and i64 %p, 255
327 exit: ; CVP only simplifies based on ranges for non-local conditions.
328 %f.1 = icmp eq i64 %p, 256
329 call void @use(i1 %f.1)
330 %t.1 = icmp ne i64 %p, 256
331 call void @use(i1 %t.1)
335 define i64 @constant_range_and_phi_constant_undef(i1 %c1, i1 %c2, i64 %a) {
336 ; CHECK-LABEL: @constant_range_and_phi_constant_undef(
338 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
340 ; CHECK-NEXT: [[R:%.*]] = and i64 [[A:%.*]], 255
341 ; CHECK-NEXT: br label [[BB5:%.*]]
343 ; CHECK-NEXT: br i1 [[C2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
345 ; CHECK-NEXT: br label [[BB4]]
347 ; CHECK-NEXT: br label [[BB5]]
349 ; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ 10, [[BB4]] ]
350 ; CHECK-NEXT: br label [[EXIT:%.*]]
352 ; CHECK-NEXT: call void @use(i1 false)
353 ; CHECK-NEXT: call void @use(i1 true)
354 ; CHECK-NEXT: ret i64 [[P]]
357 br i1 %c1, label %bb1, label %bb2
364 br i1 %c2, label %bb3, label %bb4
370 %p.1 = phi i64 [ 10, %bb2 ], [ undef, %bb3]
374 %p = phi i64 [ %r, %bb1 ], [ %p.1, %bb4]
375 %res = and i64 %p, 255
378 exit: ; CVP only simplifies based on ranges for non-local conditions.
379 %f.1 = icmp eq i64 %p, 256
380 call void @use(i1 %f.1)
381 %t.1 = icmp ne i64 %p, 256
382 call void @use(i1 %t.1)
386 ; Test case for PR68381.
387 ; Because of `undef`, we can only delete the second `and` instruction.
388 define i32 @constant_range_and_undef_and(i1 %c0, i1 %c1, i8 %v1, i8 %v2) {
389 ; CHECK-LABEL: @constant_range_and_undef_and(
391 ; CHECK-NEXT: br i1 [[C0:%.*]], label [[BB0:%.*]], label [[BB1:%.*]]
393 ; CHECK-NEXT: [[V1_I32:%.*]] = zext i8 [[V1:%.*]] to i32
394 ; CHECK-NEXT: br label [[BB1]]
396 ; CHECK-NEXT: [[X:%.*]] = phi i32 [ [[V1_I32]], [[BB0]] ], [ undef, [[START:%.*]] ]
397 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB0]], label [[BB2:%.*]]
399 ; CHECK-NEXT: [[V2_I32:%.*]] = zext i8 [[V2:%.*]] to i32
400 ; CHECK-NEXT: [[Y:%.*]] = or i32 [[X]], [[V2_I32]]
401 ; CHECK-NEXT: [[Z:%.*]] = and i32 [[Y]], 255
402 ; CHECK-NEXT: ret i32 [[Z]]
405 br i1 %c0, label %bb0, label %bb1
408 %v1_i32 = zext i8 %v1 to i32
412 %x = phi i32 [ %v1_i32, %bb0 ], [ undef, %start ]
413 br i1 %c1, label %bb0, label %bb2
416 %v2_i32 = zext i8 %v2 to i32
417 %y = or i32 %x, %v2_i32
419 %z1 = and i32 %z, 255