[MIParser] Set RegClassOrRegBank during instruction parsing
[llvm-complete.git] / test / Transforms / InstSimplify / icmp-constant.ll
blob3ebaca7c8aafbe2b3bd720194ef338ed7afaebdd
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 i1 @tautological_ugt(i8 %x) {
23 ; CHECK-LABEL: @tautological_ugt(
24 ; CHECK-NEXT:    ret i1 false
26   %cmp = icmp ugt i8 %x, 255
27   ret i1 %cmp
30 define <2 x i1> @tautological_ugt_vec(<2 x i8> %x) {
31 ; CHECK-LABEL: @tautological_ugt_vec(
32 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
34   %cmp = icmp ugt <2 x i8> %x, <i8 255, i8 255>
35   ret <2 x i1> %cmp
38 ; 'urem x, C2' produces [0, C2)
39 define i1 @urem3(i32 %X) {
40 ; CHECK-LABEL: @urem3(
41 ; CHECK-NEXT:    ret i1 true
43   %A = urem i32 %X, 10
44   %B = icmp ult i32 %A, 15
45   ret i1 %B
48 define <2 x i1> @urem3_vec(<2 x i32> %X) {
49 ; CHECK-LABEL: @urem3_vec(
50 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
52   %A = urem <2 x i32> %X, <i32 10, i32 10>
53   %B = icmp ult <2 x i32> %A, <i32 15, i32 15>
54   ret <2 x i1> %B
57 ;'srem x, C2' produces (-|C2|, |C2|)
58 define i1 @srem1(i32 %X) {
59 ; CHECK-LABEL: @srem1(
60 ; CHECK-NEXT:    ret i1 false
62   %A = srem i32 %X, -5
63   %B = icmp sgt i32 %A, 5
64   ret i1 %B
67 define <2 x i1> @srem1_vec(<2 x i32> %X) {
68 ; CHECK-LABEL: @srem1_vec(
69 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
71   %A = srem <2 x i32> %X, <i32 -5, i32 -5>
72   %B = icmp sgt <2 x i32> %A, <i32 5, i32 5>
73   ret <2 x i1> %B
76 ;'udiv C2, x' produces [0, C2]
77 define i1 @udiv5(i32 %X) {
78 ; CHECK-LABEL: @udiv5(
79 ; CHECK-NEXT:    ret i1 false
81   %A = udiv i32 123, %X
82   %C = icmp ugt i32 %A, 124
83   ret i1 %C
86 define <2 x i1> @udiv5_vec(<2 x i32> %X) {
87 ; CHECK-LABEL: @udiv5_vec(
88 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
90   %A = udiv <2 x i32> <i32 123, i32 123>, %X
91   %C = icmp ugt <2 x i32> %A, <i32 124, i32 124>
92   ret <2 x i1> %C
95 ; 'udiv x, C2' produces [0, UINT_MAX / C2]
96 define i1 @udiv1(i32 %X) {
97 ; CHECK-LABEL: @udiv1(
98 ; CHECK-NEXT:    ret i1 true
100   %A = udiv i32 %X, 1000000
101   %B = icmp ult i32 %A, 5000
102   ret i1 %B
105 define <2 x i1> @udiv1_vec(<2 x i32> %X) {
106 ; CHECK-LABEL: @udiv1_vec(
107 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
109   %A = udiv <2 x i32> %X, <i32 1000000, i32 1000000>
110   %B = icmp ult <2 x i32> %A, <i32 5000, i32 5000>
111   ret <2 x i1> %B
114 ; 'sdiv C2, x' produces [-|C2|, |C2|]
115 define i1 @compare_dividend(i32 %a) {
116 ; CHECK-LABEL: @compare_dividend(
117 ; CHECK-NEXT:    ret i1 false
119   %div = sdiv i32 2, %a
120   %cmp = icmp eq i32 %div, 3
121   ret i1 %cmp
124 define <2 x i1> @compare_dividend_vec(<2 x i32> %a) {
125 ; CHECK-LABEL: @compare_dividend_vec(
126 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
128   %div = sdiv <2 x i32> <i32 2, i32 2>, %a
129   %cmp = icmp eq <2 x i32> %div, <i32 3, i32 3>
130   ret <2 x i1> %cmp
133 ; 'sdiv x, C2' produces [INT_MIN / C2, INT_MAX / C2]
134 ;    where C2 != -1 and C2 != 0 and C2 != 1
135 define i1 @sdiv1(i32 %X) {
136 ; CHECK-LABEL: @sdiv1(
137 ; CHECK-NEXT:    ret i1 true
139   %A = sdiv i32 %X, 1000000
140   %B = icmp slt i32 %A, 3000
141   ret i1 %B
144 define <2 x i1> @sdiv1_vec(<2 x i32> %X) {
145 ; CHECK-LABEL: @sdiv1_vec(
146 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
148   %A = sdiv <2 x i32> %X, <i32 1000000, i32 1000000>
149   %B = icmp slt <2 x i32> %A, <i32 3000, i32 3000>
150   ret <2 x i1> %B
153 ; 'shl nuw C2, x' produces [C2, C2 << CLZ(C2)]
154 define i1 @shl5(i32 %X) {
155 ; CHECK-LABEL: @shl5(
156 ; CHECK-NEXT:    ret i1 true
158   %sub = shl nuw i32 4, %X
159   %cmp = icmp ugt i32 %sub, 3
160   ret i1 %cmp
163 define <2 x i1> @shl5_vec(<2 x i32> %X) {
164 ; CHECK-LABEL: @shl5_vec(
165 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
167   %sub = shl nuw <2 x i32> <i32 4, i32 4>, %X
168   %cmp = icmp ugt <2 x i32> %sub, <i32 3, i32 3>
169   ret <2 x i1> %cmp
172 ; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2]
173 define i1 @shl2(i32 %X) {
174 ; CHECK-LABEL: @shl2(
175 ; CHECK-NEXT:    ret i1 false
177   %sub = shl nsw i32 -1, %X
178   %cmp = icmp eq i32 %sub, 31
179   ret i1 %cmp
182 define <2 x i1> @shl2_vec(<2 x i32> %X) {
183 ; CHECK-LABEL: @shl2_vec(
184 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
186   %sub = shl nsw <2 x i32> <i32 -1, i32 -1>, %X
187   %cmp = icmp eq <2 x i32> %sub, <i32 31, i32 31>
188   ret <2 x i1> %cmp
191 ; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2]
192 define i1 @shl4(i32 %X) {
193 ; CHECK-LABEL: @shl4(
194 ; CHECK-NEXT:    ret i1 true
196   %sub = shl nsw i32 -1, %X
197   %cmp = icmp sle i32 %sub, -1
198   ret i1 %cmp
201 define <2 x i1> @shl4_vec(<2 x i32> %X) {
202 ; CHECK-LABEL: @shl4_vec(
203 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
205   %sub = shl nsw <2 x i32> <i32 -1, i32 -1>, %X
206   %cmp = icmp sle <2 x i32> %sub, <i32 -1, i32 -1>
207   ret <2 x i1> %cmp
210 ; 'shl nsw C2, x' produces [C2, C2 << CLZ(C2)-1]
211 define i1 @icmp_shl_nsw_1(i64 %a) {
212 ; CHECK-LABEL: @icmp_shl_nsw_1(
213 ; CHECK-NEXT:    ret i1 true
215   %shl = shl nsw i64 1, %a
216   %cmp = icmp sge i64 %shl, 0
217   ret i1 %cmp
220 define <2 x i1> @icmp_shl_nsw_1_vec(<2 x i64> %a) {
221 ; CHECK-LABEL: @icmp_shl_nsw_1_vec(
222 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
224   %shl = shl nsw <2 x i64> <i64 1, i64 1>, %a
225   %cmp = icmp sge <2 x i64> %shl, zeroinitializer
226   ret <2 x i1> %cmp
229 ; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2]
230 define i1 @icmp_shl_nsw_neg1(i64 %a) {
231 ; CHECK-LABEL: @icmp_shl_nsw_neg1(
232 ; CHECK-NEXT:    ret i1 false
234   %shl = shl nsw i64 -1, %a
235   %cmp = icmp sge i64 %shl, 3
236   ret i1 %cmp
239 define <2 x i1> @icmp_shl_nsw_neg1_vec(<2 x i64> %a) {
240 ; CHECK-LABEL: @icmp_shl_nsw_neg1_vec(
241 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
243   %shl = shl nsw <2 x i64> <i64 -1, i64 -1>, %a
244   %cmp = icmp sge <2 x i64> %shl, <i64 3, i64 3>
245   ret <2 x i1> %cmp
248 ; 'lshr x, C2' produces [0, UINT_MAX >> C2]
249 define i1 @lshr2(i32 %x) {
250 ; CHECK-LABEL: @lshr2(
251 ; CHECK-NEXT:    ret i1 false
253   %s = lshr i32 %x, 30
254   %c = icmp ugt i32 %s, 8
255   ret i1 %c
258 define <2 x i1> @lshr2_vec(<2 x i32> %x) {
259 ; CHECK-LABEL: @lshr2_vec(
260 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
262   %s = lshr <2 x i32> %x, <i32 30, i32 30>
263   %c = icmp ugt <2 x i32> %s, <i32 8, i32 8>
264   ret <2 x i1> %c
267 ; 'lshr C2, x' produces [C2 >> (Width-1), C2]
268 define i1 @exact_lshr_ugt_false(i32 %a) {
269 ; CHECK-LABEL: @exact_lshr_ugt_false(
270 ; CHECK-NEXT:    ret i1 false
272   %shr = lshr exact i32 30, %a
273   %cmp = icmp ult i32 %shr, 15
274   ret i1 %cmp
277 define <2 x i1> @exact_lshr_ugt_false_vec(<2 x i32> %a) {
278 ; CHECK-LABEL: @exact_lshr_ugt_false_vec(
279 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
281   %shr = lshr exact <2 x i32> <i32 30, i32 30>, %a
282   %cmp = icmp ult <2 x i32> %shr, <i32 15, i32 15>
283   ret <2 x i1> %cmp
286 ; 'lshr C2, x' produces [C2 >> (Width-1), C2]
287 define i1 @lshr_sgt_false(i32 %a) {
288 ; CHECK-LABEL: @lshr_sgt_false(
289 ; CHECK-NEXT:    ret i1 false
291   %shr = lshr i32 1, %a
292   %cmp = icmp sgt i32 %shr, 1
293   ret i1 %cmp
296 define <2 x i1> @lshr_sgt_false_vec(<2 x i32> %a) {
297 ; CHECK-LABEL: @lshr_sgt_false_vec(
298 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
300   %shr = lshr <2 x i32> <i32 1, i32 1>, %a
301   %cmp = icmp sgt <2 x i32> %shr, <i32 1, i32 1>
302   ret <2 x i1> %cmp
305 ; 'ashr x, C2' produces [INT_MIN >> C2, INT_MAX >> C2]
306 define i1 @ashr2(i32 %x) {
307 ; CHECK-LABEL: @ashr2(
308 ; CHECK-NEXT:    ret i1 false
310   %s = ashr i32 %x, 30
311   %c = icmp slt i32 %s, -5
312   ret i1 %c
315 define <2 x i1> @ashr2_vec(<2 x i32> %x) {
316 ; CHECK-LABEL: @ashr2_vec(
317 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
319   %s = ashr <2 x i32> %x, <i32 30, i32 30>
320   %c = icmp slt <2 x i32> %s, <i32 -5, i32 -5>
321   ret <2 x i1> %c
324 ; 'ashr C2, x' produces [C2, C2 >> (Width-1)]
325 define i1 @ashr_sgt_false(i32 %a) {
326 ; CHECK-LABEL: @ashr_sgt_false(
327 ; CHECK-NEXT:    ret i1 false
329   %shr = ashr i32 -30, %a
330   %cmp = icmp sgt i32 %shr, -1
331   ret i1 %cmp
334 define <2 x i1> @ashr_sgt_false_vec(<2 x i32> %a) {
335 ; CHECK-LABEL: @ashr_sgt_false_vec(
336 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
338   %shr = ashr <2 x i32> <i32 -30, i32 -30>, %a
339   %cmp = icmp sgt <2 x i32> %shr, <i32 -1, i32 -1>
340   ret <2 x i1> %cmp
343 ; 'ashr C2, x' produces [C2, C2 >> (Width-1)]
344 define i1 @exact_ashr_sgt_false(i32 %a) {
345 ; CHECK-LABEL: @exact_ashr_sgt_false(
346 ; CHECK-NEXT:    ret i1 false
348   %shr = ashr exact i32 -30, %a
349   %cmp = icmp sgt i32 %shr, -15
350   ret i1 %cmp
353 define <2 x i1> @exact_ashr_sgt_false_vec(<2 x i32> %a) {
354 ; CHECK-LABEL: @exact_ashr_sgt_false_vec(
355 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
357   %shr = ashr exact <2 x i32> <i32 -30, i32 -30>, %a
358   %cmp = icmp sgt <2 x i32> %shr, <i32 -15, i32 -15>
359   ret <2 x i1> %cmp
362 ; 'or x, C2' produces [C2, UINT_MAX]
363 define i1 @or1(i32 %X) {
364 ; CHECK-LABEL: @or1(
365 ; CHECK-NEXT:    ret i1 false
367   %A = or i32 %X, 62
368   %B = icmp ult i32 %A, 50
369   ret i1 %B
372 define <2 x i1> @or1_vec(<2 x i32> %X) {
373 ; CHECK-LABEL: @or1_vec(
374 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
376   %A = or <2 x i32> %X, <i32 62, i32 62>
377   %B = icmp ult <2 x i32> %A, <i32 50, i32 50>
378   ret <2 x i1> %B
381 ; Single bit OR.
382 define i1 @or2_true(i8 %x) {
383 ; CHECK-LABEL: @or2_true(
384 ; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], 64
385 ; CHECK-NEXT:    [[Z:%.*]] = icmp sge i8 [[Y]], -64
386 ; CHECK-NEXT:    ret i1 [[Z]]
388   %y = or i8 %x, 64
389   %z = icmp sge i8 %y, -64
390   ret i1 %z
393 define i1 @or2_unknown(i8 %x) {
394 ; CHECK-LABEL: @or2_unknown(
395 ; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], 64
396 ; CHECK-NEXT:    [[Z:%.*]] = icmp sgt i8 [[Y]], -64
397 ; CHECK-NEXT:    ret i1 [[Z]]
399   %y = or i8 %x, 64
400   %z = icmp sgt i8 %y, -64
401   ret i1 %z
404 ; Multi bit OR.
405 ; 78 = 0b01001110; -50 = 0b11001110
406 define i1 @or3_true(i8 %x) {
407 ; CHECK-LABEL: @or3_true(
408 ; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], 78
409 ; CHECK-NEXT:    [[Z:%.*]] = icmp sge i8 [[Y]], -50
410 ; CHECK-NEXT:    ret i1 [[Z]]
412   %y = or i8 %x, 78
413   %z = icmp sge i8 %y, -50
414   ret i1 %z
417 define i1 @or3_unknown(i8 %x) {
418 ; CHECK-LABEL: @or3_unknown(
419 ; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], 78
420 ; CHECK-NEXT:    [[Z:%.*]] = icmp sgt i8 [[Y]], -50
421 ; CHECK-NEXT:    ret i1 [[Z]]
423   %y = or i8 %x, 78
424   %z = icmp sgt i8 %y, -50
425   ret i1 %z
428 ; OR with sign bit.
429 define i1 @or4_true(i8 %x) {
430 ; CHECK-LABEL: @or4_true(
431 ; CHECK-NEXT:    ret i1 true
433   %y = or i8 %x, -64
434   %z = icmp sge i8 %y, -64
435   ret i1 %z
438 define i1 @or4_unknown(i8 %x) {
439 ; CHECK-LABEL: @or4_unknown(
440 ; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], -64
441 ; CHECK-NEXT:    [[Z:%.*]] = icmp sgt i8 [[Y]], -64
442 ; CHECK-NEXT:    ret i1 [[Z]]
444   %y = or i8 %x, -64
445   %z = icmp sgt i8 %y, -64
446   ret i1 %z
449 ; If sign bit is set, signed & unsigned ranges are the same.
450 define i1 @or5_true(i8 %x) {
451 ; CHECK-LABEL: @or5_true(
452 ; CHECK-NEXT:    ret i1 true
454   %y = or i8 %x, -64
455   %z = icmp uge i8 %y, -64
456   ret i1 %z
459 define i1 @or5_unknown(i8 %x) {
460 ; CHECK-LABEL: @or5_unknown(
461 ; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], -64
462 ; CHECK-NEXT:    [[Z:%.*]] = icmp ugt i8 [[Y]], -64
463 ; CHECK-NEXT:    ret i1 [[Z]]
465   %y = or i8 %x, -64
466   %z = icmp ugt i8 %y, -64
467   ret i1 %z
470 ; 'and x, C2' produces [0, C2]
471 define i1 @and1(i32 %X) {
472 ; CHECK-LABEL: @and1(
473 ; CHECK-NEXT:    ret i1 false
475   %A = and i32 %X, 62
476   %B = icmp ugt i32 %A, 70
477   ret i1 %B
480 define <2 x i1> @and1_vec(<2 x i32> %X) {
481 ; CHECK-LABEL: @and1_vec(
482 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
484   %A = and <2 x i32> %X, <i32 62, i32 62>
485   %B = icmp ugt <2 x i32> %A, <i32 70, i32 70>
486   ret <2 x i1> %B
489 ; If the sign bit is not set, signed and unsigned ranges are the same.
490 define i1 @and2(i32 %X) {
491 ; CHECK-LABEL: @and2(
492 ; CHECK-NEXT:    ret i1 false
494   %A = and i32 %X, 62
495   %B = icmp sgt i32 %A, 70
496   ret i1 %B
499 ; -75 = 0b10110101, 53 = 0b00110101
500 define i1 @and3_true1(i8 %x) {
501 ; CHECK-LABEL: @and3_true1(
502 ; CHECK-NEXT:    [[Y:%.*]] = and i8 [[X:%.*]], -75
503 ; CHECK-NEXT:    [[Z:%.*]] = icmp sge i8 [[Y]], -75
504 ; CHECK-NEXT:    ret i1 [[Z]]
506   %y = and i8 %x, -75
507   %z = icmp sge i8 %y, -75
508   ret i1 %z
511 define i1 @and3_unknown1(i8 %x) {
512 ; CHECK-LABEL: @and3_unknown1(
513 ; CHECK-NEXT:    [[Y:%.*]] = and i8 [[X:%.*]], -75
514 ; CHECK-NEXT:    [[Z:%.*]] = icmp sgt i8 [[Y]], -75
515 ; CHECK-NEXT:    ret i1 [[Z]]
517   %y = and i8 %x, -75
518   %z = icmp sgt i8 %y, -75
519   ret i1 %z
522 define i1 @and3_true2(i8 %x) {
523 ; CHECK-LABEL: @and3_true2(
524 ; CHECK-NEXT:    [[Y:%.*]] = and i8 [[X:%.*]], -75
525 ; CHECK-NEXT:    [[Z:%.*]] = icmp sle i8 [[Y]], 53
526 ; CHECK-NEXT:    ret i1 [[Z]]
528   %y = and i8 %x, -75
529   %z = icmp sle i8 %y, 53
530   ret i1 %z
533 define i1 @and3_unknown2(i8 %x) {
534 ; CHECK-LABEL: @and3_unknown2(
535 ; CHECK-NEXT:    [[Y:%.*]] = and i8 [[X:%.*]], -75
536 ; CHECK-NEXT:    [[Z:%.*]] = icmp slt i8 [[Y]], 53
537 ; CHECK-NEXT:    ret i1 [[Z]]
539   %y = and i8 %x, -75
540   %z = icmp slt i8 %y, 53
541   ret i1 %z
544 ; 'add nuw x, C2' produces [C2, UINT_MAX]
545 define i1 @tautological9(i32 %x) {
546 ; CHECK-LABEL: @tautological9(
547 ; CHECK-NEXT:    ret i1 true
549   %add = add nuw i32 %x, 13
550   %cmp = icmp ne i32 %add, 12
551   ret i1 %cmp
554 define <2 x i1> @tautological9_vec(<2 x i32> %x) {
555 ; CHECK-LABEL: @tautological9_vec(
556 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
558   %add = add nuw <2 x i32> %x, <i32 13, i32 13>
559   %cmp = icmp ne <2 x i32> %add, <i32 12, i32 12>
560   ret <2 x i1> %cmp
563 ; The upper bound of the 'add' is 0.
565 define i1 @add_nsw_neg_const1(i32 %x) {
566 ; CHECK-LABEL: @add_nsw_neg_const1(
567 ; CHECK-NEXT:    ret i1 false
569   %add = add nsw i32 %x, -2147483647
570   %cmp = icmp sgt i32 %add, 0
571   ret i1 %cmp
574 ; InstCombine can fold this, but not InstSimplify.
576 define i1 @add_nsw_neg_const2(i32 %x) {
577 ; CHECK-LABEL: @add_nsw_neg_const2(
578 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], -2147483647
579 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[ADD]], -1
580 ; CHECK-NEXT:    ret i1 [[CMP]]
582   %add = add nsw i32 %x, -2147483647
583   %cmp = icmp sgt i32 %add, -1
584   ret i1 %cmp
587 ; The upper bound of the 'add' is 1 (move the constants to prove we're doing range-based analysis).
589 define i1 @add_nsw_neg_const3(i32 %x) {
590 ; CHECK-LABEL: @add_nsw_neg_const3(
591 ; CHECK-NEXT:    ret i1 false
593   %add = add nsw i32 %x, -2147483646
594   %cmp = icmp sgt i32 %add, 1
595   ret i1 %cmp
598 ; InstCombine can fold this, but not InstSimplify.
600 define i1 @add_nsw_neg_const4(i32 %x) {
601 ; CHECK-LABEL: @add_nsw_neg_const4(
602 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], -2147483646
603 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[ADD]], 0
604 ; CHECK-NEXT:    ret i1 [[CMP]]
606   %add = add nsw i32 %x, -2147483646
607   %cmp = icmp sgt i32 %add, 0
608   ret i1 %cmp
611 ; The upper bound of the 'add' is 2147483647 - 42 = 2147483605 (move the constants again and try a different cmp predicate).
613 define i1 @add_nsw_neg_const5(i32 %x) {
614 ; CHECK-LABEL: @add_nsw_neg_const5(
615 ; CHECK-NEXT:    ret i1 true
617   %add = add nsw i32 %x, -42
618   %cmp = icmp ne i32 %add, 2147483606
619   ret i1 %cmp
622 ; InstCombine can fold this, but not InstSimplify.
624 define i1 @add_nsw_neg_const6(i32 %x) {
625 ; CHECK-LABEL: @add_nsw_neg_const6(
626 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], -42
627 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[ADD]], 2147483605
628 ; CHECK-NEXT:    ret i1 [[CMP]]
630   %add = add nsw i32 %x, -42
631   %cmp = icmp ne i32 %add, 2147483605
632   ret i1 %cmp
635 ; The lower bound of the 'add' is -1.
637 define i1 @add_nsw_pos_const1(i32 %x) {
638 ; CHECK-LABEL: @add_nsw_pos_const1(
639 ; CHECK-NEXT:    ret i1 false
641   %add = add nsw i32 %x, 2147483647
642   %cmp = icmp slt i32 %add, -1
643   ret i1 %cmp
646 ; InstCombine can fold this, but not InstSimplify.
648 define i1 @add_nsw_pos_const2(i32 %x) {
649 ; CHECK-LABEL: @add_nsw_pos_const2(
650 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 2147483647
651 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[ADD]], 0
652 ; CHECK-NEXT:    ret i1 [[CMP]]
654   %add = add nsw i32 %x, 2147483647
655   %cmp = icmp slt i32 %add, 0
656   ret i1 %cmp
659 ; The lower bound of the 'add' is -2 (move the constants to prove we're doing range-based analysis).
661 define i1 @add_nsw_pos_const3(i32 %x) {
662 ; CHECK-LABEL: @add_nsw_pos_const3(
663 ; CHECK-NEXT:    ret i1 false
665   %add = add nsw i32 %x, 2147483646
666   %cmp = icmp slt i32 %add, -2
667   ret i1 %cmp
670 ; InstCombine can fold this, but not InstSimplify.
672 define i1 @add_nsw_pos_const4(i32 %x) {
673 ; CHECK-LABEL: @add_nsw_pos_const4(
674 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 2147483646
675 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[ADD]], -1
676 ; CHECK-NEXT:    ret i1 [[CMP]]
678   %add = add nsw i32 %x, 2147483646
679   %cmp = icmp slt i32 %add, -1
680   ret i1 %cmp
683 ; The lower bound of the 'add' is -2147483648 + 42 = -2147483606 (move the constants again and change the cmp predicate).
685 define i1 @add_nsw_pos_const5(i32 %x) {
686 ; CHECK-LABEL: @add_nsw_pos_const5(
687 ; CHECK-NEXT:    ret i1 false
689   %add = add nsw i32 %x, 42
690   %cmp = icmp eq i32 %add, -2147483607
691   ret i1 %cmp
694 ; InstCombine can fold this, but not InstSimplify.
696 define i1 @add_nsw_pos_const6(i32 %x) {
697 ; CHECK-LABEL: @add_nsw_pos_const6(
698 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 42
699 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[ADD]], -2147483606
700 ; CHECK-NEXT:    ret i1 [[CMP]]
702   %add = add nsw i32 %x, 42
703   %cmp = icmp eq i32 %add, -2147483606
704   ret i1 %cmp
707 ; Verify that vectors work too.
709 define <2 x i1> @add_nsw_pos_const5_splat_vec(<2 x i32> %x) {
710 ; CHECK-LABEL: @add_nsw_pos_const5_splat_vec(
711 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
713   %add = add nsw <2 x i32> %x, <i32 42, i32 42>
714   %cmp = icmp ne <2 x i32> %add, <i32 -2147483607, i32 -2147483607>
715   ret <2 x i1> %cmp
718 ; PR34838 - https://bugs.llvm.org/show_bug.cgi?id=34838
719 ; The shift is known to create poison, so we can simplify the cmp.
721 define i1 @ne_shl_by_constant_produces_poison(i8 %x) {
722 ; CHECK-LABEL: @ne_shl_by_constant_produces_poison(
723 ; CHECK-NEXT:    ret i1 true
725   %zx = zext i8 %x to i16      ; zx  = 0x00xx
726   %xor = xor i16 %zx, 32767    ; xor = 0x7fyy
727   %sub = sub nsw i16 %zx, %xor ; sub = 0x80zz  (the top bit is known one)
728   %poison = shl nsw i16 %sub, 2    ; oops! this shl can't be nsw; that's POISON
729   %cmp = icmp ne i16 %poison, 1
730   ret i1 %cmp
733 define i1 @eq_shl_by_constant_produces_poison(i8 %x) {
734 ; CHECK-LABEL: @eq_shl_by_constant_produces_poison(
735 ; CHECK-NEXT:    ret i1 false
737   %clear_high_bit = and i8 %x, 127                 ; 0x7f
738   %set_next_high_bits = or i8 %clear_high_bit, 112 ; 0x70
739   %poison = shl nsw i8 %set_next_high_bits, 3
740   %cmp = icmp eq i8 %poison, 15
741   ret i1 %cmp
744 ; Shift-by-variable that produces poison is more complicated but still possible.
745 ; We guarantee that the shift will change the sign of the shifted value (and
746 ; therefore produce poison) by limiting its range from 1 to 3.
748 define i1 @eq_shl_by_variable_produces_poison(i8 %x) {
749 ; CHECK-LABEL: @eq_shl_by_variable_produces_poison(
750 ; CHECK-NEXT:    ret i1 false
752   %clear_high_bit = and i8 %x, 127                 ; 0x7f
753   %set_next_high_bits = or i8 %clear_high_bit, 112 ; 0x70
754   %notundef_shiftamt = and i8 %x, 3
755   %nonzero_shiftamt = or i8 %notundef_shiftamt, 1
756   %poison = shl nsw i8 %set_next_high_bits, %nonzero_shiftamt
757   %cmp = icmp eq i8 %poison, 15
758   ret i1 %cmp