1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 ; https://bugs.llvm.org/show_bug.cgi?id=6773
10 ; Should be transformed into:
15 ; ============================================================================ ;
16 ; Most basic positive tests
17 ; ============================================================================ ;
19 define i32 @p(i32 %x, i32 %y, i32 noundef %m) {
21 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]
22 ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1
23 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], [[NEG]]
24 ; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]]
25 ; CHECK-NEXT: ret i32 [[RET]]
29 %and1 = and i32 %neg, %y
30 %ret = xor i32 %and, %and1
34 define <2 x i32> @p_splatvec(<2 x i32> %x, <2 x i32> %y, <2 x i32> noundef %m) {
35 ; CHECK-LABEL: @p_splatvec(
36 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], [[M:%.*]]
37 ; CHECK-NEXT: [[NEG:%.*]] = xor <2 x i32> [[M]], splat (i32 -1)
38 ; CHECK-NEXT: [[AND1:%.*]] = and <2 x i32> [[Y:%.*]], [[NEG]]
39 ; CHECK-NEXT: [[RET:%.*]] = or disjoint <2 x i32> [[AND]], [[AND1]]
40 ; CHECK-NEXT: ret <2 x i32> [[RET]]
42 %and = and <2 x i32> %x, %m
43 %neg = xor <2 x i32> %m, <i32 -1, i32 -1>
44 %and1 = and <2 x i32> %neg, %y
45 %ret = xor <2 x i32> %and, %and1
49 define <3 x i32> @p_vec_undef(<3 x i32> %x, <3 x i32> %y, <3 x i32> noundef %m) {
50 ; CHECK-LABEL: @p_vec_undef(
51 ; CHECK-NEXT: [[AND:%.*]] = and <3 x i32> [[X:%.*]], [[M:%.*]]
52 ; CHECK-NEXT: [[NEG:%.*]] = xor <3 x i32> [[M]], <i32 -1, i32 undef, i32 -1>
53 ; CHECK-NEXT: [[AND1:%.*]] = and <3 x i32> [[NEG]], [[Y:%.*]]
54 ; CHECK-NEXT: [[RET:%.*]] = xor <3 x i32> [[AND]], [[AND1]]
55 ; CHECK-NEXT: ret <3 x i32> [[RET]]
57 %and = and <3 x i32> %x, %m
58 %neg = xor <3 x i32> %m, <i32 -1, i32 undef, i32 -1>
59 %and1 = and <3 x i32> %neg, %y
60 %ret = xor <3 x i32> %and, %and1
64 define <3 x i32> @p_vec_poison(<3 x i32> %x, <3 x i32> %y, <3 x i32> noundef %m) {
65 ; CHECK-LABEL: @p_vec_poison(
66 ; CHECK-NEXT: [[AND:%.*]] = and <3 x i32> [[X:%.*]], [[M:%.*]]
67 ; CHECK-NEXT: [[NEG:%.*]] = xor <3 x i32> [[M]], <i32 -1, i32 poison, i32 -1>
68 ; CHECK-NEXT: [[AND1:%.*]] = and <3 x i32> [[Y:%.*]], [[NEG]]
69 ; CHECK-NEXT: [[RET:%.*]] = or disjoint <3 x i32> [[AND]], [[AND1]]
70 ; CHECK-NEXT: ret <3 x i32> [[RET]]
72 %and = and <3 x i32> %x, %m
73 %neg = xor <3 x i32> %m, <i32 -1, i32 poison, i32 -1>
74 %and1 = and <3 x i32> %neg, %y
75 %ret = xor <3 x i32> %and, %and1
79 ; ============================================================================ ;
81 ; ============================================================================ ;
83 define i32 @p_constmask(i32 %x, i32 %y) {
84 ; CHECK-LABEL: @p_constmask(
85 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 65280
86 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], -65281
87 ; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]]
88 ; CHECK-NEXT: ret i32 [[RET]]
90 %and = and i32 %x, 65280
91 %and1 = and i32 %y, -65281
92 %ret = xor i32 %and, %and1
96 define <2 x i32> @p_constmask_splatvec(<2 x i32> %x, <2 x i32> %y) {
97 ; CHECK-LABEL: @p_constmask_splatvec(
98 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 65280)
99 ; CHECK-NEXT: [[AND1:%.*]] = and <2 x i32> [[Y:%.*]], splat (i32 -65281)
100 ; CHECK-NEXT: [[RET:%.*]] = or disjoint <2 x i32> [[AND]], [[AND1]]
101 ; CHECK-NEXT: ret <2 x i32> [[RET]]
103 %and = and <2 x i32> %x, <i32 65280, i32 65280>
104 %and1 = and <2 x i32> %y, <i32 -65281, i32 -65281>
105 %ret = xor <2 x i32> %and, %and1
109 define <2 x i32> @p_constmask_vec(<2 x i32> %x, <2 x i32> %y) {
110 ; CHECK-LABEL: @p_constmask_vec(
111 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 65280, i32 16776960>
112 ; CHECK-NEXT: [[AND1:%.*]] = and <2 x i32> [[Y:%.*]], <i32 -65281, i32 -16776961>
113 ; CHECK-NEXT: [[RET:%.*]] = xor <2 x i32> [[AND]], [[AND1]]
114 ; CHECK-NEXT: ret <2 x i32> [[RET]]
116 %and = and <2 x i32> %x, <i32 65280, i32 16776960>
117 %and1 = and <2 x i32> %y, <i32 -65281, i32 -16776961>
118 %ret = xor <2 x i32> %and, %and1
122 define <3 x i32> @p_constmask_vec_undef(<3 x i32> %x, <3 x i32> %y) {
123 ; CHECK-LABEL: @p_constmask_vec_undef(
124 ; CHECK-NEXT: [[AND:%.*]] = and <3 x i32> [[X:%.*]], <i32 65280, i32 undef, i32 65280>
125 ; CHECK-NEXT: [[AND1:%.*]] = and <3 x i32> [[Y:%.*]], <i32 -65281, i32 undef, i32 -65281>
126 ; CHECK-NEXT: [[RET:%.*]] = xor <3 x i32> [[AND]], [[AND1]]
127 ; CHECK-NEXT: ret <3 x i32> [[RET]]
129 %and = and <3 x i32> %x, <i32 65280, i32 undef, i32 65280>
130 %and1 = and <3 x i32> %y, <i32 -65281, i32 undef, i32 -65281>
131 %ret = xor <3 x i32> %and, %and1
135 ; ============================================================================ ;
136 ; Constant mask with no common bits set, but common unset bits.
137 ; ============================================================================ ;
139 define i32 @p_constmask2(i32 %x, i32 %y) {
140 ; CHECK-LABEL: @p_constmask2(
141 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 61440
142 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], -65281
143 ; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]]
144 ; CHECK-NEXT: ret i32 [[RET]]
146 %and = and i32 %x, 61440
147 %and1 = and i32 %y, -65281
148 %ret = xor i32 %and, %and1
152 define <2 x i32> @p_constmask2_splatvec(<2 x i32> %x, <2 x i32> %y) {
153 ; CHECK-LABEL: @p_constmask2_splatvec(
154 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 61440)
155 ; CHECK-NEXT: [[AND1:%.*]] = and <2 x i32> [[Y:%.*]], splat (i32 -65281)
156 ; CHECK-NEXT: [[RET:%.*]] = or disjoint <2 x i32> [[AND]], [[AND1]]
157 ; CHECK-NEXT: ret <2 x i32> [[RET]]
159 %and = and <2 x i32> %x, <i32 61440, i32 61440>
160 %and1 = and <2 x i32> %y, <i32 -65281, i32 -65281>
161 %ret = xor <2 x i32> %and, %and1
165 define <2 x i32> @p_constmask2_vec(<2 x i32> %x, <2 x i32> %y) {
166 ; CHECK-LABEL: @p_constmask2_vec(
167 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 61440, i32 16711680>
168 ; CHECK-NEXT: [[AND1:%.*]] = and <2 x i32> [[Y:%.*]], <i32 -65281, i32 -16776961>
169 ; CHECK-NEXT: [[RET:%.*]] = xor <2 x i32> [[AND]], [[AND1]]
170 ; CHECK-NEXT: ret <2 x i32> [[RET]]
172 %and = and <2 x i32> %x, <i32 61440, i32 16711680>
173 %and1 = and <2 x i32> %y, <i32 -65281, i32 -16776961>
174 %ret = xor <2 x i32> %and, %and1
178 define <3 x i32> @p_constmask2_vec_undef(<3 x i32> %x, <3 x i32> %y) {
179 ; CHECK-LABEL: @p_constmask2_vec_undef(
180 ; CHECK-NEXT: [[AND:%.*]] = and <3 x i32> [[X:%.*]], <i32 61440, i32 undef, i32 61440>
181 ; CHECK-NEXT: [[AND1:%.*]] = and <3 x i32> [[Y:%.*]], <i32 -65281, i32 undef, i32 -65281>
182 ; CHECK-NEXT: [[RET:%.*]] = xor <3 x i32> [[AND]], [[AND1]]
183 ; CHECK-NEXT: ret <3 x i32> [[RET]]
185 %and = and <3 x i32> %x, <i32 61440, i32 undef, i32 61440>
186 %and1 = and <3 x i32> %y, <i32 -65281, i32 undef, i32 -65281>
187 %ret = xor <3 x i32> %and, %and1
191 ; ============================================================================ ;
193 ; ============================================================================ ;
195 ; Used to make sure that the IR complexity sorting does not interfere.
198 define i32 @p_commutative0(i32 %x, i32 %y, i32 noundef %m) {
199 ; CHECK-LABEL: @p_commutative0(
200 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]]
201 ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1
202 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], [[NEG]]
203 ; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]]
204 ; CHECK-NEXT: ret i32 [[RET]]
206 %and = and i32 %m, %x ; swapped order
207 %neg = xor i32 %m, -1
208 %and1 = and i32 %neg, %y
209 %ret = xor i32 %and, %and1
213 define i32 @p_commutative1(i32 %x, i32 noundef %m) {
214 ; CHECK-LABEL: @p_commutative1(
215 ; CHECK-NEXT: [[Y:%.*]] = call i32 @gen32()
216 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]
217 ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1
218 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y]], [[NEG]]
219 ; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]]
220 ; CHECK-NEXT: ret i32 [[RET]]
222 %y = call i32 @gen32()
223 %and = and i32 %x, %m
224 %neg = xor i32 %m, -1
225 %and1 = and i32 %y, %neg; swapped order
226 %ret = xor i32 %and, %and1
230 define i32 @p_commutative2(i32 %x, i32 %y, i32 noundef %m) {
231 ; CHECK-LABEL: @p_commutative2(
232 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]
233 ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1
234 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], [[NEG]]
235 ; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND1]], [[AND]]
236 ; CHECK-NEXT: ret i32 [[RET]]
238 %and = and i32 %x, %m
239 %neg = xor i32 %m, -1
240 %and1 = and i32 %neg, %y
241 %ret = xor i32 %and1, %and ; swapped order
245 define i32 @p_commutative3(i32 %x, i32 noundef %m) {
246 ; CHECK-LABEL: @p_commutative3(
247 ; CHECK-NEXT: [[Y:%.*]] = call i32 @gen32()
248 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]]
249 ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1
250 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y]], [[NEG]]
251 ; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]]
252 ; CHECK-NEXT: ret i32 [[RET]]
254 %y = call i32 @gen32()
255 %and = and i32 %m, %x ; swapped order
256 %neg = xor i32 %m, -1
257 %and1 = and i32 %y, %neg; swapped order
258 %ret = xor i32 %and, %and1
262 define i32 @p_commutative4(i32 %x, i32 %y, i32 noundef %m) {
263 ; CHECK-LABEL: @p_commutative4(
264 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]]
265 ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1
266 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], [[NEG]]
267 ; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND1]], [[AND]]
268 ; CHECK-NEXT: ret i32 [[RET]]
270 %and = and i32 %m, %x ; swapped order
271 %neg = xor i32 %m, -1
272 %and1 = and i32 %neg, %y
273 %ret = xor i32 %and1, %and ; swapped order
277 define i32 @p_commutative5(i32 %x, i32 noundef %m) {
278 ; CHECK-LABEL: @p_commutative5(
279 ; CHECK-NEXT: [[Y:%.*]] = call i32 @gen32()
280 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]
281 ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1
282 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y]], [[NEG]]
283 ; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND1]], [[AND]]
284 ; CHECK-NEXT: ret i32 [[RET]]
286 %y = call i32 @gen32()
287 %and = and i32 %x, %m
288 %neg = xor i32 %m, -1
289 %and1 = and i32 %y, %neg; swapped order
290 %ret = xor i32 %and1, %and ; swapped order
294 define i32 @p_commutative6(i32 %x, i32 noundef %m) {
295 ; CHECK-LABEL: @p_commutative6(
296 ; CHECK-NEXT: [[Y:%.*]] = call i32 @gen32()
297 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]]
298 ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1
299 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y]], [[NEG]]
300 ; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND1]], [[AND]]
301 ; CHECK-NEXT: ret i32 [[RET]]
303 %y = call i32 @gen32()
304 %and = and i32 %m, %x ; swapped order
305 %neg = xor i32 %m, -1
306 %and1 = and i32 %y, %neg; swapped order
307 %ret = xor i32 %and1, %and ; swapped order
311 define i32 @p_constmask_commutative(i32 %x, i32 %y) {
312 ; CHECK-LABEL: @p_constmask_commutative(
313 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 65280
314 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], -65281
315 ; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND1]], [[AND]]
316 ; CHECK-NEXT: ret i32 [[RET]]
318 %and = and i32 %x, 65280
319 %and1 = and i32 %y, -65281
320 %ret = xor i32 %and1, %and ; swapped order
324 ; ============================================================================ ;
325 ; Negative tests. Should not be folded.
326 ; ============================================================================ ;
330 declare void @use32(i32)
332 define i32 @n0_oneuse(i32 %x, i32 %y, i32 noundef %m) {
333 ; CHECK-LABEL: @n0_oneuse(
334 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]
335 ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1
336 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], [[NEG]]
337 ; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]]
338 ; CHECK-NEXT: call void @use32(i32 [[AND]])
339 ; CHECK-NEXT: call void @use32(i32 [[NEG]])
340 ; CHECK-NEXT: call void @use32(i32 [[AND1]])
341 ; CHECK-NEXT: ret i32 [[RET]]
343 %and = and i32 %x, %m
344 %neg = xor i32 %m, -1
345 %and1 = and i32 %neg, %y
346 %ret = xor i32 %and, %and1
347 call void @use32(i32 %and)
348 call void @use32(i32 %neg)
349 call void @use32(i32 %and1)
353 define i32 @n0_constmask_oneuse(i32 %x, i32 %y) {
354 ; CHECK-LABEL: @n0_constmask_oneuse(
355 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 65280
356 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], -65281
357 ; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]]
358 ; CHECK-NEXT: call void @use32(i32 [[AND]])
359 ; CHECK-NEXT: call void @use32(i32 [[AND1]])
360 ; CHECK-NEXT: ret i32 [[RET]]
362 %and = and i32 %x, 65280
363 %and1 = and i32 %y, -65281
364 %ret = xor i32 %and, %and1
365 call void @use32(i32 %and)
366 call void @use32(i32 %and1)
372 define i32 @n1_badxor(i32 %x, i32 %y, i32 %m) {
373 ; CHECK-LABEL: @n1_badxor(
374 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]]
375 ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], 1
376 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NEG]], [[Y:%.*]]
377 ; CHECK-NEXT: [[RET:%.*]] = xor i32 [[AND]], [[AND1]]
378 ; CHECK-NEXT: ret i32 [[RET]]
380 %and = and i32 %x, %m
381 %neg = xor i32 %m, 1 ; not -1
382 %and1 = and i32 %neg, %y
383 %ret = xor i32 %and, %and1
387 ; Different mask is used
389 define i32 @n2_badmask(i32 %x, i32 %y, i32 %m1, i32 %m2) {
390 ; CHECK-LABEL: @n2_badmask(
391 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[M1:%.*]], [[X:%.*]]
392 ; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M2:%.*]], -1
393 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], [[NEG]]
394 ; CHECK-NEXT: [[RET:%.*]] = xor i32 [[AND]], [[AND1]]
395 ; CHECK-NEXT: ret i32 [[RET]]
397 %and = and i32 %m1, %x
398 %neg = xor i32 %m2, -1 ; different mask, not %m1
399 %and1 = and i32 %neg, %y
400 %ret = xor i32 %and, %and1
404 ; Different const mask is used
406 define i32 @n3_constmask_badmask(i32 %x, i32 %y) {
407 ; CHECK-LABEL: @n3_constmask_badmask(
408 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 65280
409 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], -65280
410 ; CHECK-NEXT: [[RET:%.*]] = xor i32 [[AND]], [[AND1]]
411 ; CHECK-NEXT: ret i32 [[RET]]
413 %and = and i32 %x, 65280
414 %and1 = and i32 %y, -65280 ; not -65281, so they have one common bit
415 %ret = xor i32 %and, %and1
419 define i32 @n3_constmask_samemask(i32 %x, i32 %y) {
420 ; CHECK-LABEL: @n3_constmask_samemask(
421 ; CHECK-NEXT: [[AND2:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
422 ; CHECK-NEXT: [[RET:%.*]] = and i32 [[AND2]], 65280
423 ; CHECK-NEXT: ret i32 [[RET]]
425 %and = and i32 %x, 65280
426 %and1 = and i32 %y, 65280 ; both masks are the same
427 %ret = xor i32 %and, %and1