Follow up to d0858bffa11, add missing REQUIRES x86
[llvm-project.git] / llvm / test / Transforms / InstSimplify / icmp-constant.ll
blob04261f6f40b7c333b5d812d7940feff6c1bb7c78
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
4 ; Fold icmp with a constant operand.
6 define i1 @tautological_ule(i8 %x) {
7 ; CHECK-LABEL: @tautological_ule(
8 ; CHECK-NEXT:    ret i1 true
10   %cmp = icmp ule i8 %x, 255
11   ret i1 %cmp
14 define <2 x i1> @tautological_ule_vec(<2 x i8> %x) {
15 ; CHECK-LABEL: @tautological_ule_vec(
16 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
18   %cmp = icmp ule <2 x i8> %x, <i8 255, i8 255>
19   ret <2 x i1> %cmp
22 define <2 x i1> @tautological_ule_vec_partial_undef(<2 x i8> %x) {
23 ; CHECK-LABEL: @tautological_ule_vec_partial_undef(
24 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
26   %cmp = icmp ule <2 x i8> %x, <i8 255, i8 undef>
27   ret <2 x i1> %cmp
30 define i1 @tautological_ugt(i8 %x) {
31 ; CHECK-LABEL: @tautological_ugt(
32 ; CHECK-NEXT:    ret i1 false
34   %cmp = icmp ugt i8 %x, 255
35   ret i1 %cmp
38 define <2 x i1> @tautological_ugt_vec(<2 x i8> %x) {
39 ; CHECK-LABEL: @tautological_ugt_vec(
40 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
42   %cmp = icmp ugt <2 x i8> %x, <i8 255, i8 255>
43   ret <2 x i1> %cmp
46 define <2 x i1> @tautological_ugt_vec_partial_undef(<2 x i8> %x) {
47 ; CHECK-LABEL: @tautological_ugt_vec_partial_undef(
48 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
50   %cmp = icmp ugt <2 x i8> %x, <i8 undef, i8 255>
51   ret <2 x i1> %cmp
54 ; 'urem x, C2' produces [0, C2)
55 define i1 @urem3(i32 %X) {
56 ; CHECK-LABEL: @urem3(
57 ; CHECK-NEXT:    ret i1 true
59   %A = urem i32 %X, 10
60   %B = icmp ult i32 %A, 15
61   ret i1 %B
64 define <2 x i1> @urem3_vec(<2 x i32> %X) {
65 ; CHECK-LABEL: @urem3_vec(
66 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
68   %A = urem <2 x i32> %X, <i32 10, i32 10>
69   %B = icmp ult <2 x i32> %A, <i32 15, i32 15>
70   ret <2 x i1> %B
73 define <2 x i1> @urem3_vec_partial_undef(<2 x i32> %X) {
74 ; CHECK-LABEL: @urem3_vec_partial_undef(
75 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
77   %A = urem <2 x i32> %X, <i32 10, i32 10>
78   %B = icmp ult <2 x i32> %A, <i32 undef, i32 15>
79   ret <2 x i1> %B
82 ;'srem x, C2' produces (-|C2|, |C2|)
83 define i1 @srem1(i32 %X) {
84 ; CHECK-LABEL: @srem1(
85 ; CHECK-NEXT:    ret i1 false
87   %A = srem i32 %X, -5
88   %B = icmp sgt i32 %A, 5
89   ret i1 %B
92 define <2 x i1> @srem1_vec(<2 x i32> %X) {
93 ; CHECK-LABEL: @srem1_vec(
94 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
96   %A = srem <2 x i32> %X, <i32 -5, i32 -5>
97   %B = icmp sgt <2 x i32> %A, <i32 5, i32 5>
98   ret <2 x i1> %B
101 define <2 x i1> @srem1_vec_partial_undef(<2 x i32> %X) {
102 ; CHECK-LABEL: @srem1_vec_partial_undef(
103 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
105   %A = srem <2 x i32> %X, <i32 -5, i32 -5>
106   %B = icmp sgt <2 x i32> %A, <i32 5, i32 undef>
107   ret <2 x i1> %B
110 ;'udiv C2, x' produces [0, C2]
111 define i1 @udiv5(i32 %X) {
112 ; CHECK-LABEL: @udiv5(
113 ; CHECK-NEXT:    ret i1 false
115   %A = udiv i32 123, %X
116   %C = icmp ugt i32 %A, 124
117   ret i1 %C
120 define <2 x i1> @udiv5_vec(<2 x i32> %X) {
121 ; CHECK-LABEL: @udiv5_vec(
122 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
124   %A = udiv <2 x i32> <i32 123, i32 123>, %X
125   %C = icmp ugt <2 x i32> %A, <i32 124, i32 124>
126   ret <2 x i1> %C
129 ; 'udiv x, C2' produces [0, UINT_MAX / C2]
130 define i1 @udiv1(i32 %X) {
131 ; CHECK-LABEL: @udiv1(
132 ; CHECK-NEXT:    ret i1 true
134   %A = udiv i32 %X, 1000000
135   %B = icmp ult i32 %A, 5000
136   ret i1 %B
139 define <2 x i1> @udiv1_vec(<2 x i32> %X) {
140 ; CHECK-LABEL: @udiv1_vec(
141 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
143   %A = udiv <2 x i32> %X, <i32 1000000, i32 1000000>
144   %B = icmp ult <2 x i32> %A, <i32 5000, i32 5000>
145   ret <2 x i1> %B
148 ; 'sdiv C2, x' produces [-|C2|, |C2|]
149 define i1 @compare_dividend(i32 %a) {
150 ; CHECK-LABEL: @compare_dividend(
151 ; CHECK-NEXT:    ret i1 false
153   %div = sdiv i32 2, %a
154   %cmp = icmp eq i32 %div, 3
155   ret i1 %cmp
158 define <2 x i1> @compare_dividend_vec(<2 x i32> %a) {
159 ; CHECK-LABEL: @compare_dividend_vec(
160 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
162   %div = sdiv <2 x i32> <i32 2, i32 2>, %a
163   %cmp = icmp eq <2 x i32> %div, <i32 3, i32 3>
164   ret <2 x i1> %cmp
167 ; 'sdiv x, C2' produces [INT_MIN / C2, INT_MAX / C2]
168 ;    where C2 != -1 and C2 != 0 and C2 != 1
169 define i1 @sdiv1(i32 %X) {
170 ; CHECK-LABEL: @sdiv1(
171 ; CHECK-NEXT:    ret i1 true
173   %A = sdiv i32 %X, 1000000
174   %B = icmp slt i32 %A, 3000
175   ret i1 %B
178 define <2 x i1> @sdiv1_vec(<2 x i32> %X) {
179 ; CHECK-LABEL: @sdiv1_vec(
180 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
182   %A = sdiv <2 x i32> %X, <i32 1000000, i32 1000000>
183   %B = icmp slt <2 x i32> %A, <i32 3000, i32 3000>
184   ret <2 x i1> %B
187 ; 'shl nuw C2, x' produces [C2, C2 << CLZ(C2)]
188 define i1 @shl5(i32 %X) {
189 ; CHECK-LABEL: @shl5(
190 ; CHECK-NEXT:    ret i1 true
192   %sub = shl nuw i32 4, %X
193   %cmp = icmp ugt i32 %sub, 3
194   ret i1 %cmp
197 define <2 x i1> @shl5_vec(<2 x i32> %X) {
198 ; CHECK-LABEL: @shl5_vec(
199 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
201   %sub = shl nuw <2 x i32> <i32 4, i32 4>, %X
202   %cmp = icmp ugt <2 x i32> %sub, <i32 3, i32 3>
203   ret <2 x i1> %cmp
206 define <2 x i1> @shl5_vec_partial_undef(<2 x i32> %X) {
207 ; CHECK-LABEL: @shl5_vec_partial_undef(
208 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
210   %sub = shl nuw <2 x i32> <i32 4, i32 4>, %X
211   %cmp = icmp ugt <2 x i32> %sub, <i32 undef, i32 3>
212   ret <2 x i1> %cmp
215 ; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2]
216 define i1 @shl2(i32 %X) {
217 ; CHECK-LABEL: @shl2(
218 ; CHECK-NEXT:    ret i1 false
220   %sub = shl nsw i32 -1, %X
221   %cmp = icmp eq i32 %sub, 31
222   ret i1 %cmp
225 define <2 x i1> @shl2_vec(<2 x i32> %X) {
226 ; CHECK-LABEL: @shl2_vec(
227 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
229   %sub = shl nsw <2 x i32> <i32 -1, i32 -1>, %X
230   %cmp = icmp eq <2 x i32> %sub, <i32 31, i32 31>
231   ret <2 x i1> %cmp
234 ; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2]
235 define i1 @shl4(i32 %X) {
236 ; CHECK-LABEL: @shl4(
237 ; CHECK-NEXT:    ret i1 true
239   %sub = shl nsw i32 -1, %X
240   %cmp = icmp sle i32 %sub, -1
241   ret i1 %cmp
244 define <2 x i1> @shl4_vec(<2 x i32> %X) {
245 ; CHECK-LABEL: @shl4_vec(
246 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
248   %sub = shl nsw <2 x i32> <i32 -1, i32 -1>, %X
249   %cmp = icmp sle <2 x i32> %sub, <i32 -1, i32 -1>
250   ret <2 x i1> %cmp
253 ; 'shl nsw C2, x' produces [C2, C2 << CLZ(C2)-1]
254 define i1 @icmp_shl_nsw_1(i64 %a) {
255 ; CHECK-LABEL: @icmp_shl_nsw_1(
256 ; CHECK-NEXT:    ret i1 true
258   %shl = shl nsw i64 1, %a
259   %cmp = icmp sge i64 %shl, 0
260   ret i1 %cmp
263 define <2 x i1> @icmp_shl_nsw_1_vec(<2 x i64> %a) {
264 ; CHECK-LABEL: @icmp_shl_nsw_1_vec(
265 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
267   %shl = shl nsw <2 x i64> <i64 1, i64 1>, %a
268   %cmp = icmp sge <2 x i64> %shl, zeroinitializer
269   ret <2 x i1> %cmp
272 ; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2]
273 define i1 @icmp_shl_nsw_neg1(i64 %a) {
274 ; CHECK-LABEL: @icmp_shl_nsw_neg1(
275 ; CHECK-NEXT:    ret i1 false
277   %shl = shl nsw i64 -1, %a
278   %cmp = icmp sge i64 %shl, 3
279   ret i1 %cmp
282 define <2 x i1> @icmp_shl_nsw_neg1_vec(<2 x i64> %a) {
283 ; CHECK-LABEL: @icmp_shl_nsw_neg1_vec(
284 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
286   %shl = shl nsw <2 x i64> <i64 -1, i64 -1>, %a
287   %cmp = icmp sge <2 x i64> %shl, <i64 3, i64 3>
288   ret <2 x i1> %cmp
291 ; 'lshr x, C2' produces [0, UINT_MAX >> C2]
292 define i1 @lshr2(i32 %x) {
293 ; CHECK-LABEL: @lshr2(
294 ; CHECK-NEXT:    ret i1 false
296   %s = lshr i32 %x, 30
297   %c = icmp ugt i32 %s, 8
298   ret i1 %c
301 define <2 x i1> @lshr2_vec(<2 x i32> %x) {
302 ; CHECK-LABEL: @lshr2_vec(
303 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
305   %s = lshr <2 x i32> %x, <i32 30, i32 30>
306   %c = icmp ugt <2 x i32> %s, <i32 8, i32 8>
307   ret <2 x i1> %c
310 ; 'lshr C2, x' produces [C2 >> (Width-1), C2]
311 define i1 @exact_lshr_ugt_false(i32 %a) {
312 ; CHECK-LABEL: @exact_lshr_ugt_false(
313 ; CHECK-NEXT:    ret i1 false
315   %shr = lshr exact i32 30, %a
316   %cmp = icmp ult i32 %shr, 15
317   ret i1 %cmp
320 define <2 x i1> @exact_lshr_ugt_false_vec(<2 x i32> %a) {
321 ; CHECK-LABEL: @exact_lshr_ugt_false_vec(
322 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
324   %shr = lshr exact <2 x i32> <i32 30, i32 30>, %a
325   %cmp = icmp ult <2 x i32> %shr, <i32 15, i32 15>
326   ret <2 x i1> %cmp
329 ; 'lshr C2, x' produces [C2 >> (Width-1), C2]
330 define i1 @lshr_sgt_false(i32 %a) {
331 ; CHECK-LABEL: @lshr_sgt_false(
332 ; CHECK-NEXT:    ret i1 false
334   %shr = lshr i32 1, %a
335   %cmp = icmp sgt i32 %shr, 1
336   ret i1 %cmp
339 define <2 x i1> @lshr_sgt_false_vec(<2 x i32> %a) {
340 ; CHECK-LABEL: @lshr_sgt_false_vec(
341 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
343   %shr = lshr <2 x i32> <i32 1, i32 1>, %a
344   %cmp = icmp sgt <2 x i32> %shr, <i32 1, i32 1>
345   ret <2 x i1> %cmp
348 ; 'ashr x, C2' produces [INT_MIN >> C2, INT_MAX >> C2]
349 define i1 @ashr2(i32 %x) {
350 ; CHECK-LABEL: @ashr2(
351 ; CHECK-NEXT:    ret i1 false
353   %s = ashr i32 %x, 30
354   %c = icmp slt i32 %s, -5
355   ret i1 %c
358 define <2 x i1> @ashr2_vec(<2 x i32> %x) {
359 ; CHECK-LABEL: @ashr2_vec(
360 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
362   %s = ashr <2 x i32> %x, <i32 30, i32 30>
363   %c = icmp slt <2 x i32> %s, <i32 -5, i32 -5>
364   ret <2 x i1> %c
367 ; 'ashr C2, x' produces [C2, C2 >> (Width-1)]
368 define i1 @ashr_sgt_false(i32 %a) {
369 ; CHECK-LABEL: @ashr_sgt_false(
370 ; CHECK-NEXT:    ret i1 false
372   %shr = ashr i32 -30, %a
373   %cmp = icmp sgt i32 %shr, -1
374   ret i1 %cmp
377 define <2 x i1> @ashr_sgt_false_vec(<2 x i32> %a) {
378 ; CHECK-LABEL: @ashr_sgt_false_vec(
379 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
381   %shr = ashr <2 x i32> <i32 -30, i32 -30>, %a
382   %cmp = icmp sgt <2 x i32> %shr, <i32 -1, i32 -1>
383   ret <2 x i1> %cmp
386 ; 'ashr C2, x' produces [C2, C2 >> (Width-1)]
387 define i1 @exact_ashr_sgt_false(i32 %a) {
388 ; CHECK-LABEL: @exact_ashr_sgt_false(
389 ; CHECK-NEXT:    ret i1 false
391   %shr = ashr exact i32 -30, %a
392   %cmp = icmp sgt i32 %shr, -15
393   ret i1 %cmp
396 define <2 x i1> @exact_ashr_sgt_false_vec(<2 x i32> %a) {
397 ; CHECK-LABEL: @exact_ashr_sgt_false_vec(
398 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
400   %shr = ashr exact <2 x i32> <i32 -30, i32 -30>, %a
401   %cmp = icmp sgt <2 x i32> %shr, <i32 -15, i32 -15>
402   ret <2 x i1> %cmp
405 ; 'or x, C2' produces [C2, UINT_MAX]
406 define i1 @or1(i32 %X) {
407 ; CHECK-LABEL: @or1(
408 ; CHECK-NEXT:    ret i1 false
410   %A = or i32 %X, 62
411   %B = icmp ult i32 %A, 50
412   ret i1 %B
415 define <2 x i1> @or1_vec(<2 x i32> %X) {
416 ; CHECK-LABEL: @or1_vec(
417 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
419   %A = or <2 x i32> %X, <i32 62, i32 62>
420   %B = icmp ult <2 x i32> %A, <i32 50, i32 50>
421   ret <2 x i1> %B
424 define <2 x i1> @or1_vec_partial_undef(<2 x i32> %X) {
425 ; CHECK-LABEL: @or1_vec_partial_undef(
426 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
428   %A = or <2 x i32> %X, <i32 62, i32 62>
429   %B = icmp ult <2 x i32> %A, <i32 undef, i32 50>
430   ret <2 x i1> %B
433 ; Single bit OR.
434 define i1 @or2_true(i8 %x) {
435 ; CHECK-LABEL: @or2_true(
436 ; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], 64
437 ; CHECK-NEXT:    [[Z:%.*]] = icmp sge i8 [[Y]], -64
438 ; CHECK-NEXT:    ret i1 [[Z]]
440   %y = or i8 %x, 64
441   %z = icmp sge i8 %y, -64
442   ret i1 %z
445 define i1 @or2_unknown(i8 %x) {
446 ; CHECK-LABEL: @or2_unknown(
447 ; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], 64
448 ; CHECK-NEXT:    [[Z:%.*]] = icmp sgt i8 [[Y]], -64
449 ; CHECK-NEXT:    ret i1 [[Z]]
451   %y = or i8 %x, 64
452   %z = icmp sgt i8 %y, -64
453   ret i1 %z
456 ; Multi bit OR.
457 ; 78 = 0b01001110; -50 = 0b11001110
458 define i1 @or3_true(i8 %x) {
459 ; CHECK-LABEL: @or3_true(
460 ; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], 78
461 ; CHECK-NEXT:    [[Z:%.*]] = icmp sge i8 [[Y]], -50
462 ; CHECK-NEXT:    ret i1 [[Z]]
464   %y = or i8 %x, 78
465   %z = icmp sge i8 %y, -50
466   ret i1 %z
469 define i1 @or3_unknown(i8 %x) {
470 ; CHECK-LABEL: @or3_unknown(
471 ; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], 78
472 ; CHECK-NEXT:    [[Z:%.*]] = icmp sgt i8 [[Y]], -50
473 ; CHECK-NEXT:    ret i1 [[Z]]
475   %y = or i8 %x, 78
476   %z = icmp sgt i8 %y, -50
477   ret i1 %z
480 ; OR with sign bit.
481 define i1 @or4_true(i8 %x) {
482 ; CHECK-LABEL: @or4_true(
483 ; CHECK-NEXT:    ret i1 true
485   %y = or i8 %x, -64
486   %z = icmp sge i8 %y, -64
487   ret i1 %z
490 define i1 @or4_unknown(i8 %x) {
491 ; CHECK-LABEL: @or4_unknown(
492 ; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], -64
493 ; CHECK-NEXT:    [[Z:%.*]] = icmp sgt i8 [[Y]], -64
494 ; CHECK-NEXT:    ret i1 [[Z]]
496   %y = or i8 %x, -64
497   %z = icmp sgt i8 %y, -64
498   ret i1 %z
501 ; If sign bit is set, signed & unsigned ranges are the same.
502 define i1 @or5_true(i8 %x) {
503 ; CHECK-LABEL: @or5_true(
504 ; CHECK-NEXT:    ret i1 true
506   %y = or i8 %x, -64
507   %z = icmp uge i8 %y, -64
508   ret i1 %z
511 define i1 @or5_unknown(i8 %x) {
512 ; CHECK-LABEL: @or5_unknown(
513 ; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], -64
514 ; CHECK-NEXT:    [[Z:%.*]] = icmp ugt i8 [[Y]], -64
515 ; CHECK-NEXT:    ret i1 [[Z]]
517   %y = or i8 %x, -64
518   %z = icmp ugt i8 %y, -64
519   ret i1 %z
522 ; 'and x, C2' produces [0, C2]
523 define i1 @and1(i32 %X) {
524 ; CHECK-LABEL: @and1(
525 ; CHECK-NEXT:    ret i1 false
527   %A = and i32 %X, 62
528   %B = icmp ugt i32 %A, 70
529   ret i1 %B
532 define <2 x i1> @and1_vec(<2 x i32> %X) {
533 ; CHECK-LABEL: @and1_vec(
534 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
536   %A = and <2 x i32> %X, <i32 62, i32 62>
537   %B = icmp ugt <2 x i32> %A, <i32 70, i32 70>
538   ret <2 x i1> %B
541 ; If the sign bit is not set, signed and unsigned ranges are the same.
542 define i1 @and2(i32 %X) {
543 ; CHECK-LABEL: @and2(
544 ; CHECK-NEXT:    ret i1 false
546   %A = and i32 %X, 62
547   %B = icmp sgt i32 %A, 70
548   ret i1 %B
551 ; -75 = 0b10110101, 53 = 0b00110101
552 define i1 @and3_true1(i8 %x) {
553 ; CHECK-LABEL: @and3_true1(
554 ; CHECK-NEXT:    [[Y:%.*]] = and i8 [[X:%.*]], -75
555 ; CHECK-NEXT:    [[Z:%.*]] = icmp sge i8 [[Y]], -75
556 ; CHECK-NEXT:    ret i1 [[Z]]
558   %y = and i8 %x, -75
559   %z = icmp sge i8 %y, -75
560   ret i1 %z
563 define i1 @and3_unknown1(i8 %x) {
564 ; CHECK-LABEL: @and3_unknown1(
565 ; CHECK-NEXT:    [[Y:%.*]] = and i8 [[X:%.*]], -75
566 ; CHECK-NEXT:    [[Z:%.*]] = icmp sgt i8 [[Y]], -75
567 ; CHECK-NEXT:    ret i1 [[Z]]
569   %y = and i8 %x, -75
570   %z = icmp sgt i8 %y, -75
571   ret i1 %z
574 define i1 @and3_true2(i8 %x) {
575 ; CHECK-LABEL: @and3_true2(
576 ; CHECK-NEXT:    [[Y:%.*]] = and i8 [[X:%.*]], -75
577 ; CHECK-NEXT:    [[Z:%.*]] = icmp sle i8 [[Y]], 53
578 ; CHECK-NEXT:    ret i1 [[Z]]
580   %y = and i8 %x, -75
581   %z = icmp sle i8 %y, 53
582   ret i1 %z
585 define i1 @and3_unknown2(i8 %x) {
586 ; CHECK-LABEL: @and3_unknown2(
587 ; CHECK-NEXT:    [[Y:%.*]] = and i8 [[X:%.*]], -75
588 ; CHECK-NEXT:    [[Z:%.*]] = icmp slt i8 [[Y]], 53
589 ; CHECK-NEXT:    ret i1 [[Z]]
591   %y = and i8 %x, -75
592   %z = icmp slt i8 %y, 53
593   ret i1 %z
596 ; 'add nuw x, C2' produces [C2, UINT_MAX]
597 define i1 @tautological9(i32 %x) {
598 ; CHECK-LABEL: @tautological9(
599 ; CHECK-NEXT:    ret i1 true
601   %add = add nuw i32 %x, 13
602   %cmp = icmp ne i32 %add, 12
603   ret i1 %cmp
606 define <2 x i1> @tautological9_vec(<2 x i32> %x) {
607 ; CHECK-LABEL: @tautological9_vec(
608 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
610   %add = add nuw <2 x i32> %x, <i32 13, i32 13>
611   %cmp = icmp ne <2 x i32> %add, <i32 12, i32 12>
612   ret <2 x i1> %cmp
615 ; The upper bound of the 'add' is 0.
617 define i1 @add_nsw_neg_const1(i32 %x) {
618 ; CHECK-LABEL: @add_nsw_neg_const1(
619 ; CHECK-NEXT:    ret i1 false
621   %add = add nsw i32 %x, -2147483647
622   %cmp = icmp sgt i32 %add, 0
623   ret i1 %cmp
626 define i1 @add_nsw_sgt(i8 %x) {
627 ; CHECK-LABEL: @add_nsw_sgt(
628 ; CHECK-NEXT:    ret i1 true
630   %add = add nsw i8 %x, 5
631   %cmp = icmp sgt i8 %add, -124
632   ret i1 %cmp
635 ; nuw should not inhibit the fold.
637 define i1 @add_nsw_nuw_sgt(i8 %x) {
638 ; CHECK-LABEL: @add_nsw_nuw_sgt(
639 ; CHECK-NEXT:    ret i1 true
641   %add = add nsw nuw i8 %x, 5
642   %cmp = icmp sgt i8 %add, -124
643   ret i1 %cmp
646 ; negative test - minimum x is -128, so add could be -124.
648 define i1 @add_nsw_sgt_limit(i8 %x) {
649 ; CHECK-LABEL: @add_nsw_sgt_limit(
650 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[X:%.*]], 4
651 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[ADD]], -124
652 ; CHECK-NEXT:    ret i1 [[CMP]]
654   %add = add nsw i8 %x, 4
655   %cmp = icmp sgt i8 %add, -124
656   ret i1 %cmp
659 define i1 @add_nsw_slt(i8 %x) {
660 ; CHECK-LABEL: @add_nsw_slt(
661 ; CHECK-NEXT:    ret i1 false
663   %add = add nsw i8 %x, 5
664   %cmp = icmp slt i8 %add, -123
665   ret i1 %cmp
668 ; nuw should not inhibit the fold.
670 define i1 @add_nsw_nuw_slt(i8 %x) {
671 ; CHECK-LABEL: @add_nsw_nuw_slt(
672 ; CHECK-NEXT:    ret i1 false
674   %add = add nsw nuw i8 %x, 5
675   %cmp = icmp slt i8 %add, -123
676   ret i1 %cmp
679 ; negative test - minimum x is -128, so add could be -123.
681 define i1 @add_nsw_slt_limit(i8 %x) {
682 ; CHECK-LABEL: @add_nsw_slt_limit(
683 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[X:%.*]], 5
684 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[ADD]], -122
685 ; CHECK-NEXT:    ret i1 [[CMP]]
687   %add = add nsw i8 %x, 5
688   %cmp = icmp slt i8 %add, -122
689   ret i1 %cmp
692 ; InstCombine can fold this, but not InstSimplify.
694 define i1 @add_nsw_neg_const2(i32 %x) {
695 ; CHECK-LABEL: @add_nsw_neg_const2(
696 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], -2147483647
697 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[ADD]], -1
698 ; CHECK-NEXT:    ret i1 [[CMP]]
700   %add = add nsw i32 %x, -2147483647
701   %cmp = icmp sgt i32 %add, -1
702   ret i1 %cmp
705 ; The upper bound of the 'add' is 1 (move the constants to prove we're doing range-based analysis).
707 define i1 @add_nsw_neg_const3(i32 %x) {
708 ; CHECK-LABEL: @add_nsw_neg_const3(
709 ; CHECK-NEXT:    ret i1 false
711   %add = add nsw i32 %x, -2147483646
712   %cmp = icmp sgt i32 %add, 1
713   ret i1 %cmp
716 ; InstCombine can fold this, but not InstSimplify.
718 define i1 @add_nsw_neg_const4(i32 %x) {
719 ; CHECK-LABEL: @add_nsw_neg_const4(
720 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], -2147483646
721 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[ADD]], 0
722 ; CHECK-NEXT:    ret i1 [[CMP]]
724   %add = add nsw i32 %x, -2147483646
725   %cmp = icmp sgt i32 %add, 0
726   ret i1 %cmp
729 ; The upper bound of the 'add' is 2147483647 - 42 = 2147483605 (move the constants again and try a different cmp predicate).
731 define i1 @add_nsw_neg_const5(i32 %x) {
732 ; CHECK-LABEL: @add_nsw_neg_const5(
733 ; CHECK-NEXT:    ret i1 true
735   %add = add nsw i32 %x, -42
736   %cmp = icmp ne i32 %add, 2147483606
737   ret i1 %cmp
740 ; InstCombine can fold this, but not InstSimplify.
742 define i1 @add_nsw_neg_const6(i32 %x) {
743 ; CHECK-LABEL: @add_nsw_neg_const6(
744 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], -42
745 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[ADD]], 2147483605
746 ; CHECK-NEXT:    ret i1 [[CMP]]
748   %add = add nsw i32 %x, -42
749   %cmp = icmp ne i32 %add, 2147483605
750   ret i1 %cmp
753 ; The lower bound of the 'add' is -1.
755 define i1 @add_nsw_pos_const1(i32 %x) {
756 ; CHECK-LABEL: @add_nsw_pos_const1(
757 ; CHECK-NEXT:    ret i1 false
759   %add = add nsw i32 %x, 2147483647
760   %cmp = icmp slt i32 %add, -1
761   ret i1 %cmp
764 ; InstCombine can fold this, but not InstSimplify.
766 define i1 @add_nsw_pos_const2(i32 %x) {
767 ; CHECK-LABEL: @add_nsw_pos_const2(
768 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 2147483647
769 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[ADD]], 0
770 ; CHECK-NEXT:    ret i1 [[CMP]]
772   %add = add nsw i32 %x, 2147483647
773   %cmp = icmp slt i32 %add, 0
774   ret i1 %cmp
777 ; The lower bound of the 'add' is -2 (move the constants to prove we're doing range-based analysis).
779 define i1 @add_nsw_pos_const3(i32 %x) {
780 ; CHECK-LABEL: @add_nsw_pos_const3(
781 ; CHECK-NEXT:    ret i1 false
783   %add = add nsw i32 %x, 2147483646
784   %cmp = icmp slt i32 %add, -2
785   ret i1 %cmp
788 ; InstCombine can fold this, but not InstSimplify.
790 define i1 @add_nsw_pos_const4(i32 %x) {
791 ; CHECK-LABEL: @add_nsw_pos_const4(
792 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 2147483646
793 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[ADD]], -1
794 ; CHECK-NEXT:    ret i1 [[CMP]]
796   %add = add nsw i32 %x, 2147483646
797   %cmp = icmp slt i32 %add, -1
798   ret i1 %cmp
801 ; The lower bound of the 'add' is -2147483648 + 42 = -2147483606 (move the constants again and change the cmp predicate).
803 define i1 @add_nsw_pos_const5(i32 %x) {
804 ; CHECK-LABEL: @add_nsw_pos_const5(
805 ; CHECK-NEXT:    ret i1 false
807   %add = add nsw i32 %x, 42
808   %cmp = icmp eq i32 %add, -2147483607
809   ret i1 %cmp
812 ; InstCombine can fold this, but not InstSimplify.
814 define i1 @add_nsw_pos_const6(i32 %x) {
815 ; CHECK-LABEL: @add_nsw_pos_const6(
816 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 42
817 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[ADD]], -2147483606
818 ; CHECK-NEXT:    ret i1 [[CMP]]
820   %add = add nsw i32 %x, 42
821   %cmp = icmp eq i32 %add, -2147483606
822   ret i1 %cmp
825 ; Verify that vectors work too.
827 define <2 x i1> @add_nsw_pos_const5_splat_vec(<2 x i32> %x) {
828 ; CHECK-LABEL: @add_nsw_pos_const5_splat_vec(
829 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
831   %add = add nsw <2 x i32> %x, <i32 42, i32 42>
832   %cmp = icmp ne <2 x i32> %add, <i32 -2147483607, i32 -2147483607>
833   ret <2 x i1> %cmp
836 ; PR34838 - https://bugs.llvm.org/show_bug.cgi?id=34838
837 ; The shift is known to create poison, so we can simplify the cmp.
839 define i1 @ne_shl_by_constant_produces_poison(i8 %x) {
840 ; CHECK-LABEL: @ne_shl_by_constant_produces_poison(
841 ; CHECK-NEXT:    ret i1 poison
843   %zx = zext i8 %x to i16      ; zx  = 0x00xx
844   %xor = xor i16 %zx, 32767    ; xor = 0x7fyy
845   %sub = sub nsw i16 %zx, %xor ; sub = 0x80zz  (the top bit is known one)
846   %poison = shl nsw i16 %sub, 2    ; oops! this shl can't be nsw; that's POISON
847   %cmp = icmp ne i16 %poison, 1
848   ret i1 %cmp
851 define i1 @eq_shl_by_constant_produces_poison(i8 %x) {
852 ; CHECK-LABEL: @eq_shl_by_constant_produces_poison(
853 ; CHECK-NEXT:    ret i1 poison
855   %clear_high_bit = and i8 %x, 127                 ; 0x7f
856   %set_next_high_bits = or i8 %clear_high_bit, 112 ; 0x70
857   %poison = shl nsw i8 %set_next_high_bits, 3
858   %cmp = icmp eq i8 %poison, 15
859   ret i1 %cmp
862 ; Shift-by-variable that produces poison is more complicated but still possible.
863 ; We guarantee that the shift will change the sign of the shifted value (and
864 ; therefore produce poison) by limiting its range from 1 to 3.
866 define i1 @eq_shl_by_variable_produces_poison(i8 %x) {
867 ; CHECK-LABEL: @eq_shl_by_variable_produces_poison(
868 ; CHECK-NEXT:    ret i1 poison
870   %clear_high_bit = and i8 %x, 127                 ; 0x7f
871   %set_next_high_bits = or i8 %clear_high_bit, 112 ; 0x70
872   %notundef_shiftamt = and i8 %x, 3
873   %nonzero_shiftamt = or i8 %notundef_shiftamt, 1
874   %poison = shl nsw i8 %set_next_high_bits, %nonzero_shiftamt
875   %cmp = icmp eq i8 %poison, 15
876   ret i1 %cmp
879 ; No overflow, so mul constant must be a factor of cmp constant.
881 define i1 @mul_nuw_urem_cmp_constant1(i8 %x) {
882 ; CHECK-LABEL: @mul_nuw_urem_cmp_constant1(
883 ; CHECK-NEXT:    ret i1 false
885   %m = mul nuw i8 %x, 43
886   %r = icmp eq i8 %m, 42
887   ret i1 %r
890 ; Invert predicate and check vector type.
892 define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat(<2 x i8> %x) {
893 ; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat(
894 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
896   %m = mul nuw <2 x i8> %x, <i8 45, i8 45>
897   %r = icmp ne <2 x i8> %m, <i8 15, i8 15>
898   ret <2 x i1> %r
901 ; Undefs in vector constants are ok.
903 define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat_undef1(<2 x i8> %x) {
904 ; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat_undef1(
905 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
907   %m = mul nuw <2 x i8> %x, <i8 45, i8 45>
908   %r = icmp ne <2 x i8> %m, <i8 15, i8 undef>
909   ret <2 x i1> %r
912 ; Undefs in vector constants are ok.
914 define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat_undef2(<2 x i8> %x) {
915 ; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat_undef2(
916 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
918   %m = mul nuw <2 x i8> %x, <i8 undef, i8 45>
919   %r = icmp ne <2 x i8> %m, <i8 15, i8 15>
920   ret <2 x i1> %r
923 ; Check "negative" numbers (constants should be analyzed as unsigned).
925 define i1 @mul_nuw_urem_cmp_constant2(i8 %x) {
926 ; CHECK-LABEL: @mul_nuw_urem_cmp_constant2(
927 ; CHECK-NEXT:    ret i1 false
929   %m = mul nuw i8 %x, -42
930   %r = icmp eq i8 %m, -84
931   ret i1 %r
934 ; Negative test - require nuw.
936 define i1 @mul_urem_cmp_constant1(i8 %x) {
937 ; CHECK-LABEL: @mul_urem_cmp_constant1(
938 ; CHECK-NEXT:    [[M:%.*]] = mul i8 [[X:%.*]], 43
939 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 42
940 ; CHECK-NEXT:    ret i1 [[R]]
942   %m = mul i8 %x, 43
943   %r = icmp eq i8 %m, 42
944   ret i1 %r
947 ; Negative test - x could be 0.
949 define i1 @mul_nuw_urem_cmp_constant0(i8 %x) {
950 ; CHECK-LABEL: @mul_nuw_urem_cmp_constant0(
951 ; CHECK-NEXT:    [[M:%.*]] = mul nuw i8 [[X:%.*]], 23
952 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 0
953 ; CHECK-NEXT:    ret i1 [[R]]
955   %m = mul nuw i8 %x, 23
956   %r = icmp eq i8 %m, 0
957   ret i1 %r
960 ; Negative test - cmp constant is multiple of mul constant.
962 define i1 @mul_nuw_urem_cmp_constant_is_0(i8 %x) {
963 ; CHECK-LABEL: @mul_nuw_urem_cmp_constant_is_0(
964 ; CHECK-NEXT:    [[M:%.*]] = mul nuw i8 [[X:%.*]], 42
965 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 84
966 ; CHECK-NEXT:    ret i1 [[R]]
968   %m = mul nuw i8 %x, 42
969   %r = icmp eq i8 %m, 84
970   ret i1 %r
973 ; Negative test - cmp constant is multiple (treated as unsigned).
975 define i1 @mul_nuw_urem_cmp_neg_constant_is_0(i8 %x) {
976 ; CHECK-LABEL: @mul_nuw_urem_cmp_neg_constant_is_0(
977 ; CHECK-NEXT:    [[M:%.*]] = mul nuw i8 [[X:%.*]], 43
978 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], -127
979 ; CHECK-NEXT:    ret i1 [[R]]
981   %m = mul nuw i8 %x, 43
982   %r = icmp eq i8 %m, -127
983   ret i1 %r
986 ; No overflow, so mul constant must be a factor of cmp constant.
988 define i1 @mul_nsw_srem_cmp_constant1(i8 %x) {
989 ; CHECK-LABEL: @mul_nsw_srem_cmp_constant1(
990 ; CHECK-NEXT:    ret i1 false
992   %m = mul nsw i8 %x, 43
993   %r = icmp eq i8 %m, 45
994   ret i1 %r
997 ; Invert predicate and check vector type.
999 define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat(<2 x i8> %x) {
1000 ; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat(
1001 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
1003   %m = mul nsw <2 x i8> %x, <i8 45, i8 45>
1004   %r = icmp ne <2 x i8> %m, <i8 15, i8 15>
1005   ret <2 x i1> %r
1008 ; Undefs in vector constants are ok.
1010 define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat_undef1(<2 x i8> %x) {
1011 ; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat_undef1(
1012 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
1014   %m = mul nsw <2 x i8> %x, <i8 45, i8 45>
1015   %r = icmp ne <2 x i8> %m, <i8 15, i8 undef>
1016   ret <2 x i1> %r
1019 ; Undefs in vector constants are ok.
1021 define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat_undef2(<2 x i8> %x) {
1022 ; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat_undef2(
1023 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
1025   %m = mul nsw <2 x i8> %x, <i8 undef, i8 45>
1026   %r = icmp ne <2 x i8> %m, <i8 15, i8 15>
1027   ret <2 x i1> %r
1030 ; Check negative numbers (constants should be analyzed as signed).
1032 define i1 @mul_nsw_srem_cmp_constant2(i8 %x) {
1033 ; CHECK-LABEL: @mul_nsw_srem_cmp_constant2(
1034 ; CHECK-NEXT:    ret i1 false
1036   %m = mul nsw i8 %x, 43
1037   %r = icmp eq i8 %m, -127
1038   ret i1 %r
1041 ; Negative test - require nsw.
1043 define i1 @mul_srem_cmp_constant1(i8 %x) {
1044 ; CHECK-LABEL: @mul_srem_cmp_constant1(
1045 ; CHECK-NEXT:    [[M:%.*]] = mul i8 [[X:%.*]], 43
1046 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 42
1047 ; CHECK-NEXT:    ret i1 [[R]]
1049   %m = mul i8 %x, 43
1050   %r = icmp eq i8 %m, 42
1051   ret i1 %r
1054 ; Negative test - x could be 0.
1056 define i1 @mul_nsw_srem_cmp_constant0(i8 %x) {
1057 ; CHECK-LABEL: @mul_nsw_srem_cmp_constant0(
1058 ; CHECK-NEXT:    [[M:%.*]] = mul nsw i8 [[X:%.*]], 23
1059 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 0
1060 ; CHECK-NEXT:    ret i1 [[R]]
1062   %m = mul nsw i8 %x, 23
1063   %r = icmp eq i8 %m, 0
1064   ret i1 %r
1067 ; Negative test - cmp constant is multiple of mul constant.
1069 define i1 @mul_nsw_srem_cmp_constant_is_0(i8 %x) {
1070 ; CHECK-LABEL: @mul_nsw_srem_cmp_constant_is_0(
1071 ; CHECK-NEXT:    [[M:%.*]] = mul nsw i8 [[X:%.*]], 42
1072 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 84
1073 ; CHECK-NEXT:    ret i1 [[R]]
1075   %m = mul nsw i8 %x, 42
1076   %r = icmp eq i8 %m, 84
1077   ret i1 %r
1080 ; Negative test - cmp constant is multiple (treated as signed).
1082 define i1 @mul_nsw_srem_cmp_neg_constant_is_0(i8 %x) {
1083 ; CHECK-LABEL: @mul_nsw_srem_cmp_neg_constant_is_0(
1084 ; CHECK-NEXT:    [[M:%.*]] = mul nsw i8 [[X:%.*]], -42
1085 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], -84
1086 ; CHECK-NEXT:    ret i1 [[R]]
1088   %m = mul nsw i8 %x, -42
1089   %r = icmp eq i8 %m, -84
1090   ret i1 %r
1093 ; Don't crash trying to div/rem-by-zero.
1095 define i1 @mul_nsw_by_zero(i8 %x) {
1096 ; CHECK-LABEL: @mul_nsw_by_zero(
1097 ; CHECK-NEXT:  bb1:
1098 ; CHECK-NEXT:    br label [[BB3:%.*]]
1099 ; CHECK:       bb2:
1100 ; CHECK-NEXT:    ret i1 false
1101 ; CHECK:       bb3:
1102 ; CHECK-NEXT:    br label [[BB2:%.*]]
1104 bb1:
1105   br label %bb3
1106 bb2:
1107   %r = icmp eq i8 %m, 45
1108   ret i1 %r
1109 bb3:
1110   %m = mul nsw i8 %x, 0
1111   br label %bb2
1114 ; Don't crash trying to div/rem-by-zero.
1116 define i1 @mul_nuw_by_zero(i8 %x) {
1117 ; CHECK-LABEL: @mul_nuw_by_zero(
1118 ; CHECK-NEXT:  bb1:
1119 ; CHECK-NEXT:    br label [[BB3:%.*]]
1120 ; CHECK:       bb2:
1121 ; CHECK-NEXT:    ret i1 false
1122 ; CHECK:       bb3:
1123 ; CHECK-NEXT:    br label [[BB2:%.*]]
1125 bb1:
1126   br label %bb3
1127 bb2:
1128   %r = icmp eq i8 %m, 45
1129   ret i1 %r
1130 bb3:
1131   %m = mul nuw i8 %x, 0
1132   br label %bb2
1136 define <2 x i1> @heterogeneous_constvector(<2 x i8> %x) {
1137 ; CHECK-LABEL: @heterogeneous_constvector(
1138 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1140   %c = icmp ult <2 x i8> %x, <i8 undef, i8 poison>
1141   ret <2 x i1> %c