[VectorCombine] foldInsExtVectorToShuffle - canonicalize new shuffle(undef,x) ->...
[llvm-project.git] / llvm / test / Transforms / InstCombine / icmp-and-shift.ll
blob78f1bc7d7379d47ed4bdb75b78dbf7621d42d9a4
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 declare void @use(i8)
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]]
12   %shl = shl i32 1, %0
13   %and = and i32 %shl, 16
14   %cmp = icmp eq i32 %and, 0
15   %conv = zext i1 %cmp to i32
16   ret i32 %conv
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>
29   ret <2 x i32> %conv
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]]
38   %shl = shl i32 1, %0
39   %and = and i32 %shl, 16
40   %cmp = icmp ne i32 %and, 0
41   %conv = zext i1 %cmp to i32
42   ret i32 %conv
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>
55   ret <2 x i32> %conv
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]]
64   %shl = shl i32 2, %0
65   %and = and i32 %shl, 16
66   %cmp = icmp eq i32 %and, 0
67   %conv = zext i1 %cmp to i32
68   ret i32 %conv
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>
81   ret <2 x i32> %conv
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]]
90   %shl = shl i32 2, %0
91   %and = and i32 %shl, 16
92   %cmp = icmp ne i32 %and, 0
93   %conv = zext i1 %cmp to i32
94   ret i32 %conv
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>
107   ret <2 x i32> %conv
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
122   ret i32 %conv
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]]
131   %shl = shl i32 2, %0
132   %and = and i32 %shl, 14
133   %cmp = icmp eq i32 %and, 0
134   %conv = zext i1 %cmp to i32
135   ret i32 %conv
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
146   ret i32 %conv
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]]
156   %shl = shl i32 1, %0
157   %and = and i32 %shl, 15
158   %cmp = icmp eq i32 %and, 0
159   %conv = zext i1 %cmp to i32
160   ret i32 %conv
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>
173   ret <2 x i32> %conv
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]]
182   %shl = shl i32 1, %0
183   %and = and i32 %shl, 15
184   %cmp = icmp ne i32 %and, 0
185   %conv = zext i1 %cmp to i32
186   ret i32 %conv
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>
199   ret <2 x i32> %conv
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]]
208   %shl = shl i32 2, %0
209   %and = and i32 %shl, 15
210   %cmp = icmp eq i32 %and, 0
211   %conv = zext i1 %cmp to i32
212   ret i32 %conv
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>
225   ret <2 x i32> %conv
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]]
234   %shl = shl i32 2, %0
235   %and = and i32 %shl, 15
236   %cmp = icmp ne i32 %and, 0
237   %conv = zext i1 %cmp to i32
238   ret i32 %conv
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>
251   ret <2 x i32> %conv
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]]
262   %shl = shl i32 3, %0
263   %and = and i32 %shl, 15
264   %cmp = icmp eq i32 %and, 0
265   %conv = zext i1 %cmp to i32
266   ret i32 %conv
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
277   ret i32 %conv
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
291   ret i32 %conv
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>
304   ret <2 x i32> %conv
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
317   ret i32 %conv
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>
330   ret <2 x i32> %conv
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
343   ret i32 %conv
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
354   ret i32 %conv
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>
367   ret <2 x i32> %conv
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
380   ret i32 %conv
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
391   ret i32 %conv
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>
404   ret <2 x i32> %conv
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
417   ret i32 %conv
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
432   ret i32 %conv
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]]
442   %pow2 = shl i8 1, %y
443   %and = and i8 %pow2, %x
444   %cmp = icmp eq i8 %and, %pow2
445   ret i1 %cmp
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
458   ret <2 x i1> %cmp
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
473   ret i1 %cmp
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
492   ret i1 %cmp
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
506   ret i1 %cmp
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]]
517   %pow2 = shl i8 1, %y
518   %and = and i8 %x, %pow2
519   %cmp = icmp slt i8 %and, %pow2
520   ret i1 %cmp
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]]
529   %shl = shl i8 -1, %x
530   %and = and i8 %shl, %y
531   %r = icmp eq i8 %and, 0
532   ret i1 %r
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]]
542   %shl = shl i8 -1, %x
543   %and = and i8 %shl, %y
544   %r = icmp eq i8 %and, 1
545   ret i1 %r
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]]
556   %shl = shl i8 -1, %x
557   call void @use(i8 %shl)
558   %and = and i8 %shl, %y
559   %r = icmp eq i8 %and, 0
560   ret i1 %r
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]]
570   %y = xor i8 %yy, 123
571   %shl = shl i8 -1, %x
572   %and = and i8 %y, %shl
573   %r = icmp ne i8 %and, 0
574   ret i1 %r
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]]
586   %y = xor i8 %yy, 123
587   %shl = shl i8 -1, %x
588   %and = and i8 %y, %shl
589   call void @use(i8 %and)
590   %r = icmp ne i8 %and, 0
591   ret i1 %r
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]]
602   %y = xor i8 %yy, 123
603   %shl = shl i8 -2, %x
604   %and = and i8 %y, %shl
605   %r = icmp ne i8 %and, 0
606   ret i1 %r
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
619   ret i1 %cmp
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
632   ret i1 %cmp
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
645   ret i1 %cmp
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
658   ret i1 %cmp
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
671   ret i1 %cmp
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
684   ret i1 %cmp
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
696   ret <8 x i1> %cmp
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
708   ret <8 x i1> %cmp
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
715   %shr = lshr i1 1, %b
716   %and = and i1 %shr, 1
717   %cmp = icmp ne i1 %and, 0
718   ret i1 %cmp
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
735   ret i1 %ret
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
752   ret i1 %ret