1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
6 define i32 @icmp_eq_and_pow2_shl1(i32 %0) {
7 ; CHECK-LABEL: @icmp_eq_and_pow2_shl1(
8 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP0:%.*]], 4
9 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP2]] to i32
10 ; CHECK-NEXT: ret i32 [[CONV]]
13 %and = and i32 %shl, 16
14 %cmp = icmp eq i32 %and, 0
15 %conv = zext i1 %cmp to i32
19 define <2 x i32> @icmp_eq_and_pow2_shl1_vec(<2 x i32> %0) {
20 ; CHECK-LABEL: @icmp_eq_and_pow2_shl1_vec(
21 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP0:%.*]], splat (i32 4)
22 ; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
23 ; CHECK-NEXT: ret <2 x i32> [[CONV]]
25 %shl = shl <2 x i32> <i32 1, i32 1>, %0
26 %and = and <2 x i32> %shl, <i32 16, i32 16>
27 %cmp = icmp eq <2 x i32> %and, <i32 0, i32 0>
28 %conv = zext <2 x i1> %cmp to <2 x i32>
32 define i32 @icmp_ne_and_pow2_shl1(i32 %0) {
33 ; CHECK-LABEL: @icmp_ne_and_pow2_shl1(
34 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0:%.*]], 4
35 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP2]] to i32
36 ; CHECK-NEXT: ret i32 [[CONV]]
39 %and = and i32 %shl, 16
40 %cmp = icmp ne i32 %and, 0
41 %conv = zext i1 %cmp to i32
45 define <2 x i32> @icmp_ne_and_pow2_shl1_vec(<2 x i32> %0) {
46 ; CHECK-LABEL: @icmp_ne_and_pow2_shl1_vec(
47 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP0:%.*]], splat (i32 4)
48 ; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
49 ; CHECK-NEXT: ret <2 x i32> [[CONV]]
51 %shl = shl <2 x i32> <i32 1, i32 1>, %0
52 %and = and <2 x i32> %shl, <i32 16, i32 16>
53 %cmp = icmp ne <2 x i32> %and, <i32 0, i32 0>
54 %conv = zext <2 x i1> %cmp to <2 x i32>
58 define i32 @icmp_eq_and_pow2_shl_pow2(i32 %0) {
59 ; CHECK-LABEL: @icmp_eq_and_pow2_shl_pow2(
60 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP0:%.*]], 3
61 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP2]] to i32
62 ; CHECK-NEXT: ret i32 [[CONV]]
65 %and = and i32 %shl, 16
66 %cmp = icmp eq i32 %and, 0
67 %conv = zext i1 %cmp to i32
71 define <2 x i32> @icmp_eq_and_pow2_shl_pow2_vec(<2 x i32> %0) {
72 ; CHECK-LABEL: @icmp_eq_and_pow2_shl_pow2_vec(
73 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP0:%.*]], splat (i32 2)
74 ; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
75 ; CHECK-NEXT: ret <2 x i32> [[CONV]]
77 %shl = shl <2 x i32> <i32 4, i32 4>, %0
78 %and = and <2 x i32> %shl, <i32 16, i32 16>
79 %cmp = icmp eq <2 x i32> %and, <i32 0, i32 0>
80 %conv = zext <2 x i1> %cmp to <2 x i32>
84 define i32 @icmp_ne_and_pow2_shl_pow2(i32 %0) {
85 ; CHECK-LABEL: @icmp_ne_and_pow2_shl_pow2(
86 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0:%.*]], 3
87 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP2]] to i32
88 ; CHECK-NEXT: ret i32 [[CONV]]
91 %and = and i32 %shl, 16
92 %cmp = icmp ne i32 %and, 0
93 %conv = zext i1 %cmp to i32
97 define <2 x i32> @icmp_ne_and_pow2_shl_pow2_vec(<2 x i32> %0) {
98 ; CHECK-LABEL: @icmp_ne_and_pow2_shl_pow2_vec(
99 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP0:%.*]], splat (i32 2)
100 ; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
101 ; CHECK-NEXT: ret <2 x i32> [[CONV]]
103 %shl = shl <2 x i32> <i32 4, i32 4>, %0
104 %and = and <2 x i32> %shl, <i32 16, i32 16>
105 %cmp = icmp ne <2 x i32> %and, <i32 0, i32 0>
106 %conv = zext <2 x i1> %cmp to <2 x i32>
110 define i32 @icmp_eq_and_pow2_shl_pow2_negative1(i32 %0) {
111 ; CHECK-LABEL: @icmp_eq_and_pow2_shl_pow2_negative1(
112 ; CHECK-NEXT: [[SHL:%.*]] = shl i32 11, [[TMP0:%.*]]
113 ; CHECK-NEXT: [[AND:%.*]] = lshr i32 [[SHL]], 4
114 ; CHECK-NEXT: [[AND_LOBIT:%.*]] = and i32 [[AND]], 1
115 ; CHECK-NEXT: [[CONV:%.*]] = xor i32 [[AND_LOBIT]], 1
116 ; CHECK-NEXT: ret i32 [[CONV]]
118 %shl = shl i32 11, %0
119 %and = and i32 %shl, 16
120 %cmp = icmp eq i32 %and, 0
121 %conv = zext i1 %cmp to i32
125 define i32 @icmp_eq_and_pow2_shl_pow2_negative2(i32 %0) {
126 ; CHECK-LABEL: @icmp_eq_and_pow2_shl_pow2_negative2(
127 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[TMP0:%.*]], 2
128 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
129 ; CHECK-NEXT: ret i32 [[CONV]]
132 %and = and i32 %shl, 14
133 %cmp = icmp eq i32 %and, 0
134 %conv = zext i1 %cmp to i32
138 define i32 @icmp_eq_and_pow2_shl_pow2_negative3(i32 %0) {
139 ; CHECK-LABEL: @icmp_eq_and_pow2_shl_pow2_negative3(
140 ; CHECK-NEXT: ret i32 1
142 %shl = shl i32 32, %0
143 %and = and i32 %shl, 16
144 %cmp = icmp eq i32 %and, 0
145 %conv = zext i1 %cmp to i32
150 define i32 @icmp_eq_and_pow2_minus1_shl1(i32 %0) {
151 ; CHECK-LABEL: @icmp_eq_and_pow2_minus1_shl1(
152 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[TMP0:%.*]], 3
153 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
154 ; CHECK-NEXT: ret i32 [[CONV]]
157 %and = and i32 %shl, 15
158 %cmp = icmp eq i32 %and, 0
159 %conv = zext i1 %cmp to i32
163 define <2 x i32> @icmp_eq_and_pow2_minus1_shl1_vec(<2 x i32> %0) {
164 ; CHECK-LABEL: @icmp_eq_and_pow2_minus1_shl1_vec(
165 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[TMP0:%.*]], splat (i32 3)
166 ; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[CMP]] to <2 x i32>
167 ; CHECK-NEXT: ret <2 x i32> [[CONV]]
169 %shl = shl <2 x i32> <i32 1, i32 1>, %0
170 %and = and <2 x i32> %shl, <i32 15, i32 15>
171 %cmp = icmp eq <2 x i32> %and, <i32 0, i32 0>
172 %conv = zext <2 x i1> %cmp to <2 x i32>
176 define i32 @icmp_ne_and_pow2_minus1_shl1(i32 %0) {
177 ; CHECK-LABEL: @icmp_ne_and_pow2_minus1_shl1(
178 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP0:%.*]], 4
179 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
180 ; CHECK-NEXT: ret i32 [[CONV]]
183 %and = and i32 %shl, 15
184 %cmp = icmp ne i32 %and, 0
185 %conv = zext i1 %cmp to i32
189 define <2 x i32> @icmp_ne_and_pow2_minus1_shl1_vec(<2 x i32> %0) {
190 ; CHECK-LABEL: @icmp_ne_and_pow2_minus1_shl1_vec(
191 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[TMP0:%.*]], splat (i32 4)
192 ; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[CMP]] to <2 x i32>
193 ; CHECK-NEXT: ret <2 x i32> [[CONV]]
195 %shl = shl <2 x i32> <i32 1, i32 1>, %0
196 %and = and <2 x i32> %shl, <i32 15, i32 15>
197 %cmp = icmp ne <2 x i32> %and, <i32 0, i32 0>
198 %conv = zext <2 x i1> %cmp to <2 x i32>
202 define i32 @icmp_eq_and_pow2_minus1_shl_pow2(i32 %0) {
203 ; CHECK-LABEL: @icmp_eq_and_pow2_minus1_shl_pow2(
204 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[TMP0:%.*]], 2
205 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
206 ; CHECK-NEXT: ret i32 [[CONV]]
209 %and = and i32 %shl, 15
210 %cmp = icmp eq i32 %and, 0
211 %conv = zext i1 %cmp to i32
215 define <2 x i32> @icmp_eq_and_pow2_minus1_shl_pow2_vec(<2 x i32> %0) {
216 ; CHECK-LABEL: @icmp_eq_and_pow2_minus1_shl_pow2_vec(
217 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[TMP0:%.*]], splat (i32 1)
218 ; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[CMP]] to <2 x i32>
219 ; CHECK-NEXT: ret <2 x i32> [[CONV]]
221 %shl = shl <2 x i32> <i32 4, i32 4>, %0
222 %and = and <2 x i32> %shl, <i32 15, i32 15>
223 %cmp = icmp eq <2 x i32> %and, <i32 0, i32 0>
224 %conv = zext <2 x i1> %cmp to <2 x i32>
228 define i32 @icmp_ne_and_pow2_minus1_shl_pow2(i32 %0) {
229 ; CHECK-LABEL: @icmp_ne_and_pow2_minus1_shl_pow2(
230 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TMP0:%.*]], 3
231 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
232 ; CHECK-NEXT: ret i32 [[CONV]]
235 %and = and i32 %shl, 15
236 %cmp = icmp ne i32 %and, 0
237 %conv = zext i1 %cmp to i32
241 define <2 x i32> @icmp_ne_and_pow2_minus1_shl_pow2_vec(<2 x i32> %0) {
242 ; CHECK-LABEL: @icmp_ne_and_pow2_minus1_shl_pow2_vec(
243 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[TMP0:%.*]], splat (i32 2)
244 ; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[CMP]] to <2 x i32>
245 ; CHECK-NEXT: ret <2 x i32> [[CONV]]
247 %shl = shl <2 x i32> <i32 4, i32 4>, %0
248 %and = and <2 x i32> %shl, <i32 15, i32 15>
249 %cmp = icmp ne <2 x i32> %and, <i32 0, i32 0>
250 %conv = zext <2 x i1> %cmp to <2 x i32>
254 define i32 @icmp_eq_and_pow2_minus1_shl1_negative1(i32 %0) {
255 ; CHECK-LABEL: @icmp_eq_and_pow2_minus1_shl1_negative1(
256 ; CHECK-NEXT: [[SHL:%.*]] = shl i32 3, [[TMP0:%.*]]
257 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHL]], 15
258 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
259 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
260 ; CHECK-NEXT: ret i32 [[CONV]]
263 %and = and i32 %shl, 15
264 %cmp = icmp eq i32 %and, 0
265 %conv = zext i1 %cmp to i32
269 define i32 @icmp_eq_and_pow2_minus1_shl1_negative2(i32 %0) {
270 ; CHECK-LABEL: @icmp_eq_and_pow2_minus1_shl1_negative2(
271 ; CHECK-NEXT: ret i32 1
273 %shl = shl i32 32, %0
274 %and = and i32 %shl, 15
275 %cmp = icmp eq i32 %and, 0
276 %conv = zext i1 %cmp to i32
281 define i32 @icmp_eq_and1_lshr_pow2(i32 %0) {
282 ; CHECK-LABEL: @icmp_eq_and1_lshr_pow2(
283 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP0:%.*]], 3
284 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP2]] to i32
285 ; CHECK-NEXT: ret i32 [[CONV]]
287 %lshr = lshr i32 8, %0
288 %and = and i32 %lshr, 1
289 %cmp = icmp eq i32 %and, 0
290 %conv = zext i1 %cmp to i32
294 define <2 x i32> @icmp_eq_and1_lshr_pow2_vec(<2 x i32> %0) {
295 ; CHECK-LABEL: @icmp_eq_and1_lshr_pow2_vec(
296 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP0:%.*]], splat (i32 3)
297 ; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
298 ; CHECK-NEXT: ret <2 x i32> [[CONV]]
300 %lshr = lshr <2 x i32> <i32 8, i32 8>, %0
301 %and = and <2 x i32> %lshr, <i32 1, i32 1>
302 %cmp = icmp eq <2 x i32> %and, <i32 0, i32 0>
303 %conv = zext <2 x i1> %cmp to <2 x i32>
307 define i32 @icmp_ne_and1_lshr_pow2(i32 %0) {
308 ; CHECK-LABEL: @icmp_ne_and1_lshr_pow2(
309 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP0:%.*]], 3
310 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP2]] to i32
311 ; CHECK-NEXT: ret i32 [[CONV]]
313 %lshr = lshr i32 8, %0
314 %and = and i32 %lshr, 1
315 %cmp = icmp eq i32 %and, 0
316 %conv = zext i1 %cmp to i32
320 define <2 x i32> @icmp_ne_and1_lshr_pow2_vec(<2 x i32> %0) {
321 ; CHECK-LABEL: @icmp_ne_and1_lshr_pow2_vec(
322 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP0:%.*]], splat (i32 1)
323 ; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
324 ; CHECK-NEXT: ret <2 x i32> [[CONV]]
326 %lshr = lshr <2 x i32> <i32 8, i32 8>, %0
327 %and = and <2 x i32> %lshr, <i32 4, i32 4>
328 %cmp = icmp ne <2 x i32> %and, <i32 0, i32 0>
329 %conv = zext <2 x i1> %cmp to <2 x i32>
333 define i32 @icmp_eq_and_pow2_lshr_pow2(i32 %0) {
334 ; CHECK-LABEL: @icmp_eq_and_pow2_lshr_pow2(
335 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP0:%.*]], 1
336 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP2]] to i32
337 ; CHECK-NEXT: ret i32 [[CONV]]
339 %lshr = lshr i32 8, %0
340 %and = and i32 %lshr, 4
341 %cmp = icmp eq i32 %and, 0
342 %conv = zext i1 %cmp to i32
346 define i32 @icmp_eq_and_pow2_lshr_pow2_case2(i32 %0) {
347 ; CHECK-LABEL: @icmp_eq_and_pow2_lshr_pow2_case2(
348 ; CHECK-NEXT: ret i32 1
350 %lshr = lshr i32 4, %0
351 %and = and i32 %lshr, 8
352 %cmp = icmp eq i32 %and, 0
353 %conv = zext i1 %cmp to i32
357 define <2 x i32> @icmp_eq_and_pow2_lshr_pow2_vec(<2 x i32> %0) {
358 ; CHECK-LABEL: @icmp_eq_and_pow2_lshr_pow2_vec(
359 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP0:%.*]], splat (i32 1)
360 ; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
361 ; CHECK-NEXT: ret <2 x i32> [[CONV]]
363 %lshr = lshr <2 x i32> <i32 8, i32 8>, %0
364 %and = and <2 x i32> %lshr, <i32 4, i32 4>
365 %cmp = icmp eq <2 x i32> %and, <i32 0, i32 0>
366 %conv = zext <2 x i1> %cmp to <2 x i32>
370 define i32 @icmp_ne_and_pow2_lshr_pow2(i32 %0) {
371 ; CHECK-LABEL: @icmp_ne_and_pow2_lshr_pow2(
372 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP0:%.*]], 1
373 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP2]] to i32
374 ; CHECK-NEXT: ret i32 [[CONV]]
376 %lshr = lshr i32 8, %0
377 %and = and i32 %lshr, 4
378 %cmp = icmp eq i32 %and, 0
379 %conv = zext i1 %cmp to i32
383 define i32 @icmp_ne_and_pow2_lshr_pow2_case2(i32 %0) {
384 ; CHECK-LABEL: @icmp_ne_and_pow2_lshr_pow2_case2(
385 ; CHECK-NEXT: ret i32 1
387 %lshr = lshr i32 4, %0
388 %and = and i32 %lshr, 8
389 %cmp = icmp eq i32 %and, 0
390 %conv = zext i1 %cmp to i32
394 define <2 x i32> @icmp_ne_and_pow2_lshr_pow2_vec(<2 x i32> %0) {
395 ; CHECK-LABEL: @icmp_ne_and_pow2_lshr_pow2_vec(
396 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP0:%.*]], splat (i32 1)
397 ; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
398 ; CHECK-NEXT: ret <2 x i32> [[CONV]]
400 %lshr = lshr <2 x i32> <i32 8, i32 8>, %0
401 %and = and <2 x i32> %lshr, <i32 4, i32 4>
402 %cmp = icmp ne <2 x i32> %and, <i32 0, i32 0>
403 %conv = zext <2 x i1> %cmp to <2 x i32>
407 define i32 @icmp_eq_and1_lshr_pow2_minus_one(i32 %0) {
408 ; CHECK-LABEL: @icmp_eq_and1_lshr_pow2_minus_one(
409 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[TMP0:%.*]], 2
410 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
411 ; CHECK-NEXT: ret i32 [[CONV]]
413 %lshr = lshr i32 7, %0
414 %and = and i32 %lshr, 1
415 %cmp = icmp eq i32 %and, 0
416 %conv = zext i1 %cmp to i32
420 define i32 @icmp_eq_and1_lshr_pow2_negative2(i32 %0) {
421 ; CHECK-LABEL: @icmp_eq_and1_lshr_pow2_negative2(
422 ; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 8, [[TMP0:%.*]]
423 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[LSHR]], 3
424 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
425 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
426 ; CHECK-NEXT: ret i32 [[CONV]]
428 %lshr = lshr i32 8, %0
429 %and = and i32 %lshr, 3
430 %cmp = icmp eq i32 %and, 0
431 %conv = zext i1 %cmp to i32
435 define i1 @eq_and_shl_one(i8 %x, i8 %y) {
436 ; CHECK-LABEL: @eq_and_shl_one(
437 ; CHECK-NEXT: [[POW2:%.*]] = shl nuw i8 1, [[Y:%.*]]
438 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[POW2]], [[X:%.*]]
439 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0
440 ; CHECK-NEXT: ret i1 [[CMP]]
443 %and = and i8 %pow2, %x
444 %cmp = icmp eq i8 %and, %pow2
448 define <2 x i1> @ne_and_shl_one_commute(<2 x i8> %x, <2 x i8> %y) {
449 ; CHECK-LABEL: @ne_and_shl_one_commute(
450 ; CHECK-NEXT: [[POW2:%.*]] = shl nuw <2 x i8> <i8 1, i8 poison>, [[Y:%.*]]
451 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[POW2]], [[X:%.*]]
452 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[AND]], zeroinitializer
453 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
455 %pow2 = shl <2 x i8> <i8 1, i8 poison>, %y
456 %and = and <2 x i8> %pow2, %x
457 %cmp = icmp ne <2 x i8> %pow2, %and
461 define i1 @ne_and_lshr_minval(i8 %px, i8 %y) {
462 ; CHECK-LABEL: @ne_and_lshr_minval(
463 ; CHECK-NEXT: [[X:%.*]] = mul i8 [[PX:%.*]], [[PX]]
464 ; CHECK-NEXT: [[POW2:%.*]] = lshr exact i8 -128, [[Y:%.*]]
465 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[POW2]]
466 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0
467 ; CHECK-NEXT: ret i1 [[CMP]]
469 %x = mul i8 %px, %px ; thwart complexity-based canonicalization
470 %pow2 = lshr i8 -128, %y
471 %and = and i8 %x, %pow2
472 %cmp = icmp ne i8 %and, %pow2
476 define i1 @eq_and_lshr_minval_commute(i8 %px, i8 %y) {
477 ; CHECK-LABEL: @eq_and_lshr_minval_commute(
478 ; CHECK-NEXT: [[X:%.*]] = mul i8 [[PX:%.*]], [[PX]]
479 ; CHECK-NEXT: [[POW2:%.*]] = lshr exact i8 -128, [[Y:%.*]]
480 ; CHECK-NEXT: call void @use(i8 [[POW2]])
481 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[POW2]]
482 ; CHECK-NEXT: call void @use(i8 [[AND]])
483 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0
484 ; CHECK-NEXT: ret i1 [[CMP]]
486 %x = mul i8 %px, %px ; thwart complexity-based canonicalization
487 %pow2 = lshr i8 -128, %y
488 call void @use(i8 %pow2)
489 %and = and i8 %x, %pow2
490 call void @use(i8 %and)
491 %cmp = icmp eq i8 %pow2, %and
495 ; Negative test: May be power of two or zero.
496 define i1 @eq_and_shl_two(i8 %x, i8 %y) {
497 ; CHECK-LABEL: @eq_and_shl_two(
498 ; CHECK-NEXT: [[POW2_OR_ZERO:%.*]] = shl i8 2, [[Y:%.*]]
499 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[POW2_OR_ZERO]]
500 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], [[POW2_OR_ZERO]]
501 ; CHECK-NEXT: ret i1 [[CMP]]
503 %pow2_or_zero = shl i8 2, %y
504 %and = and i8 %x, %pow2_or_zero
505 %cmp = icmp eq i8 %and, %pow2_or_zero
509 ; Negative test: Wrong predicate.
510 define i1 @slt_and_shl_one(i8 %x, i8 %y) {
511 ; CHECK-LABEL: @slt_and_shl_one(
512 ; CHECK-NEXT: [[POW2:%.*]] = shl nuw i8 1, [[Y:%.*]]
513 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], [[POW2]]
514 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[AND]], [[POW2]]
515 ; CHECK-NEXT: ret i1 [[CMP]]
518 %and = and i8 %x, %pow2
519 %cmp = icmp slt i8 %and, %pow2
523 define i1 @fold_eq_lhs(i8 %x, i8 %y) {
524 ; CHECK-LABEL: @fold_eq_lhs(
525 ; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 [[Y:%.*]], [[X:%.*]]
526 ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP1]], 0
527 ; CHECK-NEXT: ret i1 [[R]]
530 %and = and i8 %shl, %y
531 %r = icmp eq i8 %and, 0
535 define i1 @fold_eq_lhs_fail_eq_nonzero(i8 %x, i8 %y) {
536 ; CHECK-LABEL: @fold_eq_lhs_fail_eq_nonzero(
537 ; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 -1, [[X:%.*]]
538 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[SHL]], [[Y:%.*]]
539 ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], 1
540 ; CHECK-NEXT: ret i1 [[R]]
543 %and = and i8 %shl, %y
544 %r = icmp eq i8 %and, 1
548 define i1 @fold_eq_lhs_fail_multiuse_shl(i8 %x, i8 %y) {
549 ; CHECK-LABEL: @fold_eq_lhs_fail_multiuse_shl(
550 ; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 -1, [[X:%.*]]
551 ; CHECK-NEXT: call void @use(i8 [[SHL]])
552 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[SHL]], [[Y:%.*]]
553 ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], 0
554 ; CHECK-NEXT: ret i1 [[R]]
557 call void @use(i8 %shl)
558 %and = and i8 %shl, %y
559 %r = icmp eq i8 %and, 0
563 define i1 @fold_ne_rhs(i8 %x, i8 %yy) {
564 ; CHECK-LABEL: @fold_ne_rhs(
565 ; CHECK-NEXT: [[Y:%.*]] = xor i8 [[YY:%.*]], 123
566 ; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 [[Y]], [[X:%.*]]
567 ; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[TMP1]], 0
568 ; CHECK-NEXT: ret i1 [[R]]
572 %and = and i8 %y, %shl
573 %r = icmp ne i8 %and, 0
577 define i1 @fold_ne_rhs_fail_multiuse_and(i8 %x, i8 %yy) {
578 ; CHECK-LABEL: @fold_ne_rhs_fail_multiuse_and(
579 ; CHECK-NEXT: [[Y:%.*]] = xor i8 [[YY:%.*]], 123
580 ; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 -1, [[X:%.*]]
581 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y]], [[SHL]]
582 ; CHECK-NEXT: call void @use(i8 [[AND]])
583 ; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[AND]], 0
584 ; CHECK-NEXT: ret i1 [[R]]
588 %and = and i8 %y, %shl
589 call void @use(i8 %and)
590 %r = icmp ne i8 %and, 0
594 define i1 @fold_ne_rhs_fail_shift_not_1s(i8 %x, i8 %yy) {
595 ; CHECK-LABEL: @fold_ne_rhs_fail_shift_not_1s(
596 ; CHECK-NEXT: [[Y:%.*]] = xor i8 [[YY:%.*]], 122
597 ; CHECK-NEXT: [[SHL:%.*]] = shl i8 -2, [[X:%.*]]
598 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[Y]], [[SHL]]
599 ; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[AND]], 0
600 ; CHECK-NEXT: ret i1 [[R]]
604 %and = and i8 %y, %shl
605 %r = icmp ne i8 %and, 0
609 define i1 @test_shr_and_1_ne_0(i32 %a, i32 %b) {
610 ; CHECK-LABEL: @test_shr_and_1_ne_0(
611 ; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i32 1, [[B:%.*]]
612 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[A:%.*]], [[TMP1]]
613 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP2]], 0
614 ; CHECK-NEXT: ret i1 [[CMP]]
616 %shr = lshr i32 %a, %b
617 %and = and i32 %shr, 1
618 %cmp = icmp ne i32 %and, 0
622 define i1 @test_shr_and_1_ne_0_samesign(i32 %a, i32 %b) {
623 ; CHECK-LABEL: @test_shr_and_1_ne_0_samesign(
624 ; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i32 1, [[B:%.*]]
625 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[A:%.*]], [[TMP1]]
626 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP2]], 0
627 ; CHECK-NEXT: ret i1 [[CMP]]
629 %shr = lshr i32 %a, %b
630 %and = and i32 %shr, 1
631 %cmp = icmp samesign ne i32 %and, 0
635 define i1 @test_const_shr_and_1_ne_0(i32 %b) {
636 ; CHECK-LABEL: @test_const_shr_and_1_ne_0(
637 ; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i32 1, [[B:%.*]]
638 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 42
639 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP2]], 0
640 ; CHECK-NEXT: ret i1 [[CMP]]
642 %shr = lshr i32 42, %b
643 %and = and i32 %shr, 1
644 %cmp = icmp ne i32 %and, 0
648 define i1 @test_not_const_shr_and_1_ne_0(i32 %b) {
649 ; CHECK-LABEL: @test_not_const_shr_and_1_ne_0(
650 ; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i32 1, [[B:%.*]]
651 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 42
652 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP2]], 0
653 ; CHECK-NEXT: ret i1 [[CMP]]
655 %shr = lshr i32 42, %b
656 %and = and i32 %shr, 1
657 %cmp = icmp eq i32 %and, 0
661 define i1 @test_const_shr_exact_and_1_ne_0(i32 %b) {
662 ; CHECK-LABEL: @test_const_shr_exact_and_1_ne_0(
663 ; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i32 1, [[B:%.*]]
664 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 42
665 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP2]], 0
666 ; CHECK-NEXT: ret i1 [[CMP]]
668 %shr = lshr exact i32 42, %b
669 %and = and i32 %shr, 1
670 %cmp = icmp ne i32 %and, 0
674 define i1 @test_const_shr_and_2_ne_0_negative(i32 %b) {
675 ; CHECK-LABEL: @test_const_shr_and_2_ne_0_negative(
676 ; CHECK-NEXT: [[SHR:%.*]] = lshr i32 42, [[B:%.*]]
677 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHR]], 2
678 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
679 ; CHECK-NEXT: ret i1 [[CMP]]
681 %shr = lshr i32 42, %b
682 %and = and i32 %shr, 2
683 %cmp = icmp eq i32 %and, 0
687 define <8 x i1> @test_const_shr_and_1_ne_0_v8i8_splat_negative(<8 x i8> %b) {
688 ; CHECK-LABEL: @test_const_shr_and_1_ne_0_v8i8_splat_negative(
689 ; CHECK-NEXT: [[SHR:%.*]] = lshr <8 x i8> splat (i8 42), [[B:%.*]]
690 ; CHECK-NEXT: [[CMP:%.*]] = trunc <8 x i8> [[SHR]] to <8 x i1>
691 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
693 %shr = lshr <8 x i8> <i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42>, %b
694 %and = and <8 x i8> %shr, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
695 %cmp = icmp ne <8 x i8> %and, zeroinitializer
699 define <8 x i1> @test_const_shr_and_1_ne_0_v8i8_nonsplat_negative(<8 x i8> %b) {
700 ; CHECK-LABEL: @test_const_shr_and_1_ne_0_v8i8_nonsplat_negative(
701 ; CHECK-NEXT: [[SHR:%.*]] = lshr <8 x i8> <i8 42, i8 43, i8 44, i8 45, i8 46, i8 47, i8 48, i8 49>, [[B:%.*]]
702 ; CHECK-NEXT: [[CMP:%.*]] = trunc <8 x i8> [[SHR]] to <8 x i1>
703 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
705 %shr = lshr <8 x i8> <i8 42, i8 43, i8 44, i8 45, i8 46, i8 47, i8 48, i8 49>, %b
706 %and = and <8 x i8> %shr, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
707 %cmp = icmp ne <8 x i8> %and, zeroinitializer
711 define i1 @test_const_shr_and_1_ne_0_i1_negative(i1 %b) {
712 ; CHECK-LABEL: @test_const_shr_and_1_ne_0_i1_negative(
713 ; CHECK-NEXT: ret i1 true
716 %and = and i1 %shr, 1
717 %cmp = icmp ne i1 %and, 0
721 define i1 @test_const_shr_and_1_ne_0_multi_use_lshr_negative(i32 %b) {
722 ; CHECK-LABEL: @test_const_shr_and_1_ne_0_multi_use_lshr_negative(
723 ; CHECK-NEXT: [[SHR:%.*]] = lshr i32 42, [[B:%.*]]
724 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHR]], 1
725 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[AND]], 0
726 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[B]], [[SHR]]
727 ; CHECK-NEXT: [[RET:%.*]] = and i1 [[CMP1]], [[CMP2]]
728 ; CHECK-NEXT: ret i1 [[RET]]
730 %shr = lshr i32 42, %b
731 %and = and i32 %shr, 1
732 %cmp1 = icmp ne i32 %and, 0
733 %cmp2 = icmp eq i32 %b, %shr
734 %ret = and i1 %cmp1, %cmp2
738 define i1 @test_const_shr_and_1_ne_0_multi_use_and_negative(i32 %b) {
739 ; CHECK-LABEL: @test_const_shr_and_1_ne_0_multi_use_and_negative(
740 ; CHECK-NEXT: [[SHR:%.*]] = lshr i32 42, [[B:%.*]]
741 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHR]], 1
742 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[AND]], 0
743 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[B]], [[AND]]
744 ; CHECK-NEXT: [[RET:%.*]] = and i1 [[CMP1]], [[CMP2]]
745 ; CHECK-NEXT: ret i1 [[RET]]
747 %shr = lshr i32 42, %b
748 %and = and i32 %shr, 1
749 %cmp1 = icmp ne i32 %and, 0
750 %cmp2 = icmp eq i32 %b, %and
751 %ret = and i1 %cmp1, %cmp2