1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instsimplify -S | FileCheck %s
3
4; Fold icmp with a constant operand.
5
6define i1 @tautological_ule(i8 %x) {
7; CHECK-LABEL: @tautological_ule(
8; CHECK-NEXT:    ret i1 true
9;
10  %cmp = icmp ule i8 %x, 255
11  ret i1 %cmp
12}
13
14define <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>
17;
18  %cmp = icmp ule <2 x i8> %x, <i8 255, i8 255>
19  ret <2 x i1> %cmp
20}
21
22define i1 @tautological_ugt(i8 %x) {
23; CHECK-LABEL: @tautological_ugt(
24; CHECK-NEXT:    ret i1 false
25;
26  %cmp = icmp ugt i8 %x, 255
27  ret i1 %cmp
28}
29
30define <2 x i1> @tautological_ugt_vec(<2 x i8> %x) {
31; CHECK-LABEL: @tautological_ugt_vec(
32; CHECK-NEXT:    ret <2 x i1> zeroinitializer
33;
34  %cmp = icmp ugt <2 x i8> %x, <i8 255, i8 255>
35  ret <2 x i1> %cmp
36}
37
38; 'urem x, C2' produces [0, C2)
39define i1 @urem3(i32 %X) {
40; CHECK-LABEL: @urem3(
41; CHECK-NEXT:    ret i1 true
42;
43  %A = urem i32 %X, 10
44  %B = icmp ult i32 %A, 15
45  ret i1 %B
46}
47
48define <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>
51;
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
55}
56
57;'srem x, C2' produces (-|C2|, |C2|)
58define i1 @srem1(i32 %X) {
59; CHECK-LABEL: @srem1(
60; CHECK-NEXT:    ret i1 false
61;
62  %A = srem i32 %X, -5
63  %B = icmp sgt i32 %A, 5
64  ret i1 %B
65}
66
67define <2 x i1> @srem1_vec(<2 x i32> %X) {
68; CHECK-LABEL: @srem1_vec(
69; CHECK-NEXT:    ret <2 x i1> zeroinitializer
70;
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
74}
75
76;'udiv C2, x' produces [0, C2]
77define i1 @udiv5(i32 %X) {
78; CHECK-LABEL: @udiv5(
79; CHECK-NEXT:    ret i1 false
80;
81  %A = udiv i32 123, %X
82  %C = icmp ugt i32 %A, 124
83  ret i1 %C
84}
85
86define <2 x i1> @udiv5_vec(<2 x i32> %X) {
87; CHECK-LABEL: @udiv5_vec(
88; CHECK-NEXT:    ret <2 x i1> zeroinitializer
89;
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
93}
94
95; 'udiv x, C2' produces [0, UINT_MAX / C2]
96define i1 @udiv1(i32 %X) {
97; CHECK-LABEL: @udiv1(
98; CHECK-NEXT:    ret i1 true
99;
100  %A = udiv i32 %X, 1000000
101  %B = icmp ult i32 %A, 5000
102  ret i1 %B
103}
104
105define <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>
108;
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
112}
113
114; 'sdiv C2, x' produces [-|C2|, |C2|]
115define i1 @compare_dividend(i32 %a) {
116; CHECK-LABEL: @compare_dividend(
117; CHECK-NEXT:    ret i1 false
118;
119  %div = sdiv i32 2, %a
120  %cmp = icmp eq i32 %div, 3
121  ret i1 %cmp
122}
123
124define <2 x i1> @compare_dividend_vec(<2 x i32> %a) {
125; CHECK-LABEL: @compare_dividend_vec(
126; CHECK-NEXT:    ret <2 x i1> zeroinitializer
127;
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
131}
132
133; 'sdiv x, C2' produces [INT_MIN / C2, INT_MAX / C2]
134;    where C2 != -1 and C2 != 0 and C2 != 1
135define i1 @sdiv1(i32 %X) {
136; CHECK-LABEL: @sdiv1(
137; CHECK-NEXT:    ret i1 true
138;
139  %A = sdiv i32 %X, 1000000
140  %B = icmp slt i32 %A, 3000
141  ret i1 %B
142}
143
144define <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>
147;
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
151}
152
153; 'shl nuw C2, x' produces [C2, C2 << CLZ(C2)]
154define i1 @shl5(i32 %X) {
155; CHECK-LABEL: @shl5(
156; CHECK-NEXT:    ret i1 true
157;
158  %sub = shl nuw i32 4, %X
159  %cmp = icmp ugt i32 %sub, 3
160  ret i1 %cmp
161}
162
163define <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>
166;
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
170}
171
172; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2]
173define i1 @shl2(i32 %X) {
174; CHECK-LABEL: @shl2(
175; CHECK-NEXT:    ret i1 false
176;
177  %sub = shl nsw i32 -1, %X
178  %cmp = icmp eq i32 %sub, 31
179  ret i1 %cmp
180}
181
182define <2 x i1> @shl2_vec(<2 x i32> %X) {
183; CHECK-LABEL: @shl2_vec(
184; CHECK-NEXT:    ret <2 x i1> zeroinitializer
185;
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
189}
190
191; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2]
192define i1 @shl4(i32 %X) {
193; CHECK-LABEL: @shl4(
194; CHECK-NEXT:    ret i1 true
195;
196  %sub = shl nsw i32 -1, %X
197  %cmp = icmp sle i32 %sub, -1
198  ret i1 %cmp
199}
200
201define <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>
204;
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
208}
209
210; 'shl nsw C2, x' produces [C2, C2 << CLZ(C2)-1]
211define i1 @icmp_shl_nsw_1(i64 %a) {
212; CHECK-LABEL: @icmp_shl_nsw_1(
213; CHECK-NEXT:    ret i1 true
214;
215  %shl = shl nsw i64 1, %a
216  %cmp = icmp sge i64 %shl, 0
217  ret i1 %cmp
218}
219
220define <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>
223;
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
227}
228
229; 'shl nsw C2, x' produces [C2 << CLO(C2)-1, C2]
230define i1 @icmp_shl_nsw_neg1(i64 %a) {
231; CHECK-LABEL: @icmp_shl_nsw_neg1(
232; CHECK-NEXT:    ret i1 false
233;
234  %shl = shl nsw i64 -1, %a
235  %cmp = icmp sge i64 %shl, 3
236  ret i1 %cmp
237}
238
239define <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
242;
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
246}
247
248; 'lshr x, C2' produces [0, UINT_MAX >> C2]
249define i1 @lshr2(i32 %x) {
250; CHECK-LABEL: @lshr2(
251; CHECK-NEXT:    ret i1 false
252;
253  %s = lshr i32 %x, 30
254  %c = icmp ugt i32 %s, 8
255  ret i1 %c
256}
257
258define <2 x i1> @lshr2_vec(<2 x i32> %x) {
259; CHECK-LABEL: @lshr2_vec(
260; CHECK-NEXT:    ret <2 x i1> zeroinitializer
261;
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
265}
266
267; 'lshr C2, x' produces [C2 >> (Width-1), C2]
268define i1 @exact_lshr_ugt_false(i32 %a) {
269; CHECK-LABEL: @exact_lshr_ugt_false(
270; CHECK-NEXT:    ret i1 false
271;
272  %shr = lshr exact i32 30, %a
273  %cmp = icmp ult i32 %shr, 15
274  ret i1 %cmp
275}
276
277define <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
280;
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
284}
285
286; 'lshr C2, x' produces [C2 >> (Width-1), C2]
287define i1 @lshr_sgt_false(i32 %a) {
288; CHECK-LABEL: @lshr_sgt_false(
289; CHECK-NEXT:    ret i1 false
290;
291  %shr = lshr i32 1, %a
292  %cmp = icmp sgt i32 %shr, 1
293  ret i1 %cmp
294}
295
296define <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
299;
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
303}
304
305; 'ashr x, C2' produces [INT_MIN >> C2, INT_MAX >> C2]
306define i1 @ashr2(i32 %x) {
307; CHECK-LABEL: @ashr2(
308; CHECK-NEXT:    ret i1 false
309;
310  %s = ashr i32 %x, 30
311  %c = icmp slt i32 %s, -5
312  ret i1 %c
313}
314
315define <2 x i1> @ashr2_vec(<2 x i32> %x) {
316; CHECK-LABEL: @ashr2_vec(
317; CHECK-NEXT:    ret <2 x i1> zeroinitializer
318;
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
322}
323
324; 'ashr C2, x' produces [C2, C2 >> (Width-1)]
325define i1 @ashr_sgt_false(i32 %a) {
326; CHECK-LABEL: @ashr_sgt_false(
327; CHECK-NEXT:    ret i1 false
328;
329  %shr = ashr i32 -30, %a
330  %cmp = icmp sgt i32 %shr, -1
331  ret i1 %cmp
332}
333
334define <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
337;
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
341}
342
343; 'ashr C2, x' produces [C2, C2 >> (Width-1)]
344define i1 @exact_ashr_sgt_false(i32 %a) {
345; CHECK-LABEL: @exact_ashr_sgt_false(
346; CHECK-NEXT:    ret i1 false
347;
348  %shr = ashr exact i32 -30, %a
349  %cmp = icmp sgt i32 %shr, -15
350  ret i1 %cmp
351}
352
353define <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
356;
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
360}
361
362; 'or x, C2' produces [C2, UINT_MAX]
363define i1 @or1(i32 %X) {
364; CHECK-LABEL: @or1(
365; CHECK-NEXT:    ret i1 false
366;
367  %A = or i32 %X, 62
368  %B = icmp ult i32 %A, 50
369  ret i1 %B
370}
371
372define <2 x i1> @or1_vec(<2 x i32> %X) {
373; CHECK-LABEL: @or1_vec(
374; CHECK-NEXT:    ret <2 x i1> zeroinitializer
375;
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
379}
380
381; Single bit OR.
382define 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]]
387;
388  %y = or i8 %x, 64
389  %z = icmp sge i8 %y, -64
390  ret i1 %z
391}
392
393define 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]]
398;
399  %y = or i8 %x, 64
400  %z = icmp sgt i8 %y, -64
401  ret i1 %z
402}
403
404; Multi bit OR.
405; 78 = 0b01001110; -50 = 0b11001110
406define 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]]
411;
412  %y = or i8 %x, 78
413  %z = icmp sge i8 %y, -50
414  ret i1 %z
415}
416
417define 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]]
422;
423  %y = or i8 %x, 78
424  %z = icmp sgt i8 %y, -50
425  ret i1 %z
426}
427
428; OR with sign bit.
429define i1 @or4_true(i8 %x) {
430; CHECK-LABEL: @or4_true(
431; CHECK-NEXT:    ret i1 true
432;
433  %y = or i8 %x, -64
434  %z = icmp sge i8 %y, -64
435  ret i1 %z
436}
437
438define 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]]
443;
444  %y = or i8 %x, -64
445  %z = icmp sgt i8 %y, -64
446  ret i1 %z
447}
448
449; If sign bit is set, signed & unsigned ranges are the same.
450define i1 @or5_true(i8 %x) {
451; CHECK-LABEL: @or5_true(
452; CHECK-NEXT:    ret i1 true
453;
454  %y = or i8 %x, -64
455  %z = icmp uge i8 %y, -64
456  ret i1 %z
457}
458
459define 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]]
464;
465  %y = or i8 %x, -64
466  %z = icmp ugt i8 %y, -64
467  ret i1 %z
468}
469
470; 'and x, C2' produces [0, C2]
471define i1 @and1(i32 %X) {
472; CHECK-LABEL: @and1(
473; CHECK-NEXT:    ret i1 false
474;
475  %A = and i32 %X, 62
476  %B = icmp ugt i32 %A, 70
477  ret i1 %B
478}
479
480define <2 x i1> @and1_vec(<2 x i32> %X) {
481; CHECK-LABEL: @and1_vec(
482; CHECK-NEXT:    ret <2 x i1> zeroinitializer
483;
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
487}
488
489; If the sign bit is not set, signed and unsigned ranges are the same.
490define i1 @and2(i32 %X) {
491; CHECK-LABEL: @and2(
492; CHECK-NEXT:    ret i1 false
493;
494  %A = and i32 %X, 62
495  %B = icmp sgt i32 %A, 70
496  ret i1 %B
497}
498
499; -75 = 0b10110101, 53 = 0b00110101
500define 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]]
505;
506  %y = and i8 %x, -75
507  %z = icmp sge i8 %y, -75
508  ret i1 %z
509}
510
511define 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]]
516;
517  %y = and i8 %x, -75
518  %z = icmp sgt i8 %y, -75
519  ret i1 %z
520}
521
522define 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]]
527;
528  %y = and i8 %x, -75
529  %z = icmp sle i8 %y, 53
530  ret i1 %z
531}
532
533define 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]]
538;
539  %y = and i8 %x, -75
540  %z = icmp slt i8 %y, 53
541  ret i1 %z
542}
543
544; 'add nuw x, C2' produces [C2, UINT_MAX]
545define i1 @tautological9(i32 %x) {
546; CHECK-LABEL: @tautological9(
547; CHECK-NEXT:    ret i1 true
548;
549  %add = add nuw i32 %x, 13
550  %cmp = icmp ne i32 %add, 12
551  ret i1 %cmp
552}
553
554define <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>
557;
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
561}
562
563; The upper bound of the 'add' is 0.
564
565define i1 @add_nsw_neg_const1(i32 %x) {
566; CHECK-LABEL: @add_nsw_neg_const1(
567; CHECK-NEXT:    ret i1 false
568;
569  %add = add nsw i32 %x, -2147483647
570  %cmp = icmp sgt i32 %add, 0
571  ret i1 %cmp
572}
573
574; InstCombine can fold this, but not InstSimplify.
575
576define 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]]
581;
582  %add = add nsw i32 %x, -2147483647
583  %cmp = icmp sgt i32 %add, -1
584  ret i1 %cmp
585}
586
587; The upper bound of the 'add' is 1 (move the constants to prove we're doing range-based analysis).
588
589define i1 @add_nsw_neg_const3(i32 %x) {
590; CHECK-LABEL: @add_nsw_neg_const3(
591; CHECK-NEXT:    ret i1 false
592;
593  %add = add nsw i32 %x, -2147483646
594  %cmp = icmp sgt i32 %add, 1
595  ret i1 %cmp
596}
597
598; InstCombine can fold this, but not InstSimplify.
599
600define 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]]
605;
606  %add = add nsw i32 %x, -2147483646
607  %cmp = icmp sgt i32 %add, 0
608  ret i1 %cmp
609}
610
611; The upper bound of the 'add' is 2147483647 - 42 = 2147483605 (move the constants again and try a different cmp predicate).
612
613define i1 @add_nsw_neg_const5(i32 %x) {
614; CHECK-LABEL: @add_nsw_neg_const5(
615; CHECK-NEXT:    ret i1 true
616;
617  %add = add nsw i32 %x, -42
618  %cmp = icmp ne i32 %add, 2147483606
619  ret i1 %cmp
620}
621
622; InstCombine can fold this, but not InstSimplify.
623
624define 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]]
629;
630  %add = add nsw i32 %x, -42
631  %cmp = icmp ne i32 %add, 2147483605
632  ret i1 %cmp
633}
634
635; The lower bound of the 'add' is -1.
636
637define i1 @add_nsw_pos_const1(i32 %x) {
638; CHECK-LABEL: @add_nsw_pos_const1(
639; CHECK-NEXT:    ret i1 false
640;
641  %add = add nsw i32 %x, 2147483647
642  %cmp = icmp slt i32 %add, -1
643  ret i1 %cmp
644}
645
646; InstCombine can fold this, but not InstSimplify.
647
648define 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]]
653;
654  %add = add nsw i32 %x, 2147483647
655  %cmp = icmp slt i32 %add, 0
656  ret i1 %cmp
657}
658
659; The lower bound of the 'add' is -2 (move the constants to prove we're doing range-based analysis).
660
661define i1 @add_nsw_pos_const3(i32 %x) {
662; CHECK-LABEL: @add_nsw_pos_const3(
663; CHECK-NEXT:    ret i1 false
664;
665  %add = add nsw i32 %x, 2147483646
666  %cmp = icmp slt i32 %add, -2
667  ret i1 %cmp
668}
669
670; InstCombine can fold this, but not InstSimplify.
671
672define 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]]
677;
678  %add = add nsw i32 %x, 2147483646
679  %cmp = icmp slt i32 %add, -1
680  ret i1 %cmp
681}
682
683; The lower bound of the 'add' is -2147483648 + 42 = -2147483606 (move the constants again and change the cmp predicate).
684
685define i1 @add_nsw_pos_const5(i32 %x) {
686; CHECK-LABEL: @add_nsw_pos_const5(
687; CHECK-NEXT:    ret i1 false
688;
689  %add = add nsw i32 %x, 42
690  %cmp = icmp eq i32 %add, -2147483607
691  ret i1 %cmp
692}
693
694; InstCombine can fold this, but not InstSimplify.
695
696define 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]]
701;
702  %add = add nsw i32 %x, 42
703  %cmp = icmp eq i32 %add, -2147483606
704  ret i1 %cmp
705}
706
707; Verify that vectors work too.
708
709define <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>
712;
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
716}
717
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.
720
721define i1 @ne_shl_by_constant_produces_poison(i8 %x) {
722; CHECK-LABEL: @ne_shl_by_constant_produces_poison(
723; CHECK-NEXT:    ret i1 true
724;
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
731}
732
733define i1 @eq_shl_by_constant_produces_poison(i8 %x) {
734; CHECK-LABEL: @eq_shl_by_constant_produces_poison(
735; CHECK-NEXT:    ret i1 false
736;
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
742}
743
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.
747
748define i1 @eq_shl_by_variable_produces_poison(i8 %x) {
749; CHECK-LABEL: @eq_shl_by_variable_produces_poison(
750; CHECK-NEXT:    ret i1 false
751;
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
759}
760
761