[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / InstSimplify / icmp-constant.ll
blob77d4a388c05546b43328e6459a24b6c1d13f231f
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -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 ; InstCombine can fold this, but not InstSimplify.
628 define i1 @add_nsw_neg_const2(i32 %x) {
629 ; CHECK-LABEL: @add_nsw_neg_const2(
630 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], -2147483647
631 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[ADD]], -1
632 ; CHECK-NEXT:    ret i1 [[CMP]]
634   %add = add nsw i32 %x, -2147483647
635   %cmp = icmp sgt i32 %add, -1
636   ret i1 %cmp
639 ; The upper bound of the 'add' is 1 (move the constants to prove we're doing range-based analysis).
641 define i1 @add_nsw_neg_const3(i32 %x) {
642 ; CHECK-LABEL: @add_nsw_neg_const3(
643 ; CHECK-NEXT:    ret i1 false
645   %add = add nsw i32 %x, -2147483646
646   %cmp = icmp sgt i32 %add, 1
647   ret i1 %cmp
650 ; InstCombine can fold this, but not InstSimplify.
652 define i1 @add_nsw_neg_const4(i32 %x) {
653 ; CHECK-LABEL: @add_nsw_neg_const4(
654 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], -2147483646
655 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[ADD]], 0
656 ; CHECK-NEXT:    ret i1 [[CMP]]
658   %add = add nsw i32 %x, -2147483646
659   %cmp = icmp sgt i32 %add, 0
660   ret i1 %cmp
663 ; The upper bound of the 'add' is 2147483647 - 42 = 2147483605 (move the constants again and try a different cmp predicate).
665 define i1 @add_nsw_neg_const5(i32 %x) {
666 ; CHECK-LABEL: @add_nsw_neg_const5(
667 ; CHECK-NEXT:    ret i1 true
669   %add = add nsw i32 %x, -42
670   %cmp = icmp ne i32 %add, 2147483606
671   ret i1 %cmp
674 ; InstCombine can fold this, but not InstSimplify.
676 define i1 @add_nsw_neg_const6(i32 %x) {
677 ; CHECK-LABEL: @add_nsw_neg_const6(
678 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], -42
679 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[ADD]], 2147483605
680 ; CHECK-NEXT:    ret i1 [[CMP]]
682   %add = add nsw i32 %x, -42
683   %cmp = icmp ne i32 %add, 2147483605
684   ret i1 %cmp
687 ; The lower bound of the 'add' is -1.
689 define i1 @add_nsw_pos_const1(i32 %x) {
690 ; CHECK-LABEL: @add_nsw_pos_const1(
691 ; CHECK-NEXT:    ret i1 false
693   %add = add nsw i32 %x, 2147483647
694   %cmp = icmp slt i32 %add, -1
695   ret i1 %cmp
698 ; InstCombine can fold this, but not InstSimplify.
700 define i1 @add_nsw_pos_const2(i32 %x) {
701 ; CHECK-LABEL: @add_nsw_pos_const2(
702 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 2147483647
703 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[ADD]], 0
704 ; CHECK-NEXT:    ret i1 [[CMP]]
706   %add = add nsw i32 %x, 2147483647
707   %cmp = icmp slt i32 %add, 0
708   ret i1 %cmp
711 ; The lower bound of the 'add' is -2 (move the constants to prove we're doing range-based analysis).
713 define i1 @add_nsw_pos_const3(i32 %x) {
714 ; CHECK-LABEL: @add_nsw_pos_const3(
715 ; CHECK-NEXT:    ret i1 false
717   %add = add nsw i32 %x, 2147483646
718   %cmp = icmp slt i32 %add, -2
719   ret i1 %cmp
722 ; InstCombine can fold this, but not InstSimplify.
724 define i1 @add_nsw_pos_const4(i32 %x) {
725 ; CHECK-LABEL: @add_nsw_pos_const4(
726 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 2147483646
727 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[ADD]], -1
728 ; CHECK-NEXT:    ret i1 [[CMP]]
730   %add = add nsw i32 %x, 2147483646
731   %cmp = icmp slt i32 %add, -1
732   ret i1 %cmp
735 ; The lower bound of the 'add' is -2147483648 + 42 = -2147483606 (move the constants again and change the cmp predicate).
737 define i1 @add_nsw_pos_const5(i32 %x) {
738 ; CHECK-LABEL: @add_nsw_pos_const5(
739 ; CHECK-NEXT:    ret i1 false
741   %add = add nsw i32 %x, 42
742   %cmp = icmp eq i32 %add, -2147483607
743   ret i1 %cmp
746 ; InstCombine can fold this, but not InstSimplify.
748 define i1 @add_nsw_pos_const6(i32 %x) {
749 ; CHECK-LABEL: @add_nsw_pos_const6(
750 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 42
751 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[ADD]], -2147483606
752 ; CHECK-NEXT:    ret i1 [[CMP]]
754   %add = add nsw i32 %x, 42
755   %cmp = icmp eq i32 %add, -2147483606
756   ret i1 %cmp
759 ; Verify that vectors work too.
761 define <2 x i1> @add_nsw_pos_const5_splat_vec(<2 x i32> %x) {
762 ; CHECK-LABEL: @add_nsw_pos_const5_splat_vec(
763 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
765   %add = add nsw <2 x i32> %x, <i32 42, i32 42>
766   %cmp = icmp ne <2 x i32> %add, <i32 -2147483607, i32 -2147483607>
767   ret <2 x i1> %cmp
770 ; PR34838 - https://bugs.llvm.org/show_bug.cgi?id=34838
771 ; The shift is known to create poison, so we can simplify the cmp.
773 define i1 @ne_shl_by_constant_produces_poison(i8 %x) {
774 ; CHECK-LABEL: @ne_shl_by_constant_produces_poison(
775 ; CHECK-NEXT:    ret i1 poison
777   %zx = zext i8 %x to i16      ; zx  = 0x00xx
778   %xor = xor i16 %zx, 32767    ; xor = 0x7fyy
779   %sub = sub nsw i16 %zx, %xor ; sub = 0x80zz  (the top bit is known one)
780   %poison = shl nsw i16 %sub, 2    ; oops! this shl can't be nsw; that's POISON
781   %cmp = icmp ne i16 %poison, 1
782   ret i1 %cmp
785 define i1 @eq_shl_by_constant_produces_poison(i8 %x) {
786 ; CHECK-LABEL: @eq_shl_by_constant_produces_poison(
787 ; CHECK-NEXT:    ret i1 poison
789   %clear_high_bit = and i8 %x, 127                 ; 0x7f
790   %set_next_high_bits = or i8 %clear_high_bit, 112 ; 0x70
791   %poison = shl nsw i8 %set_next_high_bits, 3
792   %cmp = icmp eq i8 %poison, 15
793   ret i1 %cmp
796 ; Shift-by-variable that produces poison is more complicated but still possible.
797 ; We guarantee that the shift will change the sign of the shifted value (and
798 ; therefore produce poison) by limiting its range from 1 to 3.
800 define i1 @eq_shl_by_variable_produces_poison(i8 %x) {
801 ; CHECK-LABEL: @eq_shl_by_variable_produces_poison(
802 ; CHECK-NEXT:    ret i1 poison
804   %clear_high_bit = and i8 %x, 127                 ; 0x7f
805   %set_next_high_bits = or i8 %clear_high_bit, 112 ; 0x70
806   %notundef_shiftamt = and i8 %x, 3
807   %nonzero_shiftamt = or i8 %notundef_shiftamt, 1
808   %poison = shl nsw i8 %set_next_high_bits, %nonzero_shiftamt
809   %cmp = icmp eq i8 %poison, 15
810   ret i1 %cmp
813 ; No overflow, so mul constant must be a factor of cmp constant.
815 define i1 @mul_nuw_urem_cmp_constant1(i8 %x) {
816 ; CHECK-LABEL: @mul_nuw_urem_cmp_constant1(
817 ; CHECK-NEXT:    ret i1 false
819   %m = mul nuw i8 %x, 43
820   %r = icmp eq i8 %m, 42
821   ret i1 %r
824 ; Invert predicate and check vector type.
826 define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat(<2 x i8> %x) {
827 ; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat(
828 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
830   %m = mul nuw <2 x i8> %x, <i8 45, i8 45>
831   %r = icmp ne <2 x i8> %m, <i8 15, i8 15>
832   ret <2 x i1> %r
835 ; Undefs in vector constants are ok.
837 define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat_undef1(<2 x i8> %x) {
838 ; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat_undef1(
839 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
841   %m = mul nuw <2 x i8> %x, <i8 45, i8 45>
842   %r = icmp ne <2 x i8> %m, <i8 15, i8 undef>
843   ret <2 x i1> %r
846 ; Undefs in vector constants are ok.
848 define <2 x i1> @mul_nuw_urem_cmp_constant_vec_splat_undef2(<2 x i8> %x) {
849 ; CHECK-LABEL: @mul_nuw_urem_cmp_constant_vec_splat_undef2(
850 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
852   %m = mul nuw <2 x i8> %x, <i8 undef, i8 45>
853   %r = icmp ne <2 x i8> %m, <i8 15, i8 15>
854   ret <2 x i1> %r
857 ; Check "negative" numbers (constants should be analyzed as unsigned).
859 define i1 @mul_nuw_urem_cmp_constant2(i8 %x) {
860 ; CHECK-LABEL: @mul_nuw_urem_cmp_constant2(
861 ; CHECK-NEXT:    ret i1 false
863   %m = mul nuw i8 %x, -42
864   %r = icmp eq i8 %m, -84
865   ret i1 %r
868 ; Negative test - require nuw.
870 define i1 @mul_urem_cmp_constant1(i8 %x) {
871 ; CHECK-LABEL: @mul_urem_cmp_constant1(
872 ; CHECK-NEXT:    [[M:%.*]] = mul i8 [[X:%.*]], 43
873 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 42
874 ; CHECK-NEXT:    ret i1 [[R]]
876   %m = mul i8 %x, 43
877   %r = icmp eq i8 %m, 42
878   ret i1 %r
881 ; Negative test - x could be 0.
883 define i1 @mul_nuw_urem_cmp_constant0(i8 %x) {
884 ; CHECK-LABEL: @mul_nuw_urem_cmp_constant0(
885 ; CHECK-NEXT:    [[M:%.*]] = mul nuw i8 [[X:%.*]], 23
886 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 0
887 ; CHECK-NEXT:    ret i1 [[R]]
889   %m = mul nuw i8 %x, 23
890   %r = icmp eq i8 %m, 0
891   ret i1 %r
894 ; Negative test - cmp constant is multiple of mul constant.
896 define i1 @mul_nuw_urem_cmp_constant_is_0(i8 %x) {
897 ; CHECK-LABEL: @mul_nuw_urem_cmp_constant_is_0(
898 ; CHECK-NEXT:    [[M:%.*]] = mul nuw i8 [[X:%.*]], 42
899 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 84
900 ; CHECK-NEXT:    ret i1 [[R]]
902   %m = mul nuw i8 %x, 42
903   %r = icmp eq i8 %m, 84
904   ret i1 %r
907 ; Negative test - cmp constant is multiple (treated as unsigned).
909 define i1 @mul_nuw_urem_cmp_neg_constant_is_0(i8 %x) {
910 ; CHECK-LABEL: @mul_nuw_urem_cmp_neg_constant_is_0(
911 ; CHECK-NEXT:    [[M:%.*]] = mul nuw i8 [[X:%.*]], 43
912 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], -127
913 ; CHECK-NEXT:    ret i1 [[R]]
915   %m = mul nuw i8 %x, 43
916   %r = icmp eq i8 %m, -127
917   ret i1 %r
920 ; No overflow, so mul constant must be a factor of cmp constant.
922 define i1 @mul_nsw_srem_cmp_constant1(i8 %x) {
923 ; CHECK-LABEL: @mul_nsw_srem_cmp_constant1(
924 ; CHECK-NEXT:    ret i1 false
926   %m = mul nsw i8 %x, 43
927   %r = icmp eq i8 %m, 45
928   ret i1 %r
931 ; Invert predicate and check vector type.
933 define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat(<2 x i8> %x) {
934 ; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat(
935 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
937   %m = mul nsw <2 x i8> %x, <i8 45, i8 45>
938   %r = icmp ne <2 x i8> %m, <i8 15, i8 15>
939   ret <2 x i1> %r
942 ; Undefs in vector constants are ok.
944 define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat_undef1(<2 x i8> %x) {
945 ; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat_undef1(
946 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
948   %m = mul nsw <2 x i8> %x, <i8 45, i8 45>
949   %r = icmp ne <2 x i8> %m, <i8 15, i8 undef>
950   ret <2 x i1> %r
953 ; Undefs in vector constants are ok.
955 define <2 x i1> @mul_nsw_srem_cmp_constant_vec_splat_undef2(<2 x i8> %x) {
956 ; CHECK-LABEL: @mul_nsw_srem_cmp_constant_vec_splat_undef2(
957 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
959   %m = mul nsw <2 x i8> %x, <i8 undef, i8 45>
960   %r = icmp ne <2 x i8> %m, <i8 15, i8 15>
961   ret <2 x i1> %r
964 ; Check negative numbers (constants should be analyzed as signed).
966 define i1 @mul_nsw_srem_cmp_constant2(i8 %x) {
967 ; CHECK-LABEL: @mul_nsw_srem_cmp_constant2(
968 ; CHECK-NEXT:    ret i1 false
970   %m = mul nsw i8 %x, 43
971   %r = icmp eq i8 %m, -127
972   ret i1 %r
975 ; Negative test - require nsw.
977 define i1 @mul_srem_cmp_constant1(i8 %x) {
978 ; CHECK-LABEL: @mul_srem_cmp_constant1(
979 ; CHECK-NEXT:    [[M:%.*]] = mul i8 [[X:%.*]], 43
980 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 42
981 ; CHECK-NEXT:    ret i1 [[R]]
983   %m = mul i8 %x, 43
984   %r = icmp eq i8 %m, 42
985   ret i1 %r
988 ; Negative test - x could be 0.
990 define i1 @mul_nsw_srem_cmp_constant0(i8 %x) {
991 ; CHECK-LABEL: @mul_nsw_srem_cmp_constant0(
992 ; CHECK-NEXT:    [[M:%.*]] = mul nsw i8 [[X:%.*]], 23
993 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 0
994 ; CHECK-NEXT:    ret i1 [[R]]
996   %m = mul nsw i8 %x, 23
997   %r = icmp eq i8 %m, 0
998   ret i1 %r
1001 ; Negative test - cmp constant is multiple of mul constant.
1003 define i1 @mul_nsw_srem_cmp_constant_is_0(i8 %x) {
1004 ; CHECK-LABEL: @mul_nsw_srem_cmp_constant_is_0(
1005 ; CHECK-NEXT:    [[M:%.*]] = mul nsw i8 [[X:%.*]], 42
1006 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], 84
1007 ; CHECK-NEXT:    ret i1 [[R]]
1009   %m = mul nsw i8 %x, 42
1010   %r = icmp eq i8 %m, 84
1011   ret i1 %r
1014 ; Negative test - cmp constant is multiple (treated as signed).
1016 define i1 @mul_nsw_srem_cmp_neg_constant_is_0(i8 %x) {
1017 ; CHECK-LABEL: @mul_nsw_srem_cmp_neg_constant_is_0(
1018 ; CHECK-NEXT:    [[M:%.*]] = mul nsw i8 [[X:%.*]], -42
1019 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[M]], -84
1020 ; CHECK-NEXT:    ret i1 [[R]]
1022   %m = mul nsw i8 %x, -42
1023   %r = icmp eq i8 %m, -84
1024   ret i1 %r
1027 ; Don't crash trying to div/rem-by-zero.
1029 define i1 @mul_nsw_by_zero(i8 %x) {
1030 ; CHECK-LABEL: @mul_nsw_by_zero(
1031 ; CHECK-NEXT:  bb1:
1032 ; CHECK-NEXT:    br label [[BB3:%.*]]
1033 ; CHECK:       bb2:
1034 ; CHECK-NEXT:    ret i1 false
1035 ; CHECK:       bb3:
1036 ; CHECK-NEXT:    br label [[BB2:%.*]]
1038 bb1:
1039   br label %bb3
1040 bb2:
1041   %r = icmp eq i8 %m, 45
1042   ret i1 %r
1043 bb3:
1044   %m = mul nsw i8 %x, 0
1045   br label %bb2
1048 ; Don't crash trying to div/rem-by-zero.
1050 define i1 @mul_nuw_by_zero(i8 %x) {
1051 ; CHECK-LABEL: @mul_nuw_by_zero(
1052 ; CHECK-NEXT:  bb1:
1053 ; CHECK-NEXT:    br label [[BB3:%.*]]
1054 ; CHECK:       bb2:
1055 ; CHECK-NEXT:    ret i1 false
1056 ; CHECK:       bb3:
1057 ; CHECK-NEXT:    br label [[BB2:%.*]]
1059 bb1:
1060   br label %bb3
1061 bb2:
1062   %r = icmp eq i8 %m, 45
1063   ret i1 %r
1064 bb3:
1065   %m = mul nuw i8 %x, 0
1066   br label %bb2
1070 define <2 x i1> @heterogeneous_constvector(<2 x i8> %x) {
1071 ; CHECK-LABEL: @heterogeneous_constvector(
1072 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
1074   %c = icmp ult <2 x i8> %x, <i8 undef, i8 poison>
1075   ret <2 x i1> %c