xref: /llvm-project/llvm/test/Transforms/InstCombine/icmp-add.ll (revision 63d4e0fb66b75dd1c60acaa81ff8f8a4327cffcc)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4declare void @use(i32)
5
6; PR1949
7
8; negative test for zext/zext additions with i16
9define i1 @cvt_icmp_0_zext_plus_zext_eq_i16(i16 %arg, i16 %arg1) {
10; CHECK-LABEL: @cvt_icmp_0_zext_plus_zext_eq_i16(
11; CHECK-NEXT:  bb:
12; CHECK-NEXT:    [[TMP0:%.*]] = or i16 [[ARG1:%.*]], [[ARG:%.*]]
13; CHECK-NEXT:    [[I4:%.*]] = icmp eq i16 [[TMP0]], 0
14; CHECK-NEXT:    ret i1 [[I4]]
15;
16bb:
17  %i = zext i16 %arg to i32
18  %i2 = zext i16 %arg1 to i32
19  %i3 = add i32 %i2, %i
20  %i4 = icmp eq i32 %i3, 0
21  ret i1 %i4
22}
23
24; negative test for zext/zext addtions with i8
25define i1 @cvt_icmp_0_zext_plus_zext_eq_i8(i8 %arg, i8 %arg1) {
26; CHECK-LABEL: @cvt_icmp_0_zext_plus_zext_eq_i8(
27; CHECK-NEXT:  bb:
28; CHECK-NEXT:    [[TMP0:%.*]] = or i8 [[ARG1:%.*]], [[ARG:%.*]]
29; CHECK-NEXT:    [[I4:%.*]] = icmp eq i8 [[TMP0]], 0
30; CHECK-NEXT:    ret i1 [[I4]]
31;
32bb:
33  %i = zext i8 %arg to i32
34  %i2 = zext i8 %arg1 to i32
35  %i3 = add i32 %i2, %i
36  %i4 = icmp eq i32 %i3, 0
37  ret i1 %i4
38}
39
40; start of positive tests
41define i1 @cvt_icmp_neg_2_zext_plus_zext_eq(i1 %arg, i1 %arg1) {
42; CHECK-LABEL: @cvt_icmp_neg_2_zext_plus_zext_eq(
43; CHECK-NEXT:  bb:
44; CHECK-NEXT:    ret i1 false
45;
46bb:
47  %i = zext i1 %arg to i32
48  %i2 = zext i1 %arg1 to i32
49  %i3 = add i32 %i2, %i
50  %i4 = icmp eq i32 %i3, -2
51  ret i1 %i4
52}
53
54define i1 @cvt_icmp_neg_1_zext_plus_zext_eq(i1 %arg, i1 %arg1) {
55; CHECK-LABEL: @cvt_icmp_neg_1_zext_plus_zext_eq(
56; CHECK-NEXT:  bb:
57; CHECK-NEXT:    ret i1 false
58;
59bb:
60  %i = zext i1 %arg to i32
61  %i2 = zext i1 %arg1 to i32
62  %i3 = add i32 %i2, %i
63  %i4 = icmp eq i32 %i3, -1
64  ret i1 %i4
65}
66
67define i1 @cvt_icmp_0_zext_plus_zext_eq(i1 %arg, i1 %arg1) {
68; CHECK-LABEL: @cvt_icmp_0_zext_plus_zext_eq(
69; CHECK-NEXT:  bb:
70; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
71; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
72; CHECK-NEXT:    ret i1 [[I4]]
73;
74bb:
75  %i = zext i1 %arg to i32
76  %i2 = zext i1 %arg1 to i32
77  %i3 = add i32 %i2, %i
78  %i4 = icmp eq i32 %i3, 0
79  ret i1 %i4
80}
81
82define i1 @cvt_icmp_0_zext_plus_zext_eq_i2(i1 %a, i1 %b) {
83; CHECK-LABEL: @cvt_icmp_0_zext_plus_zext_eq_i2(
84; CHECK-NEXT:    [[TMP1:%.*]] = or i1 [[A:%.*]], [[B:%.*]]
85; CHECK-NEXT:    [[CMP:%.*]] = xor i1 [[TMP1]], true
86; CHECK-NEXT:    ret i1 [[CMP]]
87;
88  %a.ext = zext i1 %a to i2
89  %b.ext = zext i1 %b to i2
90  %add = add i2 %a.ext, %b.ext
91  %cmp = icmp eq i2 %add, 0
92  ret i1 %cmp
93}
94
95define i1 @cvt_icmp_1_zext_plus_zext_eq(i1 %arg, i1 %arg1) {
96; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_eq(
97; CHECK-NEXT:  bb:
98; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
99; CHECK-NEXT:    ret i1 [[I4]]
100;
101bb:
102  %i = zext i1 %arg to i32
103  %i2 = zext i1 %arg1 to i32
104  %i3 = add i32 %i2, %i
105  %i4 = icmp eq i32 %i3, 1
106  ret i1 %i4
107}
108
109define <2 x i1> @cvt_icmp_1_zext_plus_zext_eq_vec(<2 x i1> %arg, <2 x i1> %arg1) {
110; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_eq_vec(
111; CHECK-NEXT:  bb:
112; CHECK-NEXT:    [[I4:%.*]] = xor <2 x i1> [[ARG1:%.*]], [[ARG:%.*]]
113; CHECK-NEXT:    ret <2 x i1> [[I4]]
114;
115bb:
116  %i = zext <2 x i1> %arg to <2 x i32>
117  %i2 = zext <2 x i1> %arg1 to <2 x i32>
118  %i3 = add <2 x i32> %i2, %i
119  %i4 = icmp eq <2 x i32> %i3, <i32 1, i32 1>
120  ret <2 x i1> %i4
121}
122
123define i1 @cvt_icmp_2_zext_plus_zext_eq(i1 %arg, i1 %arg1) {
124; CHECK-LABEL: @cvt_icmp_2_zext_plus_zext_eq(
125; CHECK-NEXT:  bb:
126; CHECK-NEXT:    [[T:%.*]] = and i1 [[ARG:%.*]], [[ARG1:%.*]]
127; CHECK-NEXT:    ret i1 [[T]]
128;
129bb:
130  %i = zext i1 %arg to i32
131  %i2 = zext i1 %arg1 to i32
132  %i3 = add i32 %i, %i2
133  %t = icmp eq i32 %i3, 2
134  ret i1 %t
135}
136
137define i1 @cvt_icmp_neg_2_sext_plus_sext_eq(i1 %arg, i1 %arg1) {
138; CHECK-LABEL: @cvt_icmp_neg_2_sext_plus_sext_eq(
139; CHECK-NEXT:  bb:
140; CHECK-NEXT:    [[T:%.*]] = and i1 [[ARG:%.*]], [[ARG1:%.*]]
141; CHECK-NEXT:    ret i1 [[T]]
142;
143bb:
144  %i = sext i1 %arg to i32
145  %i2 = sext i1 %arg1 to i32
146  %i3 = add i32 %i, %i2
147  %t = icmp eq i32 %i3, -2
148  ret i1 %t
149}
150
151define i1 @cvt_icmp_neg_1_sext_plus_sext_eq(i1 %arg, i1 %arg1) {
152; CHECK-LABEL: @cvt_icmp_neg_1_sext_plus_sext_eq(
153; CHECK-NEXT:  bb:
154; CHECK-NEXT:    [[T:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]]
155; CHECK-NEXT:    ret i1 [[T]]
156;
157bb:
158  %i = sext i1 %arg to i32
159  %i2 = sext i1 %arg1 to i32
160  %i3 = add i32 %i, %i2
161  %t = icmp eq i32 %i3, -1
162  ret i1 %t
163}
164
165define i1 @cvt_icmp_0_sext_plus_sext_eq(i1 %arg, i1 %arg1) {
166; CHECK-LABEL: @cvt_icmp_0_sext_plus_sext_eq(
167; CHECK-NEXT:  bb:
168; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[ARG:%.*]], [[ARG1:%.*]]
169; CHECK-NEXT:    [[T:%.*]] = xor i1 [[TMP0]], true
170; CHECK-NEXT:    ret i1 [[T]]
171;
172bb:
173  %i = sext i1 %arg to i32
174  %i2 = sext i1 %arg1 to i32
175  %i3 = add i32 %i, %i2
176  %t = icmp eq i32 %i3, 0
177  ret i1 %t
178}
179
180define i1 @cvt_icmp_1_sext_plus_sext_eq(i1 %arg, i1 %arg1) {
181; CHECK-LABEL: @cvt_icmp_1_sext_plus_sext_eq(
182; CHECK-NEXT:  bb:
183; CHECK-NEXT:    ret i1 false
184;
185bb:
186  %i = sext i1 %arg to i32
187  %i2 = sext i1 %arg1 to i32
188  %i3 = add i32 %i, %i2
189  %t = icmp eq i32 %i3, 1
190  ret i1 %t
191}
192
193define i1 @cvt_icmp_2_sext_plus_sext_eq(i1 %arg, i1 %arg1) {
194; CHECK-LABEL: @cvt_icmp_2_sext_plus_sext_eq(
195; CHECK-NEXT:  bb:
196; CHECK-NEXT:    ret i1 false
197;
198bb:
199  %i = sext i1 %arg to i32
200  %i2 = sext i1 %arg1 to i32
201  %i3 = add i32 %i, %i2
202  %t = icmp eq i32 %i3, 2
203  ret i1 %t
204}
205
206define i1 @cvt_icmp_neg_2_sext_plus_zext_eq(i1 %arg, i1 %arg1) {
207; CHECK-LABEL: @cvt_icmp_neg_2_sext_plus_zext_eq(
208; CHECK-NEXT:  bb:
209; CHECK-NEXT:    ret i1 false
210;
211bb:
212  %i = sext i1 %arg to i32
213  %i2 = zext i1 %arg1 to i32
214  %i3 = add i32 %i, %i2
215  %t = icmp eq i32 %i3, -2
216  ret i1 %t
217}
218
219define i1 @cvt_icmp_neg_1_sext_plus_zext_eq(i1 %arg, i1 %arg1) {
220; CHECK-LABEL: @cvt_icmp_neg_1_sext_plus_zext_eq(
221; CHECK-NEXT:  bb:
222; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
223; CHECK-NEXT:    [[T:%.*]] = and i1 [[ARG:%.*]], [[TMP0]]
224; CHECK-NEXT:    ret i1 [[T]]
225;
226bb:
227  %i = sext i1 %arg to i32
228  %i2 = zext i1 %arg1 to i32
229  %i3 = add i32 %i, %i2
230  %t = icmp eq i32 %i3, -1
231  ret i1 %t
232}
233
234define i1 @cvt_icmp_0_sext_plus_zext_eq(i1 %arg, i1 %arg1) {
235; CHECK-LABEL: @cvt_icmp_0_sext_plus_zext_eq(
236; CHECK-NEXT:  bb:
237; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]]
238; CHECK-NEXT:    [[T:%.*]] = xor i1 [[TMP0]], true
239; CHECK-NEXT:    ret i1 [[T]]
240;
241bb:
242  %i = sext i1 %arg to i32
243  %i2 = zext i1 %arg1 to i32
244  %i3 = add i32 %i, %i2
245  %t = icmp eq i32 %i3, 0
246  ret i1 %t
247}
248
249define i1 @cvt_icmp_1_sext_plus_zext_eq(i1 %arg, i1 %arg1) {
250; CHECK-LABEL: @cvt_icmp_1_sext_plus_zext_eq(
251; CHECK-NEXT:  bb:
252; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
253; CHECK-NEXT:    [[T:%.*]] = and i1 [[ARG1:%.*]], [[TMP0]]
254; CHECK-NEXT:    ret i1 [[T]]
255;
256bb:
257  %i = sext i1 %arg to i32
258  %i2 = zext i1 %arg1 to i32
259  %i3 = add i32 %i, %i2
260  %t = icmp eq i32 %i3, 1
261  ret i1 %t
262}
263
264define i1 @cvt_icmp_2_sext_plus_zext_eq(i1 %arg, i1 %arg1) {
265; CHECK-LABEL: @cvt_icmp_2_sext_plus_zext_eq(
266; CHECK-NEXT:  bb:
267; CHECK-NEXT:    ret i1 false
268;
269bb:
270  %i = sext i1 %arg to i32
271  %i2 = zext i1 %arg1 to i32
272  %i3 = add i32 %i, %i2
273  %t = icmp eq i32 %i3, 2
274  ret i1 %t
275}
276
277define i1 @cvt_icmp_neg_2_zext_plus_zext_ne(i1 %arg, i1 %arg1) {
278; CHECK-LABEL: @cvt_icmp_neg_2_zext_plus_zext_ne(
279; CHECK-NEXT:  bb:
280; CHECK-NEXT:    ret i1 true
281;
282bb:
283  %i = zext i1 %arg to i32
284  %i2 = zext i1 %arg1 to i32
285  %i3 = add i32 %i2, %i
286  %i4 = icmp ne i32 %i3, -2
287  ret i1 %i4
288}
289
290define i1 @cvt_icmp_neg_1_zext_plus_zext_ne(i1 %arg, i1 %arg1) {
291; CHECK-LABEL: @cvt_icmp_neg_1_zext_plus_zext_ne(
292; CHECK-NEXT:  bb:
293; CHECK-NEXT:    ret i1 true
294;
295bb:
296  %i = zext i1 %arg to i32
297  %i2 = zext i1 %arg1 to i32
298  %i3 = add i32 %i2, %i
299  %i4 = icmp ne i32 %i3, -1
300  ret i1 %i4
301}
302
303define i1 @cvt_icmp_0_zext_plus_zext_ne(i1 %arg, i1 %arg1) {
304; CHECK-LABEL: @cvt_icmp_0_zext_plus_zext_ne(
305; CHECK-NEXT:  bb:
306; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
307; CHECK-NEXT:    ret i1 [[I4]]
308;
309bb:
310  %i = zext i1 %arg to i32
311  %i2 = zext i1 %arg1 to i32
312  %i3 = add i32 %i2, %i
313  %i4 = icmp ne i32 %i3, 0
314  ret i1 %i4
315}
316
317define i1 @cvt_icmp_1_zext_plus_zext_ne(i1 %arg, i1 %arg1) {
318; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_ne(
319; CHECK-NEXT:  bb:
320; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
321; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
322; CHECK-NEXT:    ret i1 [[I4]]
323;
324bb:
325  %i = zext i1 %arg to i32
326  %i2 = zext i1 %arg1 to i32
327  %i3 = add i32 %i2, %i
328  %i4 = icmp ne i32 %i3, 1
329  ret i1 %i4
330}
331
332define i1 @cvt_icmp_1_zext_plus_zext_ne_extra_use_1(i1 %arg, i1 %arg1) {
333; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_ne_extra_use_1(
334; CHECK-NEXT:  bb:
335; CHECK-NEXT:    [[I:%.*]] = zext i1 [[ARG:%.*]] to i32
336; CHECK-NEXT:    [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32
337; CHECK-NEXT:    [[I3:%.*]] = add nuw nsw i32 [[I2]], [[I]]
338; CHECK-NEXT:    call void @use(i32 [[I3]])
339; CHECK-NEXT:    [[I4:%.*]] = icmp ne i32 [[I3]], 1
340; CHECK-NEXT:    ret i1 [[I4]]
341;
342bb:
343  %i = zext i1 %arg to i32
344  %i2 = zext i1 %arg1 to i32
345  %i3 = add i32 %i2, %i
346  call void @use(i32 %i3)
347  %i4 = icmp ne i32 %i3, 1
348  ret i1 %i4
349}
350
351define i1 @cvt_icmp_1_zext_plus_zext_ne_extra_use_2(i1 %arg, i1 %arg1) {
352; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_ne_extra_use_2(
353; CHECK-NEXT:  bb:
354; CHECK-NEXT:    [[I:%.*]] = zext i1 [[ARG:%.*]] to i32
355; CHECK-NEXT:    call void @use(i32 [[I]])
356; CHECK-NEXT:    [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32
357; CHECK-NEXT:    call void @use(i32 [[I2]])
358; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1]], [[ARG]]
359; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
360; CHECK-NEXT:    ret i1 [[I4]]
361;
362bb:
363  %i = zext i1 %arg to i32
364  call void @use(i32 %i)
365  %i2 = zext i1 %arg1 to i32
366  call void @use(i32 %i2)
367  %i3 = add i32 %i2, %i
368  %i4 = icmp ne i32 %i3, 1
369  ret i1 %i4
370}
371
372define i1 @cvt_icmp_2_zext_plus_zext_ne(i1 %arg, i1 %arg1) {
373; CHECK-LABEL: @cvt_icmp_2_zext_plus_zext_ne(
374; CHECK-NEXT:  bb:
375; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[ARG:%.*]], [[ARG1:%.*]]
376; CHECK-NEXT:    [[T:%.*]] = xor i1 [[TMP0]], true
377; CHECK-NEXT:    ret i1 [[T]]
378;
379bb:
380  %i = zext i1 %arg to i32
381  %i2 = zext i1 %arg1 to i32
382  %i3 = add i32 %i, %i2
383  %t = icmp ne i32 %i3, 2
384  ret i1 %t
385}
386
387define i1 @cvt_icmp_neg_2_sext_plus_sext_ne(i1 %arg, i1 %arg1) {
388; CHECK-LABEL: @cvt_icmp_neg_2_sext_plus_sext_ne(
389; CHECK-NEXT:  bb:
390; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[ARG:%.*]], [[ARG1:%.*]]
391; CHECK-NEXT:    [[T:%.*]] = xor i1 [[TMP0]], true
392; CHECK-NEXT:    ret i1 [[T]]
393;
394bb:
395  %i = sext i1 %arg to i32
396  %i2 = sext i1 %arg1 to i32
397  %i3 = add i32 %i, %i2
398  %t = icmp ne i32 %i3, -2
399  ret i1 %t
400}
401
402define i1 @cvt_icmp_neg_1_sext_plus_sext_ne(i1 %arg, i1 %arg1) {
403; CHECK-LABEL: @cvt_icmp_neg_1_sext_plus_sext_ne(
404; CHECK-NEXT:  bb:
405; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]]
406; CHECK-NEXT:    [[T:%.*]] = xor i1 [[TMP0]], true
407; CHECK-NEXT:    ret i1 [[T]]
408;
409bb:
410  %i = sext i1 %arg to i32
411  %i2 = sext i1 %arg1 to i32
412  %i3 = add i32 %i, %i2
413  %t = icmp ne i32 %i3, -1
414  ret i1 %t
415}
416
417define i1 @cvt_icmp_0_sext_plus_sext_ne(i1 %arg, i1 %arg1) {
418; CHECK-LABEL: @cvt_icmp_0_sext_plus_sext_ne(
419; CHECK-NEXT:  bb:
420; CHECK-NEXT:    [[T:%.*]] = or i1 [[ARG:%.*]], [[ARG1:%.*]]
421; CHECK-NEXT:    ret i1 [[T]]
422;
423bb:
424  %i = sext i1 %arg to i32
425  %i2 = sext i1 %arg1 to i32
426  %i3 = add i32 %i, %i2
427  %t = icmp ne i32 %i3, 0
428  ret i1 %t
429}
430
431define i1 @cvt_icmp_1_sext_plus_sext_ne(i1 %arg, i1 %arg1) {
432; CHECK-LABEL: @cvt_icmp_1_sext_plus_sext_ne(
433; CHECK-NEXT:  bb:
434; CHECK-NEXT:    ret i1 true
435;
436bb:
437  %i = sext i1 %arg to i32
438  %i2 = sext i1 %arg1 to i32
439  %i3 = add i32 %i, %i2
440  %t = icmp ne i32 %i3, 1
441  ret i1 %t
442}
443
444define i1 @cvt_icmp_2_sext_plus_sext_ne(i1 %arg, i1 %arg1) {
445; CHECK-LABEL: @cvt_icmp_2_sext_plus_sext_ne(
446; CHECK-NEXT:  bb:
447; CHECK-NEXT:    ret i1 true
448;
449bb:
450  %i = sext i1 %arg to i32
451  %i2 = sext i1 %arg1 to i32
452  %i3 = add i32 %i, %i2
453  %t = icmp ne i32 %i3, 2
454  ret i1 %t
455}
456
457define i1 @cvt_icmp_neg_2_sext_plus_zext_ne(i1 %arg, i1 %arg1) {
458; CHECK-LABEL: @cvt_icmp_neg_2_sext_plus_zext_ne(
459; CHECK-NEXT:  bb:
460; CHECK-NEXT:    ret i1 true
461;
462bb:
463  %i = sext i1 %arg to i32
464  %i2 = zext i1 %arg1 to i32
465  %i3 = add i32 %i, %i2
466  %t = icmp ne i32 %i3, -2
467  ret i1 %t
468}
469
470define i1 @cvt_icmp_neg_1_sext_plus_zext_ne(i1 %arg, i1 %arg1) {
471; CHECK-LABEL: @cvt_icmp_neg_1_sext_plus_zext_ne(
472; CHECK-NEXT:  bb:
473; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
474; CHECK-NEXT:    [[T:%.*]] = or i1 [[ARG1:%.*]], [[TMP0]]
475; CHECK-NEXT:    ret i1 [[T]]
476;
477bb:
478  %i = sext i1 %arg to i32
479  %i2 = zext i1 %arg1 to i32
480  %i3 = add i32 %i, %i2
481  %t = icmp ne i32 %i3, -1
482  ret i1 %t
483}
484
485define i1 @cvt_icmp_0_sext_plus_zext_ne(i1 %arg, i1 %arg1) {
486; CHECK-LABEL: @cvt_icmp_0_sext_plus_zext_ne(
487; CHECK-NEXT:  bb:
488; CHECK-NEXT:    [[T:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]]
489; CHECK-NEXT:    ret i1 [[T]]
490;
491bb:
492  %i = sext i1 %arg to i32
493  %i2 = zext i1 %arg1 to i32
494  %i3 = add i32 %i, %i2
495  %t = icmp ne i32 %i3, 0
496  ret i1 %t
497}
498
499define i1 @cvt_icmp_1_sext_plus_zext_ne(i1 %arg, i1 %arg1) {
500; CHECK-LABEL: @cvt_icmp_1_sext_plus_zext_ne(
501; CHECK-NEXT:  bb:
502; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
503; CHECK-NEXT:    [[T:%.*]] = or i1 [[ARG:%.*]], [[TMP0]]
504; CHECK-NEXT:    ret i1 [[T]]
505;
506bb:
507  %i = sext i1 %arg to i32
508  %i2 = zext i1 %arg1 to i32
509  %i3 = add i32 %i, %i2
510  %t = icmp ne i32 %i3, 1
511  ret i1 %t
512}
513
514define i1 @cvt_icmp_2_sext_plus_zext_ne(i1 %arg, i1 %arg1) {
515; CHECK-LABEL: @cvt_icmp_2_sext_plus_zext_ne(
516; CHECK-NEXT:  bb:
517; CHECK-NEXT:    ret i1 true
518;
519bb:
520  %i = sext i1 %arg to i32
521  %i2 = zext i1 %arg1 to i32
522  %i3 = add i32 %i, %i2
523  %t = icmp ne i32 %i3, 2
524  ret i1 %t
525}
526
527define <2 x i1> @cvt_icmp_2_sext_plus_zext_ne_vec(<2 x i1> %arg, <2 x i1> %arg1) {
528; CHECK-LABEL: @cvt_icmp_2_sext_plus_zext_ne_vec(
529; CHECK-NEXT:  bb:
530; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
531;
532bb:
533  %i = sext <2 x i1> %arg to <2 x i32>
534  %i2 = zext <2 x i1> %arg1 to <2 x i32>
535  %i3 = add nsw <2 x i32> %i, %i2
536  %i4 = icmp ne <2 x i32> %i3, <i32 2, i32 2>
537  ret <2 x i1> %i4
538}
539
540; test if zext i1 X + sext i1 Y converted to sext i1 X + zext i1 Y
541; and then processed
542
543define i1 @cvt_icmp_neg_2_zext_plus_sext_eq(i1 %arg, i1 %arg1) {
544; CHECK-LABEL: @cvt_icmp_neg_2_zext_plus_sext_eq(
545; CHECK-NEXT:  bb:
546; CHECK-NEXT:    ret i1 false
547;
548bb:
549  %i = zext i1 %arg to i32
550  %i2 = sext i1 %arg1 to i32
551  %i3 = add i32 %i, %i2
552  %t = icmp eq i32 %i3, -2
553  ret i1 %t
554}
555
556define <2 x i1> @cvt_icmp_neg_2_zext_plus_sext_eq_vec(<2 x i1> %arg, <2 x i1> %arg1) {
557; CHECK-LABEL: @cvt_icmp_neg_2_zext_plus_sext_eq_vec(
558; CHECK-NEXT:  bb:
559; CHECK-NEXT:    ret <2 x i1> zeroinitializer
560;
561bb:
562  %i = zext <2 x i1> %arg to <2 x i32>
563  %i2 = sext <2 x i1> %arg1 to <2 x i32>
564  %i3 = add nsw <2 x i32> %i2, %i
565  %i4 = icmp eq <2 x i32> %i3, <i32 2, i32 2>
566  ret <2 x i1> %i4
567}
568
569define i1 @cvt_icmp_neg_1_zext_plus_sext_eq(i1 %arg, i1 %arg1) {
570; CHECK-LABEL: @cvt_icmp_neg_1_zext_plus_sext_eq(
571; CHECK-NEXT:  bb:
572; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
573; CHECK-NEXT:    [[T:%.*]] = and i1 [[ARG1:%.*]], [[TMP0]]
574; CHECK-NEXT:    ret i1 [[T]]
575;
576bb:
577  %i = zext i1 %arg to i32
578  %i2 = sext i1 %arg1 to i32
579  %i3 = add i32 %i, %i2
580  %t = icmp eq i32 %i3, -1
581  ret i1 %t
582}
583
584define i1 @cvt_icmp_0_zext_plus_sext_eq(i1 %arg, i1 %arg1) {
585; CHECK-LABEL: @cvt_icmp_0_zext_plus_sext_eq(
586; CHECK-NEXT:  bb:
587; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]]
588; CHECK-NEXT:    [[T:%.*]] = xor i1 [[TMP0]], true
589; CHECK-NEXT:    ret i1 [[T]]
590;
591bb:
592  %i = zext i1 %arg to i32
593  %i2 = sext i1 %arg1 to i32
594  %i3 = add i32 %i, %i2
595  %t = icmp eq i32 %i3, 0
596  ret i1 %t
597}
598
599define i1 @cvt_icmp_1_zext_plus_sext_eq(i1 %arg, i1 %arg1) {
600; CHECK-LABEL: @cvt_icmp_1_zext_plus_sext_eq(
601; CHECK-NEXT:  bb:
602; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
603; CHECK-NEXT:    [[T:%.*]] = and i1 [[ARG:%.*]], [[TMP0]]
604; CHECK-NEXT:    ret i1 [[T]]
605;
606bb:
607  %i = zext i1 %arg to i32
608  %i2 = sext i1 %arg1 to i32
609  %i3 = add i32 %i, %i2
610  %t = icmp eq i32 %i3, 1
611  ret i1 %t
612}
613
614define i1 @cvt_icmp_2_zext_plus_sext_eq(i1 %arg, i1 %arg1) {
615; CHECK-LABEL: @cvt_icmp_2_zext_plus_sext_eq(
616; CHECK-NEXT:  bb:
617; CHECK-NEXT:    ret i1 false
618;
619bb:
620  %i = zext i1 %arg to i32
621  %i2 = sext i1 %arg1 to i32
622  %i3 = add i32 %i, %i2
623  %t = icmp eq i32 %i3, 2
624  ret i1 %t
625}
626
627define i1 @cvt_icmp_neg_2_zext_plus_sext_ne(i1 %arg, i1 %arg1) {
628; CHECK-LABEL: @cvt_icmp_neg_2_zext_plus_sext_ne(
629; CHECK-NEXT:  bb:
630; CHECK-NEXT:    ret i1 true
631;
632bb:
633  %i = zext i1 %arg to i32
634  %i2 = sext i1 %arg1 to i32
635  %i3 = add i32 %i, %i2
636  %t = icmp ne i32 %i3, -2
637  ret i1 %t
638}
639
640define i1 @cvt_icmp_neg_1_zext_plus_sext_ne(i1 %arg, i1 %arg1) {
641; CHECK-LABEL: @cvt_icmp_neg_1_zext_plus_sext_ne(
642; CHECK-NEXT:  bb:
643; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
644; CHECK-NEXT:    [[T:%.*]] = or i1 [[ARG:%.*]], [[TMP0]]
645; CHECK-NEXT:    ret i1 [[T]]
646;
647bb:
648  %i = zext i1 %arg to i32
649  %i2 = sext i1 %arg1 to i32
650  %i3 = add i32 %i, %i2
651  %t = icmp ne i32 %i3, -1
652  ret i1 %t
653}
654
655define i1 @cvt_icmp_0_zext_plus_sext_ne(i1 %arg, i1 %arg1) {
656; CHECK-LABEL: @cvt_icmp_0_zext_plus_sext_ne(
657; CHECK-NEXT:  bb:
658; CHECK-NEXT:    [[T:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]]
659; CHECK-NEXT:    ret i1 [[T]]
660;
661bb:
662  %i = zext i1 %arg to i32
663  %i2 = sext i1 %arg1 to i32
664  %i3 = add i32 %i, %i2
665  %t = icmp ne i32 %i3, 0
666  ret i1 %t
667}
668
669define i1 @cvt_icmp_1_zext_plus_sext_ne(i1 %arg, i1 %arg1) {
670; CHECK-LABEL: @cvt_icmp_1_zext_plus_sext_ne(
671; CHECK-NEXT:  bb:
672; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
673; CHECK-NEXT:    [[T:%.*]] = or i1 [[ARG1:%.*]], [[TMP0]]
674; CHECK-NEXT:    ret i1 [[T]]
675;
676bb:
677  %i = zext i1 %arg to i32
678  %i2 = sext i1 %arg1 to i32
679  %i3 = add i32 %i, %i2
680  %t = icmp ne i32 %i3, 1
681  ret i1 %t
682}
683
684define i1 @cvt_icmp_2_zext_plus_sext_ne(i1 %arg, i1 %arg1) {
685; CHECK-LABEL: @cvt_icmp_2_zext_plus_sext_ne(
686; CHECK-NEXT:  bb:
687; CHECK-NEXT:    ret i1 true
688;
689bb:
690  %i = zext i1 %arg to i32
691  %i2 = sext i1 %arg1 to i32
692  %i3 = add i32 %i, %i2
693  %t = icmp ne i32 %i3, 2
694  ret i1 %t
695}
696
697; test zext/zext additions with more than one use
698
699define i1 @test_cvt_icmp1(i1 %arg, i1 %arg1, ptr %p) {
700; CHECK-LABEL: @test_cvt_icmp1(
701; CHECK-NEXT:  bb:
702; CHECK-NEXT:    [[I2:%.*]] = zext i1 [[ARG:%.*]] to i32
703; CHECK-NEXT:    store i32 [[I2]], ptr [[P:%.*]], align 4
704; CHECK-NEXT:    ret i1 false
705;
706bb:
707  %i = zext i1 %arg to i32
708  %i2 = zext i1 %arg to i32
709  store i32 %i2, ptr %p
710  %i3 = load i32, ptr %p
711  %i4 = add i32 %i3, %i
712  %t = icmp eq i32 %i4, 1
713  ret i1 %t
714}
715
716define i1 @test_cvt_icmp2(i1 %arg, i1 %arg1, ptr %p) {
717; CHECK-LABEL: @test_cvt_icmp2(
718; CHECK-NEXT:  bb:
719; CHECK-NEXT:    [[I2:%.*]] = zext i1 [[ARG:%.*]] to i32
720; CHECK-NEXT:    store i32 [[I2]], ptr [[P:%.*]], align 4
721; CHECK-NEXT:    ret i1 false
722;
723bb:
724  %i = sext i1 %arg to i32
725  %i2 = zext i1 %arg to i32
726  store i32 %i2, ptr %p
727  %i3 = load i32, ptr %p
728  %i4 = add i32 %i3, %i
729  %t = icmp eq i32 %i4, 1
730  ret i1 %t
731}
732
733; tests for ult
734define i1 @test_zext_zext_cvt_neg_2_ult_icmp(i1 %arg, i1 %arg1) {
735; CHECK-LABEL: @test_zext_zext_cvt_neg_2_ult_icmp(
736; CHECK-NEXT:  bb:
737; CHECK-NEXT:    ret i1 true
738;
739bb:
740  %i = zext i1 %arg to i32
741  %i2 = zext i1 %arg1 to i32
742  %i3 = add i32 %i2, %i
743  %i4 = icmp ult i32 %i3, -2
744  ret i1 %i4
745}
746
747define i1 @test_zext_zext_cvt_neg_1_ult_icmp(i1 %arg, i1 %arg1) {
748; CHECK-LABEL: @test_zext_zext_cvt_neg_1_ult_icmp(
749; CHECK-NEXT:  bb:
750; CHECK-NEXT:    ret i1 true
751;
752bb:
753  %i = zext i1 %arg to i32
754  %i2 = zext i1 %arg1 to i32
755  %i3 = add i32 %i2, %i
756  %i4 = icmp ult i32 %i3, -1
757  ret i1 %i4
758}
759
760define i1 @test_zext_zext_cvt_0_ult_icmp(i1 %arg, i1 %arg1) {
761; CHECK-LABEL: @test_zext_zext_cvt_0_ult_icmp(
762; CHECK-NEXT:  bb:
763; CHECK-NEXT:    ret i1 false
764;
765bb:
766  %i = zext i1 %arg to i32
767  %i2 = zext i1 %arg1 to i32
768  %i3 = add i32 %i2, %i
769  %i4 = icmp ult i32 %i3, 0
770  ret i1 %i4
771}
772
773define i1 @test_zext_zext_cvt_2_ult_icmp(i1 %arg, i1 %arg1) {
774; CHECK-LABEL: @test_zext_zext_cvt_2_ult_icmp(
775; CHECK-NEXT:  bb:
776; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]]
777; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
778; CHECK-NEXT:    ret i1 [[I4]]
779;
780bb:
781  %i = zext i1 %arg to i32
782  %i2 = zext i1 %arg1 to i32
783  %i3 = add i32 %i2, %i
784  %i4 = icmp ult i32 %i3, 2
785  ret i1 %i4
786}
787
788define i1 @test_sext_sext_cvt_neg_2_ult_icmp(i1 %arg, i1 %arg1) {
789; CHECK-LABEL: @test_sext_sext_cvt_neg_2_ult_icmp(
790; CHECK-NEXT:  bb:
791; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
792; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
793; CHECK-NEXT:    ret i1 [[I4]]
794;
795bb:
796  %i = sext i1 %arg to i32
797  %i2 = sext i1 %arg1 to i32
798  %i3 = add i32 %i2, %i
799  %i4 = icmp ult i32 %i3, -2
800  ret i1 %i4
801}
802
803define i1 @test_sext_sext_cvt_neg_1_ult_icmp(i1 %arg, i1 %arg1) {
804; CHECK-LABEL: @test_sext_sext_cvt_neg_1_ult_icmp(
805; CHECK-NEXT:  bb:
806; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
807; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
808; CHECK-NEXT:    ret i1 [[I4]]
809;
810bb:
811  %i = sext i1 %arg to i32
812  %i2 = sext i1 %arg1 to i32
813  %i3 = add i32 %i2, %i
814  %i4 = icmp ult i32 %i3, -1
815  ret i1 %i4
816}
817
818define i1 @test_sext_sext_cvt_0_ult_icmp(i1 %arg, i1 %arg1) {
819; CHECK-LABEL: @test_sext_sext_cvt_0_ult_icmp(
820; CHECK-NEXT:  bb:
821; CHECK-NEXT:    ret i1 false
822;
823bb:
824  %i = sext i1 %arg to i32
825  %i2 = sext i1 %arg1 to i32
826  %i3 = add i32 %i2, %i
827  %i4 = icmp ult i32 %i3, 0
828  ret i1 %i4
829}
830
831define i1 @test_sext_sext_cvt_1_ult_icmp(i1 %arg, i1 %arg1) {
832; CHECK-LABEL: @test_sext_sext_cvt_1_ult_icmp(
833; CHECK-NEXT:  bb:
834; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
835; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
836; CHECK-NEXT:    ret i1 [[I4]]
837;
838bb:
839  %i = sext i1 %arg to i32
840  %i2 = sext i1 %arg1 to i32
841  %i3 = add i32 %i2, %i
842  %i4 = icmp ult i32 %i3, 1
843  ret i1 %i4
844}
845
846define i1 @test_sext_sext_cvt_2_ult_icmp(i1 %arg, i1 %arg1) {
847; CHECK-LABEL: @test_sext_sext_cvt_2_ult_icmp(
848; CHECK-NEXT:  bb:
849; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
850; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
851; CHECK-NEXT:    ret i1 [[I4]]
852;
853bb:
854  %i = sext i1 %arg to i32
855  %i2 = sext i1 %arg1 to i32
856  %i3 = add i32 %i2, %i
857  %i4 = icmp ult i32 %i3, 2
858  ret i1 %i4
859}
860
861define i1 @test_sext_zext_cvt_neg_2_ult_icmp(i1 %arg, i1 %arg1) {
862; CHECK-LABEL: @test_sext_zext_cvt_neg_2_ult_icmp(
863; CHECK-NEXT:  bb:
864; CHECK-NEXT:    [[ARG_NOT:%.*]] = xor i1 [[ARG:%.*]], true
865; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG_NOT]]
866; CHECK-NEXT:    ret i1 [[I4]]
867;
868bb:
869  %i = sext i1 %arg to i32
870  %i2 = zext i1 %arg1 to i32
871  %i3 = add i32 %i2, %i
872  %i4 = icmp ult i32 %i3, -2
873  ret i1 %i4
874}
875
876define i1 @test_sext_zext_cvt_neg_1_ult_icmp(i1 %arg, i1 %arg1) {
877; CHECK-LABEL: @test_sext_zext_cvt_neg_1_ult_icmp(
878; CHECK-NEXT:  bb:
879; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
880; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[TMP0]]
881; CHECK-NEXT:    ret i1 [[I4]]
882;
883bb:
884  %i = sext i1 %arg to i32
885  %i2 = zext i1 %arg1 to i32
886  %i3 = add i32 %i2, %i
887  %i4 = icmp ult i32 %i3, -1
888  ret i1 %i4
889}
890
891define i1 @test_sext_zext_cvt_0_ult_icmp(i1 %arg, i1 %arg1) {
892; CHECK-LABEL: @test_sext_zext_cvt_0_ult_icmp(
893; CHECK-NEXT:  bb:
894; CHECK-NEXT:    ret i1 false
895;
896bb:
897  %i = sext i1 %arg to i32
898  %i2 = zext i1 %arg1 to i32
899  %i3 = add i32 %i2, %i
900  %i4 = icmp ult i32 %i3, 0
901  ret i1 %i4
902}
903
904define i1 @test_sext_zext_cvt_2_ult_icmp(i1 %arg, i1 %arg1) {
905; CHECK-LABEL: @test_sext_zext_cvt_2_ult_icmp(
906; CHECK-NEXT:  bb:
907; CHECK-NEXT:    [[ARG_NOT:%.*]] = xor i1 [[ARG:%.*]], true
908; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG_NOT]]
909; CHECK-NEXT:    ret i1 [[I4]]
910;
911bb:
912  %i = sext i1 %arg to i32
913  %i2 = zext i1 %arg1 to i32
914  %i3 = add i32 %i2, %i
915  %i4 = icmp ult i32 %i3, 2
916  ret i1 %i4
917}
918
919define i1 @test_zext_sext_cvt_neg_1_ult_icmp(i1 %arg, i1 %arg1) {
920; CHECK-LABEL: @test_zext_sext_cvt_neg_1_ult_icmp(
921; CHECK-NEXT:  bb:
922; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
923; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG:%.*]], [[TMP0]]
924; CHECK-NEXT:    ret i1 [[I4]]
925;
926bb:
927  %i = zext i1 %arg to i32
928  %i2 = sext i1 %arg1 to i32
929  %i3 = add i32 %i2, %i
930  %i4 = icmp ult i32 %i3, -1
931  ret i1 %i4
932}
933
934define i1 @test_zext_sext_cvt_0_ult_icmp(i1 %arg, i1 %arg1) {
935; CHECK-LABEL: @test_zext_sext_cvt_0_ult_icmp(
936; CHECK-NEXT:  bb:
937; CHECK-NEXT:    ret i1 false
938;
939bb:
940  %i = zext i1 %arg to i32
941  %i2 = sext i1 %arg1 to i32
942  %i3 = add i32 %i2, %i
943  %i4 = icmp ult i32 %i3, 0
944  ret i1 %i4
945}
946
947define i1 @test_zext_sext_cvt_1_ult_icmp(i1 %arg, i1 %arg1) {
948; CHECK-LABEL: @test_zext_sext_cvt_1_ult_icmp(
949; CHECK-NEXT:  bb:
950; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
951; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
952; CHECK-NEXT:    ret i1 [[I4]]
953;
954bb:
955  %i = zext i1 %arg to i32
956  %i2 = sext i1 %arg1 to i32
957  %i3 = add i32 %i2, %i
958  %i4 = icmp ult i32 %i3, 1
959  ret i1 %i4
960}
961
962; tests for ugt
963define i1 @test_cvt_icmp4(i1 %arg, i1 %arg1) {
964; CHECK-LABEL: @test_cvt_icmp4(
965; CHECK-NEXT:  bb:
966; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
967; CHECK-NEXT:    ret i1 [[I4]]
968;
969bb:
970  %i = zext i1 %arg to i32
971  %i2 = zext i1 %arg1 to i32
972  %i3 = add i32 %i2, %i
973  %i4 = icmp ugt i32 %i3, 0
974  ret i1 %i4
975}
976
977define i1 @test_zext_zext_cvt_neg_2_ugt_icmp(i1 %arg, i1 %arg1) {
978; CHECK-LABEL: @test_zext_zext_cvt_neg_2_ugt_icmp(
979; CHECK-NEXT:  bb:
980; CHECK-NEXT:    ret i1 false
981;
982bb:
983  %i = zext i1 %arg to i32
984  %i2 = zext i1 %arg1 to i32
985  %i3 = add i32 %i2, %i
986  %i4 = icmp ugt i32 %i3, -2
987  ret i1 %i4
988}
989
990define i1 @test_zext_zext_cvt_1_ugt_icmp(i1 %arg, i1 %arg1) {
991; CHECK-LABEL: @test_zext_zext_cvt_1_ugt_icmp(
992; CHECK-NEXT:  bb:
993; CHECK-NEXT:    [[I4:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]]
994; CHECK-NEXT:    ret i1 [[I4]]
995;
996bb:
997  %i = zext i1 %arg to i32
998  %i2 = zext i1 %arg1 to i32
999  %i3 = add i32 %i2, %i
1000  %i4 = icmp ugt i32 %i3, 1
1001  ret i1 %i4
1002}
1003
1004define i1 @test_zext_zext_cvt_2_ugt_icmp(i1 %arg, i1 %arg1) {
1005; CHECK-LABEL: @test_zext_zext_cvt_2_ugt_icmp(
1006; CHECK-NEXT:  bb:
1007; CHECK-NEXT:    ret i1 false
1008;
1009bb:
1010  %i = zext i1 %arg to i32
1011  %i2 = zext i1 %arg1 to i32
1012  %i3 = add i32 %i2, %i
1013  %i4 = icmp ugt i32 %i3, 2
1014  ret i1 %i4
1015}
1016
1017define i1 @test_sext_sext_cvt_neg_2_ugt_icmp(i1 %arg, i1 %arg1) {
1018; CHECK-LABEL: @test_sext_sext_cvt_neg_2_ugt_icmp(
1019; CHECK-NEXT:  bb:
1020; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
1021; CHECK-NEXT:    ret i1 [[I4]]
1022;
1023bb:
1024  %i = sext i1 %arg to i32
1025  %i2 = sext i1 %arg1 to i32
1026  %i3 = add i32 %i2, %i
1027  %i4 = icmp ugt i32 %i3, -2
1028  ret i1 %i4
1029}
1030
1031define i1 @test_sext_sext_cvt_0_ugt_icmp(i1 %arg, i1 %arg1) {
1032; CHECK-LABEL: @test_sext_sext_cvt_0_ugt_icmp(
1033; CHECK-NEXT:  bb:
1034; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
1035; CHECK-NEXT:    ret i1 [[I4]]
1036;
1037bb:
1038  %i = sext i1 %arg to i32
1039  %i2 = sext i1 %arg1 to i32
1040  %i3 = add i32 %i2, %i
1041  %i4 = icmp ugt i32 %i3, 0
1042  ret i1 %i4
1043}
1044
1045define i1 @test_sext_sext_cvt_2_ugt_icmp(i1 %arg, i1 %arg1) {
1046; CHECK-LABEL: @test_sext_sext_cvt_2_ugt_icmp(
1047; CHECK-NEXT:  bb:
1048; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
1049; CHECK-NEXT:    ret i1 [[I4]]
1050;
1051bb:
1052  %i = sext i1 %arg to i32
1053  %i2 = sext i1 %arg1 to i32
1054  %i3 = add i32 %i2, %i
1055  %i4 = icmp ugt i32 %i3, 2
1056  ret i1 %i4
1057}
1058
1059define i1 @test_zext_sext_cvt_neg_2_ugt_icmp(i1 %arg, i1 %arg1) {
1060; CHECK-LABEL: @test_zext_sext_cvt_neg_2_ugt_icmp(
1061; CHECK-NEXT:  bb:
1062; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
1063; CHECK-NEXT:    [[I4:%.*]] = and i1 [[ARG1:%.*]], [[TMP0]]
1064; CHECK-NEXT:    ret i1 [[I4]]
1065;
1066bb:
1067  %i = zext i1 %arg to i32
1068  %i2 = sext i1 %arg1 to i32
1069  %i3 = add i32 %i2, %i
1070  %i4 = icmp ugt i32 %i3, -2
1071  ret i1 %i4
1072}
1073
1074define i1 @test_zext_sext_cvt_neg_1_ugt_icmp(i1 %arg, i1 %arg1) {
1075; CHECK-LABEL: @test_zext_sext_cvt_neg_1_ugt_icmp(
1076; CHECK-NEXT:  bb:
1077; CHECK-NEXT:    ret i1 false
1078;
1079bb:
1080  %i = zext i1 %arg to i32
1081  %i2 = sext i1 %arg1 to i32
1082  %i3 = add i32 %i2, %i
1083  %i4 = icmp ugt i32 %i3, -1
1084  ret i1 %i4
1085}
1086
1087define i1 @test_zext_sext_cvt_0_ugt_icmp(i1 %arg, i1 %arg1) {
1088; CHECK-LABEL: @test_zext_sext_cvt_0_ugt_icmp(
1089; CHECK-NEXT:  bb:
1090; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
1091; CHECK-NEXT:    ret i1 [[I4]]
1092;
1093bb:
1094  %i = zext i1 %arg to i32
1095  %i2 = sext i1 %arg1 to i32
1096  %i3 = add i32 %i2, %i
1097  %i4 = icmp ugt i32 %i3, 0
1098  ret i1 %i4
1099}
1100
1101define i1 @test_zext_sext_cvt_1_ugt_icmp(i1 %arg, i1 %arg1) {
1102; CHECK-LABEL: @test_zext_sext_cvt_1_ugt_icmp(
1103; CHECK-NEXT:  bb:
1104; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
1105; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[ARG1:%.*]], [[TMP0]]
1106; CHECK-NEXT:    ret i1 [[TMP1]]
1107;
1108bb:
1109  %i = zext i1 %arg to i32
1110  %i2 = sext i1 %arg1 to i32
1111  %i3 = add i32 %i2, %i
1112  %i4 = icmp ugt i32 %i3, 1
1113  ret i1 %i4
1114}
1115
1116define i1 @test_zext_sext_cvt_2_ugt_icmp(i1 %arg, i1 %arg1) {
1117; CHECK-LABEL: @test_zext_sext_cvt_2_ugt_icmp(
1118; CHECK-NEXT:  bb:
1119; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
1120; CHECK-NEXT:    [[I4:%.*]] = and i1 [[ARG1:%.*]], [[TMP0]]
1121; CHECK-NEXT:    ret i1 [[I4]]
1122;
1123bb:
1124  %i = zext i1 %arg to i32
1125  %i2 = sext i1 %arg1 to i32
1126  %i3 = add i32 %i2, %i
1127  %i4 = icmp ugt i32 %i3, 2
1128  ret i1 %i4
1129}
1130
1131define i1 @test_cvt_icmp5(i1 %arg, i1 %arg1) {
1132; CHECK-LABEL: @test_cvt_icmp5(
1133; CHECK-NEXT:  bb:
1134; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
1135; CHECK-NEXT:    ret i1 [[I4]]
1136;
1137bb:
1138  %i = zext i1 %arg to i32
1139  %i2 = zext i1 %arg1 to i32
1140  %i3 = add i32 %i2, %i
1141  %i4 = icmp uge i32 %i3, 1
1142  ret i1 %i4
1143}
1144
1145define i1 @test_cvt_icmp6(i1 %arg, i1 %arg1) {
1146; CHECK-LABEL: @test_cvt_icmp6(
1147; CHECK-NEXT:  bb:
1148; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]]
1149; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
1150; CHECK-NEXT:    ret i1 [[I4]]
1151;
1152bb:
1153  %i = zext i1 %arg to i32
1154  %i2 = zext i1 %arg1 to i32
1155  %i3 = add i32 %i2, %i
1156  %i4 = icmp ule i32 %i3, 1
1157  ret i1 %i4
1158}
1159
1160; tests for sgt
1161define i1 @test_cvt_icmp7(i1 %arg, i1 %arg1) {
1162; CHECK-LABEL: @test_cvt_icmp7(
1163; CHECK-NEXT:  bb:
1164; CHECK-NEXT:    [[I4:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]]
1165; CHECK-NEXT:    ret i1 [[I4]]
1166;
1167bb:
1168  %i = zext i1 %arg to i32
1169  %i2 = zext i1 %arg1 to i32
1170  %i3 = add i32 %i2, %i
1171  %i4 = icmp sgt i32 %i3, 1
1172  ret i1 %i4
1173}
1174
1175define i1 @test_zext_zext_cvt_neg_2_sgt_icmp(i1 %arg, i1 %arg1) {
1176; CHECK-LABEL: @test_zext_zext_cvt_neg_2_sgt_icmp(
1177; CHECK-NEXT:  bb:
1178; CHECK-NEXT:    ret i1 true
1179;
1180bb:
1181  %i = zext i1 %arg to i32
1182  %i2 = zext i1 %arg1 to i32
1183  %i3 = add i32 %i2, %i
1184  %i4 = icmp sgt i32 %i3, -2
1185  ret i1 %i4
1186}
1187
1188define i1 @test_zext_zext_cvt_neg_1_sgt_icmp(i1 %arg, i1 %arg1) {
1189; CHECK-LABEL: @test_zext_zext_cvt_neg_1_sgt_icmp(
1190; CHECK-NEXT:  bb:
1191; CHECK-NEXT:    ret i1 true
1192;
1193bb:
1194  %i = zext i1 %arg to i32
1195  %i2 = zext i1 %arg1 to i32
1196  %i3 = add i32 %i2, %i
1197  %i4 = icmp sgt i32 %i3, -1
1198  ret i1 %i4
1199}
1200
1201define i1 @test_zext_zext_cvt_2_sgt_icmp(i1 %arg, i1 %arg1) {
1202; CHECK-LABEL: @test_zext_zext_cvt_2_sgt_icmp(
1203; CHECK-NEXT:  bb:
1204; CHECK-NEXT:    ret i1 false
1205;
1206bb:
1207  %i = zext i1 %arg to i32
1208  %i2 = zext i1 %arg1 to i32
1209  %i3 = add i32 %i2, %i
1210  %i4 = icmp sgt i32 %i3, 2
1211  ret i1 %i4
1212}
1213
1214define i1 @test_sext_sext_cvt_neg_2_sgt_icmp(i1 %arg, i1 %arg1) {
1215; CHECK-LABEL: @test_sext_sext_cvt_neg_2_sgt_icmp(
1216; CHECK-NEXT:  bb:
1217; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]]
1218; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
1219; CHECK-NEXT:    ret i1 [[I4]]
1220;
1221bb:
1222  %i = sext i1 %arg to i32
1223  %i2 = sext i1 %arg1 to i32
1224  %i3 = add i32 %i2, %i
1225  %i4 = icmp sgt i32 %i3, -2
1226  ret i1 %i4
1227}
1228
1229define i1 @test_sext_sext_cvt_0_sgt_icmp(i1 %arg, i1 %arg1) {
1230; CHECK-LABEL: @test_sext_sext_cvt_0_sgt_icmp(
1231; CHECK-NEXT:  bb:
1232; CHECK-NEXT:    ret i1 false
1233;
1234bb:
1235  %i = sext i1 %arg to i32
1236  %i2 = sext i1 %arg1 to i32
1237  %i3 = add i32 %i2, %i
1238  %i4 = icmp sgt i32 %i3, 0
1239  ret i1 %i4
1240}
1241
1242define i1 @test_sext_sext_cvt_2_sgt_icmp(i1 %arg, i1 %arg1) {
1243; CHECK-LABEL: @test_sext_sext_cvt_2_sgt_icmp(
1244; CHECK-NEXT:  bb:
1245; CHECK-NEXT:    ret i1 false
1246;
1247bb:
1248  %i = sext i1 %arg to i32
1249  %i2 = sext i1 %arg1 to i32
1250  %i3 = add i32 %i2, %i
1251  %i4 = icmp sgt i32 %i3, 2
1252  ret i1 %i4
1253}
1254
1255define i1 @test_zext_sext_cvt_neg_2_sgt_icmp(i1 %arg, i1 %arg1) {
1256; CHECK-LABEL: @test_zext_sext_cvt_neg_2_sgt_icmp(
1257; CHECK-NEXT:  bb:
1258; CHECK-NEXT:    ret i1 true
1259;
1260bb:
1261  %i = zext i1 %arg to i32
1262  %i2 = sext i1 %arg1 to i32
1263  %i3 = add i32 %i2, %i
1264  %i4 = icmp sgt i32 %i3, -2
1265  ret i1 %i4
1266}
1267
1268define i1 @test_zext_sext_cvt_neg_1_sgt_icmp(i1 %arg, i1 %arg1) {
1269; CHECK-LABEL: @test_zext_sext_cvt_neg_1_sgt_icmp(
1270; CHECK-NEXT:  bb:
1271; CHECK-NEXT:    [[ARG1_NOT:%.*]] = xor i1 [[ARG1:%.*]], true
1272; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG:%.*]], [[ARG1_NOT]]
1273; CHECK-NEXT:    ret i1 [[I4]]
1274;
1275bb:
1276  %i = zext i1 %arg to i32
1277  %i2 = sext i1 %arg1 to i32
1278  %i3 = add i32 %i2, %i
1279  %i4 = icmp sgt i32 %i3, -1
1280  ret i1 %i4
1281}
1282
1283define i1 @test_zext_sext_cvt_0_sgt_icmp(i1 %arg, i1 %arg1) {
1284; CHECK-LABEL: @test_zext_sext_cvt_0_sgt_icmp(
1285; CHECK-NEXT:  bb:
1286; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
1287; CHECK-NEXT:    [[I4:%.*]] = and i1 [[ARG:%.*]], [[TMP0]]
1288; CHECK-NEXT:    ret i1 [[I4]]
1289;
1290bb:
1291  %i = zext i1 %arg to i32
1292  %i2 = sext i1 %arg1 to i32
1293  %i3 = add i32 %i2, %i
1294  %i4 = icmp sgt i32 %i3, 0
1295  ret i1 %i4
1296}
1297
1298define i1 @test_zext_sext_cvt_1_sgt_icmp(i1 %arg, i1 %arg1) {
1299; CHECK-LABEL: @test_zext_sext_cvt_1_sgt_icmp(
1300; CHECK-NEXT:  bb:
1301; CHECK-NEXT:    ret i1 false
1302;
1303bb:
1304  %i = zext i1 %arg to i32
1305  %i2 = sext i1 %arg1 to i32
1306  %i3 = add i32 %i2, %i
1307  %i4 = icmp sgt i32 %i3, 1
1308  ret i1 %i4
1309}
1310
1311define i1 @test_zext_sext_cvt_2_sgt_icmp(i1 %arg, i1 %arg1) {
1312; CHECK-LABEL: @test_zext_sext_cvt_2_sgt_icmp(
1313; CHECK-NEXT:  bb:
1314; CHECK-NEXT:    ret i1 false
1315;
1316bb:
1317  %i = zext i1 %arg to i32
1318  %i2 = sext i1 %arg1 to i32
1319  %i3 = add i32 %i2, %i
1320  %i4 = icmp sgt i32 %i3, 2
1321  ret i1 %i4
1322}
1323
1324; tests for slt
1325define i1 @test_zext_zext_cvt_neg_2_slt_icmp(i1 %arg, i1 %arg1) {
1326; CHECK-LABEL: @test_zext_zext_cvt_neg_2_slt_icmp(
1327; CHECK-NEXT:  bb:
1328; CHECK-NEXT:    ret i1 false
1329;
1330bb:
1331  %i = zext i1 %arg to i32
1332  %i2 = zext i1 %arg1 to i32
1333  %i3 = add i32 %i2, %i
1334  %i4 = icmp slt i32 %i3, -2
1335  ret i1 %i4
1336}
1337
1338define i1 @test_zext_zext_cvt_neg_1_slt_icmp(i1 %arg, i1 %arg1) {
1339; CHECK-LABEL: @test_zext_zext_cvt_neg_1_slt_icmp(
1340; CHECK-NEXT:  bb:
1341; CHECK-NEXT:    ret i1 false
1342;
1343bb:
1344  %i = zext i1 %arg to i32
1345  %i2 = zext i1 %arg1 to i32
1346  %i3 = add i32 %i2, %i
1347  %i4 = icmp slt i32 %i3, -1
1348  ret i1 %i4
1349}
1350
1351define i1 @test_zext_zext_cvt_2_slt_icmp(i1 %arg, i1 %arg1) {
1352; CHECK-LABEL: @test_zext_zext_cvt_2_slt_icmp(
1353; CHECK-NEXT:  bb:
1354; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]]
1355; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
1356; CHECK-NEXT:    ret i1 [[I4]]
1357;
1358bb:
1359  %i = zext i1 %arg to i32
1360  %i2 = zext i1 %arg1 to i32
1361  %i3 = add i32 %i2, %i
1362  %i4 = icmp slt i32 %i3, 2
1363  ret i1 %i4
1364}
1365
1366define i1 @test_sext_sext_cvt_neg_2_slt_icmp(i1 %arg, i1 %arg1) {
1367; CHECK-LABEL: @test_sext_sext_cvt_neg_2_slt_icmp(
1368; CHECK-NEXT:  bb:
1369; CHECK-NEXT:    ret i1 false
1370;
1371bb:
1372  %i = sext i1 %arg to i32
1373  %i2 = sext i1 %arg1 to i32
1374  %i3 = add i32 %i2, %i
1375  %i4 = icmp slt i32 %i3, -2
1376  ret i1 %i4
1377}
1378
1379define i1 @test_sext_sext_cvt_0_slt_icmp(i1 %arg, i1 %arg1) {
1380; CHECK-LABEL: @test_sext_sext_cvt_0_slt_icmp(
1381; CHECK-NEXT:  bb:
1382; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
1383; CHECK-NEXT:    ret i1 [[TMP0]]
1384;
1385bb:
1386  %i = sext i1 %arg to i32
1387  %i2 = sext i1 %arg1 to i32
1388  %i3 = add i32 %i2, %i
1389  %i4 = icmp slt i32 %i3, 0
1390  ret i1 %i4
1391}
1392
1393define i1 @test_sext_sext_cvt_2_slt_icmp(i1 %arg, i1 %arg1) {
1394; CHECK-LABEL: @test_sext_sext_cvt_2_slt_icmp(
1395; CHECK-NEXT:  bb:
1396; CHECK-NEXT:    ret i1 true
1397;
1398bb:
1399  %i = sext i1 %arg to i32
1400  %i2 = sext i1 %arg1 to i32
1401  %i3 = add i32 %i2, %i
1402  %i4 = icmp slt i32 %i3, 2
1403  ret i1 %i4
1404}
1405
1406define i1 @test_zext_sext_cvt_neg_2_slt_icmp(i1 %arg, i1 %arg1) {
1407; CHECK-LABEL: @test_zext_sext_cvt_neg_2_slt_icmp(
1408; CHECK-NEXT:  bb:
1409; CHECK-NEXT:    ret i1 false
1410;
1411bb:
1412  %i = zext i1 %arg to i32
1413  %i2 = sext i1 %arg1 to i32
1414  %i3 = add i32 %i2, %i
1415  %i4 = icmp slt i32 %i3, -2
1416  ret i1 %i4
1417}
1418
1419define i1 @test_zext_sext_cvt_neg_1_slt_icmp(i1 %arg, i1 %arg1) {
1420; CHECK-LABEL: @test_zext_sext_cvt_neg_1_slt_icmp(
1421; CHECK-NEXT:  bb:
1422; CHECK-NEXT:    ret i1 false
1423;
1424bb:
1425  %i = zext i1 %arg to i32
1426  %i2 = sext i1 %arg1 to i32
1427  %i3 = add i32 %i2, %i
1428  %i4 = icmp slt i32 %i3, -1
1429  ret i1 %i4
1430}
1431
1432define i1 @test_zext_sext_cvt_0_slt_icmp(i1 %arg, i1 %arg1) {
1433; CHECK-LABEL: @test_zext_sext_cvt_0_slt_icmp(
1434; CHECK-NEXT:  bb:
1435; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
1436; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[ARG1:%.*]], [[TMP0]]
1437; CHECK-NEXT:    ret i1 [[TMP1]]
1438;
1439bb:
1440  %i = zext i1 %arg to i32
1441  %i2 = sext i1 %arg1 to i32
1442  %i3 = add i32 %i2, %i
1443  %i4 = icmp slt i32 %i3, 0
1444  ret i1 %i4
1445}
1446
1447define i1 @test_zext_sext_cvt_1_slt_icmp(i1 %arg, i1 %arg1) {
1448; CHECK-LABEL: @test_zext_sext_cvt_1_slt_icmp(
1449; CHECK-NEXT:  bb:
1450; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
1451; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[TMP0]]
1452; CHECK-NEXT:    ret i1 [[I4]]
1453;
1454bb:
1455  %i = zext i1 %arg to i32
1456  %i2 = sext i1 %arg1 to i32
1457  %i3 = add i32 %i2, %i
1458  %i4 = icmp slt i32 %i3, 1
1459  ret i1 %i4
1460}
1461
1462define i1 @test_zext_sext_cvt_2_slt_icmp(i1 %arg, i1 %arg1) {
1463; CHECK-LABEL: @test_zext_sext_cvt_2_slt_icmp(
1464; CHECK-NEXT:  bb:
1465; CHECK-NEXT:    ret i1 true
1466;
1467bb:
1468  %i = zext i1 %arg to i32
1469  %i2 = sext i1 %arg1 to i32
1470  %i3 = add i32 %i2, %i
1471  %i4 = icmp slt i32 %i3, 2
1472  ret i1 %i4
1473}
1474
1475define i1 @test_cvt_icmp8(i1 %arg, i1 %arg1) {
1476; CHECK-LABEL: @test_cvt_icmp8(
1477; CHECK-NEXT:  bb:
1478; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
1479; CHECK-NEXT:    ret i1 [[I4]]
1480;
1481bb:
1482  %i = zext i1 %arg to i32
1483  %i2 = zext i1 %arg1 to i32
1484  %i3 = add i32 %i2, %i
1485  %i4 = icmp sge i32 %i3, 1
1486  ret i1 %i4
1487}
1488
1489define i1 @test_cvt_icmp9(i1 %arg, i1 %arg1) {
1490; CHECK-LABEL: @test_cvt_icmp9(
1491; CHECK-NEXT:  bb:
1492; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
1493; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
1494; CHECK-NEXT:    ret i1 [[I4]]
1495;
1496bb:
1497  %i = zext i1 %arg to i32
1498  %i2 = zext i1 %arg1 to i32
1499  %i3 = add i32 %i2, %i
1500  %i4 = icmp slt i32 %i3, 1
1501  ret i1 %i4
1502}
1503
1504define i1 @test_cvt_icmp10(i1 %arg, i1 %arg1) {
1505; CHECK-LABEL: @test_cvt_icmp10(
1506; CHECK-NEXT:  bb:
1507; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]]
1508; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
1509; CHECK-NEXT:    ret i1 [[I4]]
1510;
1511bb:
1512  %i = zext i1 %arg to i32
1513  %i2 = zext i1 %arg1 to i32
1514  %i3 = add i32 %i2, %i
1515  %i4 = icmp sle i32 %i3, 1
1516  ret i1 %i4
1517}
1518
1519define i1 @test_cvt_icmp11(i1 %arg, i1 %arg1) {
1520; CHECK-LABEL: @test_cvt_icmp11(
1521; CHECK-NEXT:  bb:
1522; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
1523; CHECK-NEXT:    ret i1 [[I4]]
1524;
1525bb:
1526  %i = sext i1 %arg to i32
1527  %i2 = sext i1 %arg1 to i32
1528  %i3 = add i32 %i2, %i
1529  %i4 = icmp ugt i32 %i3, 2
1530  ret i1 %i4
1531}
1532
1533define i1 @test_cvt_icmp12(i1 %arg, i1 %arg1) {
1534; CHECK-LABEL: @test_cvt_icmp12(
1535; CHECK-NEXT:  bb:
1536; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
1537; CHECK-NEXT:    ret i1 [[I4]]
1538;
1539bb:
1540  %i = sext i1 %arg to i32
1541  %i2 = sext i1 %arg1 to i32
1542  %i3 = add i32 %i2, %i
1543  %i4 = icmp uge i32 %i3, 1
1544  ret i1 %i4
1545}
1546
1547define i1 @test_cvt_icmp13(i1 %arg, i1 %arg1) {
1548; CHECK-LABEL: @test_cvt_icmp13(
1549; CHECK-NEXT:  bb:
1550; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
1551; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
1552; CHECK-NEXT:    ret i1 [[I4]]
1553;
1554bb:
1555  %i = sext i1 %arg to i32
1556  %i2 = sext i1 %arg1 to i32
1557  %i3 = add i32 %i2, %i
1558  %i4 = icmp ult i32 %i3, 1
1559  ret i1 %i4
1560}
1561
1562define i1 @test_cvt_icmp14(i1 %arg, i1 %arg1) {
1563; CHECK-LABEL: @test_cvt_icmp14(
1564; CHECK-NEXT:  bb:
1565; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
1566; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
1567; CHECK-NEXT:    ret i1 [[I4]]
1568;
1569bb:
1570  %i = sext i1 %arg to i32
1571  %i2 = sext i1 %arg1 to i32
1572  %i3 = add i32 %i2, %i
1573  %i4 = icmp ule i32 %i3, 2
1574  ret i1 %i4
1575}
1576
1577define i1 @test_cvt_icmp15(i1 %arg, i1 %arg1) {
1578; CHECK-LABEL: @test_cvt_icmp15(
1579; CHECK-NEXT:  bb:
1580; CHECK-NEXT:    ret i1 false
1581;
1582bb:
1583  %i = sext i1 %arg to i32
1584  %i2 = sext i1 %arg1 to i32
1585  %i3 = add i32 %i2, %i
1586  %i4 = icmp sgt i32 %i3, 2
1587  ret i1 %i4
1588}
1589
1590define i1 @test_cvt_icmp16(i1 %arg, i1 %arg1) {
1591; CHECK-LABEL: @test_cvt_icmp16(
1592; CHECK-NEXT:  bb:
1593; CHECK-NEXT:    ret i1 false
1594;
1595bb:
1596  %i = sext i1 %arg to i32
1597  %i2 = sext i1 %arg1 to i32
1598  %i3 = add i32 %i2, %i
1599  %i4 = icmp sge i32 %i3, 2
1600  ret i1 %i4
1601}
1602
1603define i1 @test_cvt_icmp17(i1 %arg, i1 %arg1) {
1604; CHECK-LABEL: @test_cvt_icmp17(
1605; CHECK-NEXT:  bb:
1606; CHECK-NEXT:    ret i1 true
1607;
1608bb:
1609  %i = sext i1 %arg to i32
1610  %i2 = sext i1 %arg1 to i32
1611  %i3 = add i32 %i2, %i
1612  %i4 = icmp slt i32 %i3, 2
1613  ret i1 %i4
1614}
1615
1616define i1 @test_cvt_icmp18(i1 %arg, i1 %arg1) {
1617; CHECK-LABEL: @test_cvt_icmp18(
1618; CHECK-NEXT:  bb:
1619; CHECK-NEXT:    ret i1 true
1620;
1621bb:
1622  %i = sext i1 %arg to i32
1623  %i2 = sext i1 %arg1 to i32
1624  %i3 = add i32 %i2, %i
1625  %i4 = icmp sle i32 %i3, 2
1626  ret i1 %i4
1627}
1628
1629define i1 @test_cvt_icmp19(i1 %arg, i1 %arg1) {
1630; CHECK-LABEL: @test_cvt_icmp19(
1631; CHECK-NEXT:  bb:
1632; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
1633; CHECK-NEXT:    [[I4:%.*]] = and i1 [[ARG:%.*]], [[TMP0]]
1634; CHECK-NEXT:    ret i1 [[I4]]
1635;
1636bb:
1637  %i = sext i1 %arg to i32
1638  %i2 = zext i1 %arg1 to i32
1639  %i3 = add i32 %i2, %i
1640  %i4 = icmp ugt i32 %i3, 2
1641  ret i1 %i4
1642}
1643
1644define i1 @test_cvt_icmp20(i1 %arg, i1 %arg1) {
1645; CHECK-LABEL: @test_cvt_icmp20(
1646; CHECK-NEXT:  bb:
1647; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
1648; CHECK-NEXT:    ret i1 [[I4]]
1649;
1650bb:
1651  %i = sext i1 %arg to i32
1652  %i2 = zext i1 %arg1 to i32
1653  %i3 = add i32 %i2, %i
1654  %i4 = icmp uge i32 %i3, 1
1655  ret i1 %i4
1656}
1657
1658define i1 @test_cvt_icmp21(i1 %arg, i1 %arg1) {
1659; CHECK-LABEL: @test_cvt_icmp21(
1660; CHECK-NEXT:  bb:
1661; CHECK-NEXT:    [[ARG_NOT:%.*]] = xor i1 [[ARG:%.*]], true
1662; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG_NOT]]
1663; CHECK-NEXT:    ret i1 [[I4]]
1664;
1665bb:
1666  %i = sext i1 %arg to i32
1667  %i2 = zext i1 %arg1 to i32
1668  %i3 = add i32 %i2, %i
1669  %i4 = icmp ult i32 %i3, 2
1670  ret i1 %i4
1671}
1672
1673define i1 @test_cvt_icmp22(i1 %arg, i1 %arg1) {
1674; CHECK-LABEL: @test_cvt_icmp22(
1675; CHECK-NEXT:  bb:
1676; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
1677; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[TMP0]]
1678; CHECK-NEXT:    ret i1 [[I4]]
1679;
1680bb:
1681  %i = sext i1 %arg to i32
1682  %i2 = zext i1 %arg1 to i32
1683  %i3 = add i32 %i2, %i
1684  %i4 = icmp ule i32 %i3, 2
1685  ret i1 %i4
1686}
1687
1688define i1 @test_cvt_icmp23(i1 %arg, i1 %arg1) {
1689; CHECK-LABEL: @test_cvt_icmp23(
1690; CHECK-NEXT:  bb:
1691; CHECK-NEXT:    ret i1 false
1692;
1693bb:
1694  %i = sext i1 %arg to i32
1695  %i2 = zext i1 %arg1 to i32
1696  %i3 = add i32 %i2, %i
1697  %i4 = icmp sgt i32 %i3, 2
1698  ret i1 %i4
1699}
1700
1701define i1 @test_cvt_icmp24(i1 %arg, i1 %arg1) {
1702; CHECK-LABEL: @test_cvt_icmp24(
1703; CHECK-NEXT:  bb:
1704; CHECK-NEXT:    [[ARG_NOT:%.*]] = xor i1 [[ARG:%.*]], true
1705; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG_NOT]]
1706; CHECK-NEXT:    ret i1 [[I4]]
1707;
1708bb:
1709  %i = sext i1 %arg to i32
1710  %i2 = zext i1 %arg1 to i32
1711  %i3 = add i32 %i2, %i
1712  %i4 = icmp sge i32 %i3, 0
1713  ret i1 %i4
1714}
1715
1716define i1 @test_cvt_icmp25(i1 %arg, i1 %arg1) {
1717; CHECK-LABEL: @test_cvt_icmp25(
1718; CHECK-NEXT:  bb:
1719; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
1720; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[ARG:%.*]], [[TMP0]]
1721; CHECK-NEXT:    ret i1 [[TMP1]]
1722;
1723bb:
1724  %i = sext i1 %arg to i32
1725  %i2 = zext i1 %arg1 to i32
1726  %i3 = add i32 %i2, %i
1727  %i4 = icmp slt i32 %i3, 0
1728  ret i1 %i4
1729}
1730
1731define i1 @test_cvt_icmp26(i1 %arg, i1 %arg1) {
1732; CHECK-LABEL: @test_cvt_icmp26(
1733; CHECK-NEXT:  bb:
1734; CHECK-NEXT:    ret i1 true
1735;
1736bb:
1737  %i = sext i1 %arg to i32
1738  %i2 = zext i1 %arg1 to i32
1739  %i3 = add i32 %i2, %i
1740  %i4 = icmp sle i32 %i3, 1
1741  ret i1 %i4
1742}
1743
1744define i1 @test1(i32 %a) {
1745; CHECK-LABEL: @test1(
1746; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[A:%.*]], -5
1747; CHECK-NEXT:    ret i1 [[C]]
1748;
1749  %b = add i32 %a, 4
1750  %c = icmp ult i32 %b, 4
1751  ret i1 %c
1752}
1753
1754define <2 x i1> @test1vec(<2 x i32> %a) {
1755; CHECK-LABEL: @test1vec(
1756; CHECK-NEXT:    [[C:%.*]] = icmp ugt <2 x i32> [[A:%.*]], splat (i32 -5)
1757; CHECK-NEXT:    ret <2 x i1> [[C]]
1758;
1759  %b = add <2 x i32> %a, <i32 4, i32 4>
1760  %c = icmp ult <2 x i32> %b, <i32 4, i32 4>
1761  ret <2 x i1> %c
1762}
1763
1764define i1 @test2(i32 %a) {
1765; CHECK-LABEL: @test2(
1766; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[A:%.*]], 4
1767; CHECK-NEXT:    ret i1 [[C]]
1768;
1769  %b = sub i32 %a, 4
1770  %c = icmp ugt i32 %b, -5
1771  ret i1 %c
1772}
1773
1774define <2 x i1> @test2vec(<2 x i32> %a) {
1775; CHECK-LABEL: @test2vec(
1776; CHECK-NEXT:    [[C:%.*]] = icmp ult <2 x i32> [[A:%.*]], splat (i32 4)
1777; CHECK-NEXT:    ret <2 x i1> [[C]]
1778;
1779  %b = sub <2 x i32> %a, <i32 4, i32 4>
1780  %c = icmp ugt <2 x i32> %b, <i32 -5, i32 -5>
1781  ret <2 x i1> %c
1782}
1783
1784define i1 @test3(i32 %a) {
1785; CHECK-LABEL: @test3(
1786; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[A:%.*]], 2147483643
1787; CHECK-NEXT:    ret i1 [[C]]
1788;
1789  %b = add i32 %a, 4
1790  %c = icmp slt i32 %b, 2147483652
1791  ret i1 %c
1792}
1793
1794define <2 x i1> @test3vec(<2 x i32> %a) {
1795; CHECK-LABEL: @test3vec(
1796; CHECK-NEXT:    [[C:%.*]] = icmp sgt <2 x i32> [[A:%.*]], splat (i32 2147483643)
1797; CHECK-NEXT:    ret <2 x i1> [[C]]
1798;
1799  %b = add <2 x i32> %a, <i32 4, i32 4>
1800  %c = icmp slt <2 x i32> %b, <i32 2147483652, i32 2147483652>
1801  ret <2 x i1> %c
1802}
1803
1804define i1 @test4(i32 %a) {
1805; CHECK-LABEL: @test4(
1806; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[A:%.*]], -4
1807; CHECK-NEXT:    ret i1 [[C]]
1808;
1809  %b = add i32 %a, 2147483652
1810  %c = icmp sge i32 %b, 4
1811  ret i1 %c
1812}
1813
1814define { i32, i1 } @test4multiuse(i32 %a) {
1815; CHECK-LABEL: @test4multiuse(
1816; CHECK-NEXT:    [[B:%.*]] = add nsw i32 [[A:%.*]], -2147483644
1817; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[A]], 2147483640
1818; CHECK-NEXT:    [[TMP:%.*]] = insertvalue { i32, i1 } undef, i32 [[B]], 0
1819; CHECK-NEXT:    [[RES:%.*]] = insertvalue { i32, i1 } [[TMP]], i1 [[C]], 1
1820; CHECK-NEXT:    ret { i32, i1 } [[RES]]
1821;
1822
1823  %b = add nsw i32 %a, -2147483644
1824  %c = icmp slt i32 %b, -4
1825
1826  %tmp = insertvalue { i32, i1 } undef, i32 %b, 0
1827  %res = insertvalue { i32, i1 } %tmp, i1 %c, 1
1828
1829  ret { i32, i1 } %res
1830}
1831
1832define <2 x i1> @test4vec(<2 x i32> %a) {
1833; CHECK-LABEL: @test4vec(
1834; CHECK-NEXT:    [[C:%.*]] = icmp slt <2 x i32> [[A:%.*]], splat (i32 -4)
1835; CHECK-NEXT:    ret <2 x i1> [[C]]
1836;
1837  %b = add <2 x i32> %a, <i32 2147483652, i32 2147483652>
1838  %c = icmp sge <2 x i32> %b, <i32 4, i32 4>
1839  ret <2 x i1> %c
1840}
1841
1842; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow.
1843; This becomes equality because it's at the limit.
1844
1845define i1 @nsw_slt1(i8 %a) {
1846; CHECK-LABEL: @nsw_slt1(
1847; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A:%.*]], -128
1848; CHECK-NEXT:    ret i1 [[C]]
1849;
1850  %b = add nsw i8 %a, 100
1851  %c = icmp slt i8 %b, -27
1852  ret i1 %c
1853}
1854
1855define <2 x i1> @nsw_slt1_splat_vec(<2 x i8> %a) {
1856; CHECK-LABEL: @nsw_slt1_splat_vec(
1857; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i8> [[A:%.*]], splat (i8 -128)
1858; CHECK-NEXT:    ret <2 x i1> [[C]]
1859;
1860  %b = add nsw <2 x i8> %a, <i8 100, i8 100>
1861  %c = icmp slt <2 x i8> %b, <i8 -27, i8 -27>
1862  ret <2 x i1> %c
1863}
1864
1865; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow.
1866; This becomes equality because it's at the limit.
1867
1868define i1 @nsw_slt2(i8 %a) {
1869; CHECK-LABEL: @nsw_slt2(
1870; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A:%.*]], 127
1871; CHECK-NEXT:    ret i1 [[C]]
1872;
1873  %b = add nsw i8 %a, -100
1874  %c = icmp slt i8 %b, 27
1875  ret i1 %c
1876}
1877
1878define <2 x i1> @nsw_slt2_splat_vec(<2 x i8> %a) {
1879; CHECK-LABEL: @nsw_slt2_splat_vec(
1880; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i8> [[A:%.*]], splat (i8 127)
1881; CHECK-NEXT:    ret <2 x i1> [[C]]
1882;
1883  %b = add nsw <2 x i8> %a, <i8 -100, i8 -100>
1884  %c = icmp slt <2 x i8> %b, <i8 27, i8 27>
1885  ret <2 x i1> %c
1886}
1887
1888; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow.
1889; Less than the limit, so the predicate doesn't change.
1890
1891define i1 @nsw_slt3(i8 %a) {
1892; CHECK-LABEL: @nsw_slt3(
1893; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 [[A:%.*]], -126
1894; CHECK-NEXT:    ret i1 [[C]]
1895;
1896  %b = add nsw i8 %a, 100
1897  %c = icmp slt i8 %b, -26
1898  ret i1 %c
1899}
1900
1901; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow.
1902; Less than the limit, so the predicate doesn't change.
1903
1904define i1 @nsw_slt4(i8 %a) {
1905; CHECK-LABEL: @nsw_slt4(
1906; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 [[A:%.*]], 126
1907; CHECK-NEXT:    ret i1 [[C]]
1908;
1909  %b = add nsw i8 %a, -100
1910  %c = icmp slt i8 %b, 26
1911  ret i1 %c
1912}
1913
1914; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow.
1915; Try sgt to make sure that works too.
1916
1917define i1 @nsw_sgt1(i8 %a) {
1918; CHECK-LABEL: @nsw_sgt1(
1919; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A:%.*]], 127
1920; CHECK-NEXT:    ret i1 [[C]]
1921;
1922  %b = add nsw i8 %a, -100
1923  %c = icmp sgt i8 %b, 26
1924  ret i1 %c
1925}
1926
1927define <2 x i1> @nsw_sgt1_splat_vec(<2 x i8> %a) {
1928; CHECK-LABEL: @nsw_sgt1_splat_vec(
1929; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i8> [[A:%.*]], splat (i8 127)
1930; CHECK-NEXT:    ret <2 x i1> [[C]]
1931;
1932  %b = add nsw <2 x i8> %a, <i8 -100, i8 -100>
1933  %c = icmp sgt <2 x i8> %b, <i8 26, i8 26>
1934  ret <2 x i1> %c
1935}
1936
1937define i1 @nsw_sgt2(i8 %a) {
1938; CHECK-LABEL: @nsw_sgt2(
1939; CHECK-NEXT:    [[C:%.*]] = icmp sgt i8 [[A:%.*]], -126
1940; CHECK-NEXT:    ret i1 [[C]]
1941;
1942  %b = add nsw i8 %a, 100
1943  %c = icmp sgt i8 %b, -26
1944  ret i1 %c
1945}
1946
1947define <2 x i1> @nsw_sgt2_splat_vec(<2 x i8> %a) {
1948; CHECK-LABEL: @nsw_sgt2_splat_vec(
1949; CHECK-NEXT:    [[C:%.*]] = icmp sgt <2 x i8> [[A:%.*]], splat (i8 -126)
1950; CHECK-NEXT:    ret <2 x i1> [[C]]
1951;
1952  %b = add nsw <2 x i8> %a, <i8 100, i8 100>
1953  %c = icmp sgt <2 x i8> %b, <i8 -26, i8 -26>
1954  ret <2 x i1> %c
1955}
1956
1957; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow.
1958; Comparison with 0 doesn't need special-casing.
1959
1960define i1 @slt_zero_add_nsw(i32 %a) {
1961; CHECK-LABEL: @slt_zero_add_nsw(
1962; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A:%.*]], -1
1963; CHECK-NEXT:    ret i1 [[CMP]]
1964;
1965  %add = add nsw i32 %a, 1
1966  %cmp = icmp slt i32 %add, 0
1967  ret i1 %cmp
1968}
1969
1970; The same fold should work with vectors.
1971
1972define <2 x i1> @slt_zero_add_nsw_splat_vec(<2 x i8> %a) {
1973; CHECK-LABEL: @slt_zero_add_nsw_splat_vec(
1974; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], splat (i8 -1)
1975; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1976;
1977  %add = add nsw <2 x i8> %a, <i8 1, i8 1>
1978  %cmp = icmp slt <2 x i8> %add, zeroinitializer
1979  ret <2 x i1> %cmp
1980}
1981
1982; Test the edges - instcombine should not interfere with simplification to constants.
1983; Constant subtraction does not overflow, but this is false.
1984
1985define i1 @nsw_slt3_ov_no(i8 %a) {
1986; CHECK-LABEL: @nsw_slt3_ov_no(
1987; CHECK-NEXT:    ret i1 false
1988;
1989  %b = add nsw i8 %a, 100
1990  %c = icmp slt i8 %b, -28
1991  ret i1 %c
1992}
1993
1994; Test the edges - instcombine should not interfere with simplification to constants.
1995; Constant subtraction overflows. This is false.
1996
1997define i1 @nsw_slt4_ov(i8 %a) {
1998; CHECK-LABEL: @nsw_slt4_ov(
1999; CHECK-NEXT:    ret i1 false
2000;
2001  %b = add nsw i8 %a, 100
2002  %c = icmp slt i8 %b, -29
2003  ret i1 %c
2004}
2005
2006; Test the edges - instcombine should not interfere with simplification to constants.
2007; Constant subtraction overflows. This is true.
2008
2009define i1 @nsw_slt5_ov(i8 %a) {
2010; CHECK-LABEL: @nsw_slt5_ov(
2011; CHECK-NEXT:    ret i1 true
2012;
2013  %b = add nsw i8 %a, -100
2014  %c = icmp slt i8 %b, 28
2015  ret i1 %c
2016}
2017
2018; InstCombine should not thwart this opportunity to simplify completely.
2019
2020define i1 @slt_zero_add_nsw_signbit(i8 %x) {
2021; CHECK-LABEL: @slt_zero_add_nsw_signbit(
2022; CHECK-NEXT:    ret i1 true
2023;
2024  %y = add nsw i8 %x, -128
2025  %z = icmp slt i8 %y, 0
2026  ret i1 %z
2027}
2028
2029; InstCombine should not thwart this opportunity to simplify completely.
2030
2031define i1 @slt_zero_add_nuw_signbit(i8 %x) {
2032; CHECK-LABEL: @slt_zero_add_nuw_signbit(
2033; CHECK-NEXT:    ret i1 true
2034;
2035  %y = add nuw i8 %x, 128
2036  %z = icmp slt i8 %y, 0
2037  ret i1 %z
2038}
2039
2040define i1 @reduce_add_ult(i32 %in) {
2041; CHECK-LABEL: @reduce_add_ult(
2042; CHECK-NEXT:    [[A18:%.*]] = icmp ult i32 [[IN:%.*]], 9
2043; CHECK-NEXT:    ret i1 [[A18]]
2044;
2045  %a6 = add nuw i32 %in, 3
2046  %a18 = icmp ult i32 %a6, 12
2047  ret i1 %a18
2048}
2049
2050define i1 @reduce_add_ugt(i32 %in) {
2051; CHECK-LABEL: @reduce_add_ugt(
2052; CHECK-NEXT:    [[A18:%.*]] = icmp ugt i32 [[IN:%.*]], 9
2053; CHECK-NEXT:    ret i1 [[A18]]
2054;
2055  %a6 = add nuw i32 %in, 3
2056  %a18 = icmp ugt i32 %a6, 12
2057  ret i1 %a18
2058}
2059
2060define i1 @reduce_add_ule(i32 %in) {
2061; CHECK-LABEL: @reduce_add_ule(
2062; CHECK-NEXT:    [[A18:%.*]] = icmp ult i32 [[IN:%.*]], 10
2063; CHECK-NEXT:    ret i1 [[A18]]
2064;
2065  %a6 = add nuw i32 %in, 3
2066  %a18 = icmp ule i32 %a6, 12
2067  ret i1 %a18
2068}
2069
2070define i1 @reduce_add_uge(i32 %in) {
2071; CHECK-LABEL: @reduce_add_uge(
2072; CHECK-NEXT:    [[A18:%.*]] = icmp ugt i32 [[IN:%.*]], 8
2073; CHECK-NEXT:    ret i1 [[A18]]
2074;
2075  %a6 = add nuw i32 %in, 3
2076  %a18 = icmp uge i32 %a6, 12
2077  ret i1 %a18
2078}
2079
2080define i1 @ult_add_ssubov(i32 %in) {
2081; CHECK-LABEL: @ult_add_ssubov(
2082; CHECK-NEXT:    ret i1 false
2083;
2084  %a6 = add nuw i32 %in, 71
2085  %a18 = icmp ult i32 %a6, 3
2086  ret i1 %a18
2087}
2088
2089define i1 @ult_add_nonuw(i8 %in) {
2090; CHECK-LABEL: @ult_add_nonuw(
2091; CHECK-NEXT:    [[A6:%.*]] = add i8 [[IN:%.*]], 71
2092; CHECK-NEXT:    [[A18:%.*]] = icmp ult i8 [[A6]], 12
2093; CHECK-NEXT:    ret i1 [[A18]]
2094;
2095  %a6 = add i8 %in, 71
2096  %a18 = icmp ult i8 %a6, 12
2097  ret i1 %a18
2098}
2099
2100define i1 @uge_add_nonuw(i32 %in) {
2101; CHECK-LABEL: @uge_add_nonuw(
2102; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[IN:%.*]], -9
2103; CHECK-NEXT:    [[A18:%.*]] = icmp ult i32 [[TMP1]], -12
2104; CHECK-NEXT:    ret i1 [[A18]]
2105;
2106  %a6 = add i32 %in, 3
2107  %a18 = icmp uge i32 %a6, 12
2108  ret i1 %a18
2109}
2110
2111; Test unsigned add overflow patterns. The div ops are only here to
2112; thwart complexity based canonicalization of the operand order.
2113
2114define i1 @op_ugt_sum_commute1(i8 %p1, i8 %p2) {
2115; CHECK-LABEL: @op_ugt_sum_commute1(
2116; CHECK-NEXT:    [[X:%.*]] = sdiv i8 42, [[P1:%.*]]
2117; CHECK-NEXT:    [[Y:%.*]] = sdiv i8 42, [[P2:%.*]]
2118; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[X]], -1
2119; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 [[Y]], [[TMP1]]
2120; CHECK-NEXT:    ret i1 [[C]]
2121;
2122  %x = sdiv i8 42, %p1
2123  %y = sdiv i8 42, %p2
2124  %a = add i8 %x, %y
2125  %c = icmp ugt i8 %x, %a
2126  ret i1 %c
2127}
2128
2129define <2 x i1> @op_ugt_sum_vec_commute2(<2 x i8> %p1, <2 x i8> %p2) {
2130; CHECK-LABEL: @op_ugt_sum_vec_commute2(
2131; CHECK-NEXT:    [[X:%.*]] = sdiv <2 x i8> <i8 42, i8 -42>, [[P1:%.*]]
2132; CHECK-NEXT:    [[Y:%.*]] = sdiv <2 x i8> <i8 42, i8 -42>, [[P2:%.*]]
2133; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i8> [[X]], splat (i8 -1)
2134; CHECK-NEXT:    [[C:%.*]] = icmp ugt <2 x i8> [[Y]], [[TMP1]]
2135; CHECK-NEXT:    ret <2 x i1> [[C]]
2136;
2137  %x = sdiv <2 x i8> <i8 42, i8 -42>, %p1
2138  %y = sdiv <2 x i8> <i8 42, i8 -42>, %p2
2139  %a = add <2 x i8> %y, %x
2140  %c = icmp ugt <2 x i8> %x, %a
2141  ret <2 x i1> %c
2142}
2143
2144define i1 @sum_ugt_op_uses(i8 %p1, i8 %p2, ptr %p3) {
2145; CHECK-LABEL: @sum_ugt_op_uses(
2146; CHECK-NEXT:    [[X:%.*]] = sdiv i8 42, [[P1:%.*]]
2147; CHECK-NEXT:    [[Y:%.*]] = sdiv i8 42, [[P2:%.*]]
2148; CHECK-NEXT:    [[A:%.*]] = add nsw i8 [[X]], [[Y]]
2149; CHECK-NEXT:    store i8 [[A]], ptr [[P3:%.*]], align 1
2150; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 [[X]], [[A]]
2151; CHECK-NEXT:    ret i1 [[C]]
2152;
2153  %x = sdiv i8 42, %p1
2154  %y = sdiv i8 42, %p2
2155  %a = add i8 %x, %y
2156  store i8 %a, ptr %p3
2157  %c = icmp ugt i8 %x, %a
2158  ret i1 %c
2159}
2160
2161define <2 x i1> @sum_ult_op_vec_commute1(<2 x i8> %p1, <2 x i8> %p2) {
2162; CHECK-LABEL: @sum_ult_op_vec_commute1(
2163; CHECK-NEXT:    [[X:%.*]] = sdiv <2 x i8> <i8 42, i8 -42>, [[P1:%.*]]
2164; CHECK-NEXT:    [[Y:%.*]] = sdiv <2 x i8> <i8 -42, i8 42>, [[P2:%.*]]
2165; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i8> [[X]], splat (i8 -1)
2166; CHECK-NEXT:    [[C:%.*]] = icmp ugt <2 x i8> [[Y]], [[TMP1]]
2167; CHECK-NEXT:    ret <2 x i1> [[C]]
2168;
2169  %x = sdiv <2 x i8> <i8 42, i8 -42>, %p1
2170  %y = sdiv <2 x i8> <i8 -42, i8 42>, %p2
2171  %a = add <2 x i8> %x, %y
2172  %c = icmp ult <2 x i8> %a, %x
2173  ret <2 x i1> %c
2174}
2175
2176define i1 @sum_ult_op_commute2(i8 %p1, i8 %p2) {
2177; CHECK-LABEL: @sum_ult_op_commute2(
2178; CHECK-NEXT:    [[X:%.*]] = sdiv i8 42, [[P1:%.*]]
2179; CHECK-NEXT:    [[Y:%.*]] = sdiv i8 42, [[P2:%.*]]
2180; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[X]], -1
2181; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 [[Y]], [[TMP1]]
2182; CHECK-NEXT:    ret i1 [[C]]
2183;
2184  %x = sdiv i8 42, %p1
2185  %y = sdiv i8 42, %p2
2186  %a = add i8 %y, %x
2187  %c = icmp ult i8 %a, %x
2188  ret i1 %c
2189}
2190
2191define i1 @sum_ult_op_uses(i8 %x, i8 %y, ptr %p) {
2192; CHECK-LABEL: @sum_ult_op_uses(
2193; CHECK-NEXT:    [[A:%.*]] = add i8 [[Y:%.*]], [[X:%.*]]
2194; CHECK-NEXT:    store i8 [[A]], ptr [[P:%.*]], align 1
2195; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[A]], [[X]]
2196; CHECK-NEXT:    ret i1 [[C]]
2197;
2198  %a = add i8 %y, %x
2199  store i8 %a, ptr %p
2200  %c = icmp ult i8 %a, %x
2201  ret i1 %c
2202}
2203
2204; X + Z >s Y + Z -> X > Y if there is no overflow.
2205define i1 @common_op_nsw(i32 %x, i32 %y, i32 %z) {
2206; CHECK-LABEL: @common_op_nsw(
2207; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
2208; CHECK-NEXT:    ret i1 [[C]]
2209;
2210  %lhs = add nsw i32 %x, %z
2211  %rhs = add nsw i32 %y, %z
2212  %c = icmp sgt i32 %lhs, %rhs
2213  ret i1 %c
2214}
2215
2216define i1 @common_op_nsw_extra_uses(i32 %x, i32 %y, i32 %z) {
2217; CHECK-LABEL: @common_op_nsw_extra_uses(
2218; CHECK-NEXT:    [[LHS:%.*]] = add nsw i32 [[X:%.*]], [[Z:%.*]]
2219; CHECK-NEXT:    call void @use(i32 [[LHS]])
2220; CHECK-NEXT:    [[RHS:%.*]] = add nsw i32 [[Y:%.*]], [[Z]]
2221; CHECK-NEXT:    call void @use(i32 [[RHS]])
2222; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[X]], [[Y]]
2223; CHECK-NEXT:    ret i1 [[C]]
2224;
2225  %lhs = add nsw i32 %x, %z
2226  call void @use(i32 %lhs)
2227  %rhs = add nsw i32 %y, %z
2228  call void @use(i32 %rhs)
2229  %c = icmp sgt i32 %lhs, %rhs
2230  ret i1 %c
2231}
2232
2233; X + Z >u Z + Y -> X > Y if there is no overflow.
2234define i1 @common_op_nuw(i32 %x, i32 %y, i32 %z) {
2235; CHECK-LABEL: @common_op_nuw(
2236; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
2237; CHECK-NEXT:    ret i1 [[C]]
2238;
2239  %lhs = add nuw i32 %x, %z
2240  %rhs = add nuw i32 %z, %y
2241  %c = icmp ugt i32 %lhs, %rhs
2242  ret i1 %c
2243}
2244
2245define i1 @common_op_nuw_extra_uses(i32 %x, i32 %y, i32 %z) {
2246; CHECK-LABEL: @common_op_nuw_extra_uses(
2247; CHECK-NEXT:    [[LHS:%.*]] = add nuw i32 [[X:%.*]], [[Z:%.*]]
2248; CHECK-NEXT:    call void @use(i32 [[LHS]])
2249; CHECK-NEXT:    [[RHS:%.*]] = add nuw i32 [[Z]], [[Y:%.*]]
2250; CHECK-NEXT:    call void @use(i32 [[RHS]])
2251; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[X]], [[Y]]
2252; CHECK-NEXT:    ret i1 [[C]]
2253;
2254  %lhs = add nuw i32 %x, %z
2255  call void @use(i32 %lhs)
2256  %rhs = add nuw i32 %z, %y
2257  call void @use(i32 %rhs)
2258  %c = icmp ugt i32 %lhs, %rhs
2259  ret i1 %c
2260}
2261
2262define i1 @common_op_nsw_commute(i32 %x, i32 %y, i32 %z) {
2263; CHECK-LABEL: @common_op_nsw_commute(
2264; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
2265; CHECK-NEXT:    ret i1 [[C]]
2266;
2267  %lhs = add nsw i32 %z, %x
2268  %rhs = add nsw i32 %y, %z
2269  %c = icmp slt i32 %lhs, %rhs
2270  ret i1 %c
2271}
2272
2273define i1 @common_op_nuw_commute(i32 %x, i32 %y, i32 %z) {
2274; CHECK-LABEL: @common_op_nuw_commute(
2275; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
2276; CHECK-NEXT:    ret i1 [[C]]
2277;
2278  %lhs = add nuw i32 %z, %x
2279  %rhs = add nuw i32 %z, %y
2280  %c = icmp ult i32 %lhs, %rhs
2281  ret i1 %c
2282}
2283
2284; X + Y > X -> Y > 0 if there is no overflow.
2285define i1 @common_op_test29(i32 %x, i32 %y) {
2286; CHECK-LABEL: @common_op_test29(
2287; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[Y:%.*]], 0
2288; CHECK-NEXT:    ret i1 [[C]]
2289;
2290  %lhs = add nsw i32 %x, %y
2291  %c = icmp sgt i32 %lhs, %x
2292  ret i1 %c
2293}
2294
2295; X + Y > X -> Y > 0 if there is no overflow.
2296define i1 @sum_nuw(i32 %x, i32 %y) {
2297; CHECK-LABEL: @sum_nuw(
2298; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[Y:%.*]], 0
2299; CHECK-NEXT:    ret i1 [[C]]
2300;
2301  %lhs = add nuw i32 %x, %y
2302  %c = icmp ugt i32 %lhs, %x
2303  ret i1 %c
2304}
2305
2306; X > X + Y -> 0 > Y if there is no overflow.
2307define i1 @sum_nsw_commute(i32 %x, i32 %y) {
2308; CHECK-LABEL: @sum_nsw_commute(
2309; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[Y:%.*]], 0
2310; CHECK-NEXT:    ret i1 [[C]]
2311;
2312  %rhs = add nsw i32 %x, %y
2313  %c = icmp sgt i32 %x, %rhs
2314  ret i1 %c
2315}
2316
2317; X > X + Y -> 0 > Y if there is no overflow.
2318define i1 @sum_nuw_commute(i32 %x, i32 %y) {
2319; CHECK-LABEL: @sum_nuw_commute(
2320; CHECK-NEXT:    ret i1 false
2321;
2322  %rhs = add nuw i32 %x, %y
2323  %c = icmp ugt i32 %x, %rhs
2324  ret i1 %c
2325}
2326
2327; PR2698 - https://bugs.llvm.org/show_bug.cgi?id=2698
2328
2329declare void @use1(i1)
2330declare void @use8(i8)
2331
2332define void @bzip1(i8 %a, i8 %b, i8 %x) {
2333; CHECK-LABEL: @bzip1(
2334; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], [[B:%.*]]
2335; CHECK-NEXT:    call void @use1(i1 [[CMP]])
2336; CHECK-NEXT:    ret void
2337;
2338  %add1 = add i8 %a, %x
2339  %add2 = add i8 %b, %x
2340  %cmp = icmp eq i8 %add1, %add2
2341  call void @use1(i1 %cmp)
2342  ret void
2343}
2344
2345define void @bzip2(i8 %a, i8 %b, i8 %x) {
2346; CHECK-LABEL: @bzip2(
2347; CHECK-NEXT:    [[ADD1:%.*]] = add i8 [[A:%.*]], [[X:%.*]]
2348; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A]], [[B:%.*]]
2349; CHECK-NEXT:    call void @use1(i1 [[CMP]])
2350; CHECK-NEXT:    call void @use8(i8 [[ADD1]])
2351; CHECK-NEXT:    ret void
2352;
2353  %add1 = add i8 %a, %x
2354  %add2 = add i8 %b, %x
2355  %cmp = icmp eq i8 %add1, %add2
2356  call void @use1(i1 %cmp)
2357  call void @use8(i8 %add1)
2358  ret void
2359}
2360
2361define <2 x i1> @icmp_eq_add_undef(<2 x i32> %a) {
2362; CHECK-LABEL: @icmp_eq_add_undef(
2363; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 5, i32 undef>
2364; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2365;
2366  %add = add <2 x i32> %a, <i32 5, i32 undef>
2367  %cmp = icmp eq <2 x i32> %add, <i32 10, i32 10>
2368  ret <2 x i1> %cmp
2369}
2370
2371define <2 x i1> @icmp_eq_add_non_splat(<2 x i32> %a) {
2372; CHECK-LABEL: @icmp_eq_add_non_splat(
2373; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 5, i32 4>
2374; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2375;
2376  %add = add <2 x i32> %a, <i32 5, i32 6>
2377  %cmp = icmp eq <2 x i32> %add, <i32 10, i32 10>
2378  ret <2 x i1> %cmp
2379}
2380
2381define <2 x i1> @icmp_eq_add_undef2(<2 x i32> %a) {
2382; CHECK-LABEL: @icmp_eq_add_undef2(
2383; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i32> [[A:%.*]], splat (i32 5)
2384; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[ADD]], <i32 10, i32 undef>
2385; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2386;
2387  %add = add <2 x i32> %a, <i32 5, i32 5>
2388  %cmp = icmp eq <2 x i32> %add, <i32 10, i32 undef>
2389  ret <2 x i1> %cmp
2390}
2391
2392define <2 x i1> @icmp_eq_add_non_splat2(<2 x i32> %a) {
2393; CHECK-LABEL: @icmp_eq_add_non_splat2(
2394; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i32> [[A:%.*]], splat (i32 5)
2395; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[ADD]], <i32 10, i32 11>
2396; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2397;
2398  %add = add <2 x i32> %a, <i32 5, i32 5>
2399  %cmp = icmp eq <2 x i32> %add, <i32 10, i32 11>
2400  ret <2 x i1> %cmp
2401}
2402
2403define i1 @without_nsw_nuw(i8 %x, i8 %y) {
2404; CHECK-LABEL: @without_nsw_nuw(
2405; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[X:%.*]], 2
2406; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8 [[Y:%.*]], [[TMP1]]
2407; CHECK-NEXT:    ret i1 [[TOBOOL]]
2408;
2409  %t1 = add i8 %x, 37
2410  %t2 = add i8 %y, 35
2411  %tobool = icmp eq i8 %t2, %t1
2412  ret i1 %tobool
2413}
2414
2415define i1 @with_nsw_nuw(i8 %x, i8 %y) {
2416; CHECK-LABEL: @with_nsw_nuw(
2417; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i8 [[X:%.*]], 2
2418; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8 [[Y:%.*]], [[TMP1]]
2419; CHECK-NEXT:    ret i1 [[TOBOOL]]
2420;
2421  %t1 = add nsw nuw i8 %x, 37
2422  %t2 = add i8 %y, 35
2423  %tobool = icmp eq i8 %t2, %t1
2424  ret i1 %tobool
2425}
2426
2427define i1 @with_nsw_large(i8 %x, i8 %y) {
2428; CHECK-LABEL: @with_nsw_large(
2429; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i8 [[X:%.*]], 2
2430; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8 [[Y:%.*]], [[TMP1]]
2431; CHECK-NEXT:    ret i1 [[TOBOOL]]
2432;
2433  %t1 = add nsw i8 %x, 37
2434  %t2 = add i8 %y, 35
2435  %tobool = icmp eq i8 %t2, %t1
2436  ret i1 %tobool
2437}
2438
2439define i1 @with_nsw_small(i8 %x, i8 %y) {
2440; CHECK-LABEL: @with_nsw_small(
2441; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y:%.*]], 2
2442; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8 [[TMP1]], [[X:%.*]]
2443; CHECK-NEXT:    ret i1 [[TOBOOL]]
2444;
2445  %t1 = add nsw i8 %x, 35
2446  %t2 = add i8 %y, 37
2447  %tobool = icmp eq i8 %t2, %t1
2448  ret i1 %tobool
2449}
2450
2451define i1 @with_nuw_large(i8 %x, i8 %y) {
2452; CHECK-LABEL: @with_nuw_large(
2453; CHECK-NEXT:    [[TMP1:%.*]] = add nuw i8 [[X:%.*]], 2
2454; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8 [[Y:%.*]], [[TMP1]]
2455; CHECK-NEXT:    ret i1 [[TOBOOL]]
2456;
2457  %t1 = add nuw i8 %x, 37
2458  %t2 = add i8 %y, 35
2459  %tobool = icmp eq i8 %t2, %t1
2460  ret i1 %tobool
2461}
2462
2463define i1 @with_nuw_small(i8 %x, i8 %y) {
2464; CHECK-LABEL: @with_nuw_small(
2465; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y:%.*]], 2
2466; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8 [[TMP1]], [[X:%.*]]
2467; CHECK-NEXT:    ret i1 [[TOBOOL]]
2468;
2469  %t1 = add nuw i8 %x, 35
2470  %t2 = add i8 %y, 37
2471  %tobool = icmp eq i8 %t2, %t1
2472  ret i1 %tobool
2473}
2474
2475define i1 @with_nuw_large_negative(i8 %x, i8 %y) {
2476; CHECK-LABEL: @with_nuw_large_negative(
2477; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[X:%.*]], -2
2478; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8 [[Y:%.*]], [[TMP1]]
2479; CHECK-NEXT:    ret i1 [[TOBOOL]]
2480;
2481  %t1 = add nuw i8 %x, -37
2482  %t2 = add i8 %y, -35
2483  %tobool = icmp eq i8 %t2, %t1
2484  ret i1 %tobool
2485}
2486
2487define i1 @ugt_offset(i8 %a) {
2488; CHECK-LABEL: @ugt_offset(
2489; CHECK-NEXT:    [[OV:%.*]] = icmp slt i8 [[A:%.*]], -124
2490; CHECK-NEXT:    ret i1 [[OV]]
2491;
2492  %t = add i8 %a, 124
2493  %ov = icmp ugt i8 %t, 251
2494  ret i1 %ov
2495}
2496
2497define i1 @ugt_offset_use(i32 %a) {
2498; CHECK-LABEL: @ugt_offset_use(
2499; CHECK-NEXT:    [[T:%.*]] = add i32 [[A:%.*]], 42
2500; CHECK-NEXT:    call void @use(i32 [[T]])
2501; CHECK-NEXT:    [[OV:%.*]] = icmp slt i32 [[A]], -42
2502; CHECK-NEXT:    ret i1 [[OV]]
2503;
2504  %t = add i32 %a, 42
2505  call void @use(i32 %t)
2506  %ov = icmp ugt i32 %t, 2147483689
2507  ret i1 %ov
2508}
2509
2510define <2 x i1> @ugt_offset_splat(<2 x i5> %a) {
2511; CHECK-LABEL: @ugt_offset_splat(
2512; CHECK-NEXT:    [[OV:%.*]] = icmp slt <2 x i5> [[A:%.*]], splat (i5 -9)
2513; CHECK-NEXT:    ret <2 x i1> [[OV]]
2514;
2515  %t = add <2 x i5> %a, <i5 9, i5 9>
2516  %ov = icmp ugt <2 x i5> %t, <i5 24, i5 24>
2517  ret <2 x i1> %ov
2518}
2519
2520; negative test - constants must differ by SMAX
2521
2522define i1 @ugt_wrong_offset(i8 %a) {
2523; CHECK-LABEL: @ugt_wrong_offset(
2524; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[A:%.*]], 127
2525; CHECK-NEXT:    [[OV:%.*]] = icmp ult i8 [[TMP1]], 4
2526; CHECK-NEXT:    ret i1 [[OV]]
2527;
2528  %t = add i8 %a, 123
2529  %ov = icmp ugt i8 %t, 251
2530  ret i1 %ov
2531}
2532
2533define i1 @ugt_offset_nuw(i8 %a) {
2534; CHECK-LABEL: @ugt_offset_nuw(
2535; CHECK-NEXT:    [[OV:%.*]] = icmp slt i8 [[A:%.*]], 0
2536; CHECK-NEXT:    ret i1 [[OV]]
2537;
2538  %t = add nuw i8 %a, 124
2539  %ov = icmp ugt i8 %t, 251
2540  ret i1 %ov
2541}
2542
2543define i1 @ult_offset(i8 %a) {
2544; CHECK-LABEL: @ult_offset(
2545; CHECK-NEXT:    [[OV:%.*]] = icmp sgt i8 [[A:%.*]], 5
2546; CHECK-NEXT:    ret i1 [[OV]]
2547;
2548  %t = add i8 %a, 250
2549  %ov = icmp ult i8 %t, 122
2550  ret i1 %ov
2551}
2552
2553define i1 @ult_offset_use(i32 %a) {
2554; CHECK-LABEL: @ult_offset_use(
2555; CHECK-NEXT:    [[T:%.*]] = add i32 [[A:%.*]], 42
2556; CHECK-NEXT:    call void @use(i32 [[T]])
2557; CHECK-NEXT:    [[OV:%.*]] = icmp sgt i32 [[A]], -43
2558; CHECK-NEXT:    ret i1 [[OV]]
2559;
2560  %t = add i32 %a, 42
2561  call void @use(i32 %t)
2562  %ov = icmp ult i32 %t, 2147483690
2563  ret i1 %ov
2564}
2565
2566define <2 x i1> @ult_offset_splat(<2 x i5> %a) {
2567; CHECK-LABEL: @ult_offset_splat(
2568; CHECK-NEXT:    [[OV:%.*]] = icmp sgt <2 x i5> [[A:%.*]], splat (i5 -10)
2569; CHECK-NEXT:    ret <2 x i1> [[OV]]
2570;
2571  %t = add <2 x i5> %a, <i5 9, i5 9>
2572  %ov = icmp ult <2 x i5> %t, <i5 25, i5 25>
2573  ret <2 x i1> %ov
2574}
2575
2576; negative test - constants must differ by SMIN
2577
2578define i1 @ult_wrong_offset(i8 %a) {
2579; CHECK-LABEL: @ult_wrong_offset(
2580; CHECK-NEXT:    [[T:%.*]] = add i8 [[A:%.*]], -6
2581; CHECK-NEXT:    [[OV:%.*]] = icmp ult i8 [[T]], 123
2582; CHECK-NEXT:    ret i1 [[OV]]
2583;
2584  %t = add i8 %a, 250
2585  %ov = icmp ult i8 %t, 123
2586  ret i1 %ov
2587}
2588
2589define i1 @ult_offset_nuw(i8 %a) {
2590; CHECK-LABEL: @ult_offset_nuw(
2591; CHECK-NEXT:    [[OV:%.*]] = icmp sgt i8 [[A:%.*]], -1
2592; CHECK-NEXT:    ret i1 [[OV]]
2593;
2594  %t = add nuw i8 %a, 42
2595  %ov = icmp ult i8 %t, 170
2596  ret i1 %ov
2597}
2598
2599define i1 @sgt_offset(i8 %a) {
2600; CHECK-LABEL: @sgt_offset(
2601; CHECK-NEXT:    [[OV:%.*]] = icmp ult i8 [[A:%.*]], -122
2602; CHECK-NEXT:    ret i1 [[OV]]
2603;
2604  %t = add i8 %a, -6
2605  %ov = icmp sgt i8 %t, -7
2606  ret i1 %ov
2607}
2608
2609define i1 @sgt_offset_use(i32 %a) {
2610; CHECK-LABEL: @sgt_offset_use(
2611; CHECK-NEXT:    [[T:%.*]] = add i32 [[A:%.*]], 42
2612; CHECK-NEXT:    call void @use(i32 [[T]])
2613; CHECK-NEXT:    [[OV:%.*]] = icmp ult i32 [[A]], 2147483606
2614; CHECK-NEXT:    ret i1 [[OV]]
2615;
2616  %t = add i32 %a, 42
2617  call void @use(i32 %t)
2618  %ov = icmp sgt i32 %t, 41
2619  ret i1 %ov
2620}
2621
2622define <2 x i1> @sgt_offset_splat(<2 x i5> %a) {
2623; CHECK-LABEL: @sgt_offset_splat(
2624; CHECK-NEXT:    [[OV:%.*]] = icmp ult <2 x i5> [[A:%.*]], splat (i5 7)
2625; CHECK-NEXT:    ret <2 x i1> [[OV]]
2626;
2627  %t = add <2 x i5> %a, <i5 9, i5 9>
2628  %ov = icmp sgt <2 x i5> %t, <i5 8, i5 8>
2629  ret <2 x i1> %ov
2630}
2631
2632; negative test - constants must differ by 1
2633
2634define i1 @sgt_wrong_offset(i8 %a) {
2635; CHECK-LABEL: @sgt_wrong_offset(
2636; CHECK-NEXT:    [[T:%.*]] = add i8 [[A:%.*]], -7
2637; CHECK-NEXT:    [[OV:%.*]] = icmp sgt i8 [[T]], -7
2638; CHECK-NEXT:    ret i1 [[OV]]
2639;
2640  %t = add i8 %a, -7
2641  %ov = icmp sgt i8 %t, -7
2642  ret i1 %ov
2643}
2644
2645define i1 @sgt_offset_nsw(i8 %a, i8 %c) {
2646; CHECK-LABEL: @sgt_offset_nsw(
2647; CHECK-NEXT:    [[OV:%.*]] = icmp sgt i8 [[A:%.*]], -1
2648; CHECK-NEXT:    ret i1 [[OV]]
2649;
2650  %t = add nsw i8 %a, 42
2651  %ov = icmp sgt i8 %t, 41
2652  ret i1 %ov
2653}
2654
2655define i1 @slt_offset(i8 %a) {
2656; CHECK-LABEL: @slt_offset(
2657; CHECK-NEXT:    [[OV:%.*]] = icmp ugt i8 [[A:%.*]], -123
2658; CHECK-NEXT:    ret i1 [[OV]]
2659;
2660  %t = add i8 %a, -6
2661  %ov = icmp slt i8 %t, -6
2662  ret i1 %ov
2663}
2664
2665define i1 @slt_offset_use(i32 %a) {
2666; CHECK-LABEL: @slt_offset_use(
2667; CHECK-NEXT:    [[T:%.*]] = add i32 [[A:%.*]], 42
2668; CHECK-NEXT:    call void @use(i32 [[T]])
2669; CHECK-NEXT:    [[OV:%.*]] = icmp ugt i32 [[A]], 2147483605
2670; CHECK-NEXT:    ret i1 [[OV]]
2671;
2672  %t = add i32 %a, 42
2673  call void @use(i32 %t)
2674  %ov = icmp slt i32 %t, 42
2675  ret i1 %ov
2676}
2677
2678define <2 x i1> @slt_offset_splat(<2 x i5> %a) {
2679; CHECK-LABEL: @slt_offset_splat(
2680; CHECK-NEXT:    [[OV:%.*]] = icmp ugt <2 x i5> [[A:%.*]], splat (i5 6)
2681; CHECK-NEXT:    ret <2 x i1> [[OV]]
2682;
2683  %t = add <2 x i5> %a, <i5 9, i5 9>
2684  %ov = icmp slt <2 x i5> %t, <i5 9, i5 9>
2685  ret <2 x i1> %ov
2686}
2687
2688; negative test - constants must be equal
2689
2690define i1 @slt_wrong_offset(i8 %a) {
2691; CHECK-LABEL: @slt_wrong_offset(
2692; CHECK-NEXT:    [[T:%.*]] = add i8 [[A:%.*]], -6
2693; CHECK-NEXT:    [[OV:%.*]] = icmp slt i8 [[T]], -7
2694; CHECK-NEXT:    ret i1 [[OV]]
2695;
2696  %t = add i8 %a, -6
2697  %ov = icmp slt i8 %t, -7
2698  ret i1 %ov
2699}
2700
2701define i1 @slt_offset_nsw(i8 %a, i8 %c) {
2702; CHECK-LABEL: @slt_offset_nsw(
2703; CHECK-NEXT:    [[OV:%.*]] = icmp slt i8 [[A:%.*]], 0
2704; CHECK-NEXT:    ret i1 [[OV]]
2705;
2706  %t = add nsw i8 %a, 42
2707  %ov = icmp slt i8 %t, 42
2708  ret i1 %ov
2709}
2710
2711; In the following 4 tests, we could push the inc/dec
2712; through the min/max, but we should not break up the
2713; min/max idiom by using different icmp and select
2714; operands.
2715
2716define i32 @increment_max(i32 %x) {
2717; CHECK-LABEL: @increment_max(
2718; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 -1)
2719; CHECK-NEXT:    [[S:%.*]] = add nsw i32 [[TMP1]], 1
2720; CHECK-NEXT:    ret i32 [[S]]
2721;
2722  %a = add nsw i32 %x, 1
2723  %c = icmp sgt i32 %a, 0
2724  %s = select i1 %c, i32 %a, i32 0
2725  ret i32 %s
2726}
2727
2728define i32 @decrement_max(i32 %x) {
2729; CHECK-LABEL: @decrement_max(
2730; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 1)
2731; CHECK-NEXT:    [[S:%.*]] = add nsw i32 [[TMP1]], -1
2732; CHECK-NEXT:    ret i32 [[S]]
2733;
2734  %a = add nsw i32 %x, -1
2735  %c = icmp sgt i32 %a, 0
2736  %s = select i1 %c, i32 %a, i32 0
2737  ret i32 %s
2738}
2739
2740define i32 @increment_min(i32 %x) {
2741; CHECK-LABEL: @increment_min(
2742; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 -1)
2743; CHECK-NEXT:    [[S:%.*]] = add nsw i32 [[TMP1]], 1
2744; CHECK-NEXT:    ret i32 [[S]]
2745;
2746  %a = add nsw i32 %x, 1
2747  %c = icmp slt i32 %a, 0
2748  %s = select i1 %c, i32 %a, i32 0
2749  ret i32 %s
2750}
2751
2752define i32 @decrement_min(i32 %x) {
2753; CHECK-LABEL: @decrement_min(
2754; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 1)
2755; CHECK-NEXT:    [[S:%.*]] = add nsw i32 [[TMP1]], -1
2756; CHECK-NEXT:    ret i32 [[S]]
2757;
2758  %a = add nsw i32 %x, -1
2759  %c = icmp slt i32 %a, 0
2760  %s = select i1 %c, i32 %a, i32 0
2761  ret i32 %s
2762}
2763
2764define i1 @icmp_add_add_C(i32 %a, i32 %b) {
2765; CHECK-LABEL: @icmp_add_add_C(
2766; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[B:%.*]]
2767; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], [[TMP1]]
2768; CHECK-NEXT:    ret i1 [[CMP]]
2769;
2770  %add1 = add i32 %a, %b
2771  %add2 = add i32 %add1, -1
2772  %cmp = icmp ult i32 %add2, %a
2773  ret i1 %cmp
2774}
2775
2776define i1 @icmp_add_add_C_pred(i32 %a, i32 %b) {
2777; CHECK-LABEL: @icmp_add_add_C_pred(
2778; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[B:%.*]]
2779; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[A:%.*]], [[TMP1]]
2780; CHECK-NEXT:    ret i1 [[CMP]]
2781;
2782  %add1 = add i32 %a, %b
2783  %add2 = add i32 %add1, -1
2784  %cmp = icmp uge i32 %add2, %a
2785  ret i1 %cmp
2786}
2787
2788define i1 @icmp_add_add_C_wrong_pred(i32 %a, i32 %b) {
2789; CHECK-LABEL: @icmp_add_add_C_wrong_pred(
2790; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
2791; CHECK-NEXT:    [[ADD2:%.*]] = add i32 [[ADD1]], -1
2792; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[ADD2]], [[A]]
2793; CHECK-NEXT:    ret i1 [[CMP]]
2794;
2795  %add1 = add i32 %a, %b
2796  %add2 = add i32 %add1, -1
2797  %cmp = icmp ule i32 %add2, %a
2798  ret i1 %cmp
2799}
2800
2801define i1 @icmp_add_add_C_wrong_operand(i32 %a, i32 %b, i32 %c) {
2802; CHECK-LABEL: @icmp_add_add_C_wrong_operand(
2803; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
2804; CHECK-NEXT:    [[ADD2:%.*]] = add i32 [[ADD1]], -1
2805; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD2]], [[C:%.*]]
2806; CHECK-NEXT:    ret i1 [[CMP]]
2807;
2808  %add1 = add i32 %a, %b
2809  %add2 = add i32 %add1, -1
2810  %cmp = icmp ult i32 %add2, %c
2811  ret i1 %cmp
2812}
2813
2814define i1 @icmp_add_add_C_different_const(i32 %a, i32 %b) {
2815; CHECK-LABEL: @icmp_add_add_C_different_const(
2816; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 -43, [[B:%.*]]
2817; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[TMP1]], [[A:%.*]]
2818; CHECK-NEXT:    ret i1 [[CMP]]
2819;
2820  %add1 = add i32 %a, %b
2821  %add2 = add i32 %add1, 42
2822  %cmp = icmp ult i32 %add2, %a
2823  ret i1 %cmp
2824}
2825
2826define <2 x i1> @icmp_add_add_C_vector(<2 x i8> %a, <2 x i8> %b) {
2827; CHECK-LABEL: @icmp_add_add_C_vector(
2828; CHECK-NEXT:    [[TMP1:%.*]] = sub <2 x i8> <i8 -11, i8 -21>, [[B:%.*]]
2829; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i8> [[TMP1]], [[A:%.*]]
2830; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2831;
2832  %add1 = add <2 x i8> %a, %b
2833  %add2 = add <2 x i8> %add1, <i8 10, i8 20>
2834  %cmp = icmp ult <2 x i8> %add2, %a
2835  ret <2 x i1> %cmp
2836}
2837
2838define <2 x i1> @icmp_add_add_C_vector_undef(<2 x i8> %a, <2 x i8> %b) {
2839; CHECK-LABEL: @icmp_add_add_C_vector_undef(
2840; CHECK-NEXT:    [[TMP1:%.*]] = sub <2 x i8> <i8 -11, i8 undef>, [[B:%.*]]
2841; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i8> [[TMP1]], [[A:%.*]]
2842; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2843;
2844  %add1 = add <2 x i8> %a, %b
2845  %add2 = add <2 x i8> %add1, <i8 10, i8 undef>
2846  %cmp = icmp ult <2 x i8> %add2, %a
2847  ret <2 x i1> %cmp
2848}
2849
2850define i1 @icmp_add_add_C_comm1(i32 %a, i32 %b) {
2851; CHECK-LABEL: @icmp_add_add_C_comm1(
2852; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[B:%.*]]
2853; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], [[TMP1]]
2854; CHECK-NEXT:    ret i1 [[CMP]]
2855;
2856  %add1 = add i32 %b, %a
2857  %add2 = add i32 %add1, -1
2858  %cmp = icmp ult i32 %add2, %a
2859  ret i1 %cmp
2860}
2861
2862define i1 @icmp_add_add_C_comm2(i32 %X, i32 %b) {
2863; CHECK-LABEL: @icmp_add_add_C_comm2(
2864; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[X:%.*]]
2865; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[B:%.*]]
2866; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A]], [[TMP1]]
2867; CHECK-NEXT:    ret i1 [[CMP]]
2868;
2869  %a = udiv i32 42, %X ; thwart complexity-based canonicalization
2870  %add1 = add i32 %a, %b
2871  %add2 = add i32 %add1, -1
2872  %cmp = icmp ugt i32 %a, %add2
2873  ret i1 %cmp
2874}
2875
2876define i1 @icmp_add_add_C_comm2_pred(i32 %X, i32 %b) {
2877; CHECK-LABEL: @icmp_add_add_C_comm2_pred(
2878; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[X:%.*]]
2879; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[B:%.*]]
2880; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[A]], [[TMP1]]
2881; CHECK-NEXT:    ret i1 [[CMP]]
2882;
2883  %a = udiv i32 42, %X ; thwart complexity-based canonicalization
2884  %add1 = add i32 %a, %b
2885  %add2 = add i32 %add1, -1
2886  %cmp = icmp ule i32 %a, %add2
2887  ret i1 %cmp
2888}
2889
2890define i1 @icmp_add_add_C_comm2_wrong_pred(i32 %X, i32 %b) {
2891; CHECK-LABEL: @icmp_add_add_C_comm2_wrong_pred(
2892; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[X:%.*]]
2893; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[A]], [[B:%.*]]
2894; CHECK-NEXT:    [[ADD2:%.*]] = add i32 [[ADD1]], -1
2895; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A]], [[ADD2]]
2896; CHECK-NEXT:    ret i1 [[CMP]]
2897;
2898  %a = udiv i32 42, %X ; thwart complexity-based canonicalization
2899  %add1 = add i32 %a, %b
2900  %add2 = add i32 %add1, -1
2901  %cmp = icmp ult i32 %a, %add2
2902  ret i1 %cmp
2903}
2904
2905define i1 @icmp_add_add_C_comm3(i32 %X, i32 %b) {
2906; CHECK-LABEL: @icmp_add_add_C_comm3(
2907; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[X:%.*]]
2908; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[B:%.*]]
2909; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A]], [[TMP1]]
2910; CHECK-NEXT:    ret i1 [[CMP]]
2911;
2912  %a = udiv i32 42, %X ; thwart complexity-based canonicalization
2913  %add1 = add i32 %b, %a
2914  %add2 = add i32 %add1, -1
2915  %cmp = icmp ugt i32 %a, %add2
2916  ret i1 %cmp
2917}
2918
2919define i1 @icmp_add_add_C_extra_use1(i32 %a, i32 %b) {
2920; CHECK-LABEL: @icmp_add_add_C_extra_use1(
2921; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
2922; CHECK-NEXT:    [[ADD2:%.*]] = add i32 [[ADD1]], -1
2923; CHECK-NEXT:    call void @use(i32 [[ADD2]])
2924; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD2]], [[A]]
2925; CHECK-NEXT:    ret i1 [[CMP]]
2926;
2927  %add1 = add i32 %a, %b
2928  %add2 = add i32 %add1, -1
2929  call void @use(i32 %add2)
2930  %cmp = icmp ult i32 %add2, %a
2931  ret i1 %cmp
2932}
2933
2934define i1 @icmp_add_add_C_extra_use2(i32 %a, i32 %b) {
2935; CHECK-LABEL: @icmp_add_add_C_extra_use2(
2936; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
2937; CHECK-NEXT:    call void @use(i32 [[ADD1]])
2938; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[B]]
2939; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A]], [[TMP1]]
2940; CHECK-NEXT:    ret i1 [[CMP]]
2941;
2942  %add1 = add i32 %a, %b
2943  call void @use(i32 %add1)
2944  %add2 = add i32 %add1, -1
2945  %cmp = icmp ult i32 %add2, %a
2946  ret i1 %cmp
2947}
2948
2949; PR57635 - fold ULT->ULE pre-decrement of a non-zero inputs
2950
2951define i1 @icmp_dec_assume_nonzero(i8 %x) {
2952; CHECK-LABEL: @icmp_dec_assume_nonzero(
2953; CHECK-NEXT:    [[Z:%.*]] = icmp ne i8 [[X:%.*]], 0
2954; CHECK-NEXT:    call void @llvm.assume(i1 [[Z]])
2955; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[X]], 8
2956; CHECK-NEXT:    ret i1 [[C]]
2957;
2958  %z = icmp ne i8 %x, 0
2959  call void @llvm.assume(i1 %z)
2960  %i = add i8 %x, -1
2961  %c = icmp ult i8 %i, 7
2962  ret i1 %c
2963}
2964
2965define i1 @icmp_dec_sub_assume_nonzero(i8 %x) {
2966; CHECK-LABEL: @icmp_dec_sub_assume_nonzero(
2967; CHECK-NEXT:    [[Z:%.*]] = icmp ne i8 [[X:%.*]], 0
2968; CHECK-NEXT:    call void @llvm.assume(i1 [[Z]])
2969; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[X]], 12
2970; CHECK-NEXT:    ret i1 [[C]]
2971;
2972  %z = icmp ne i8 %x, 0
2973  call void @llvm.assume(i1 %z)
2974  %i = sub i8 %x, 1
2975  %c = icmp ult i8 %i, 11
2976  ret i1 %c
2977}
2978
2979define i1 @icmp_dec_nonzero(i16 %x) {
2980; CHECK-LABEL: @icmp_dec_nonzero(
2981; CHECK-NEXT:    [[C:%.*]] = icmp ult i16 [[X:%.*]], 8
2982; CHECK-NEXT:    ret i1 [[C]]
2983;
2984  %o = or i16 %x, 4
2985  %i = add i16 %o, -1
2986  %c = icmp ult i16 %i, 7
2987  ret i1 %c
2988}
2989
2990define <2 x i1> @icmp_dec_nonzero_vec(<2 x i32> %x) {
2991; CHECK-LABEL: @icmp_dec_nonzero_vec(
2992; CHECK-NEXT:    [[O:%.*]] = or <2 x i32> [[X:%.*]], splat (i32 8)
2993; CHECK-NEXT:    [[I:%.*]] = add nsw <2 x i32> [[O]], splat (i32 -1)
2994; CHECK-NEXT:    [[C:%.*]] = icmp ult <2 x i32> [[I]], <i32 15, i32 17>
2995; CHECK-NEXT:    ret <2 x i1> [[C]]
2996;
2997  %o = or <2 x i32> %x, <i32 8, i32 8>
2998  %i = add <2 x i32> %o, <i32 -1, i32 -1>
2999  %c = icmp ult <2 x i32> %i, <i32 15, i32 17>
3000  ret <2 x i1> %c
3001}
3002
3003; Negative test
3004define i1 @icmp_dec_notnonzero(i8 %x) {
3005; CHECK-LABEL: @icmp_dec_notnonzero(
3006; CHECK-NEXT:    [[I:%.*]] = add i8 [[X:%.*]], -1
3007; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[I]], 11
3008; CHECK-NEXT:    ret i1 [[C]]
3009;
3010  %i = add i8 %x, -1
3011  %c = icmp ult i8 %i, 11
3012  ret i1 %c
3013}
3014
3015define i1 @icmp_addnuw_nonzero(i8 %x, i8 %y) {
3016; CHECK-LABEL: @icmp_addnuw_nonzero(
3017; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
3018; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[TMP1]], 0
3019; CHECK-NEXT:    ret i1 [[C]]
3020;
3021  %i = add nuw i8 %x, %y
3022  %c = icmp eq i8 %i, 0
3023  ret i1 %c
3024}
3025
3026define i1 @icmp_addnuw_nonzero_fail_multiuse(i32 %x, i32 %y) {
3027; CHECK-LABEL: @icmp_addnuw_nonzero_fail_multiuse(
3028; CHECK-NEXT:    [[I:%.*]] = add nuw i32 [[X:%.*]], [[Y:%.*]]
3029; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[I]], 0
3030; CHECK-NEXT:    call void @use(i32 [[I]])
3031; CHECK-NEXT:    ret i1 [[C]]
3032;
3033  %i = add nuw i32 %x, %y
3034  %c = icmp eq i32 %i, 0
3035  call void @use(i32 %i)
3036  ret i1 %c
3037}
3038
3039define i1 @ult_add_C2_pow2_C_neg(i8 %x) {
3040; CHECK-LABEL: @ult_add_C2_pow2_C_neg(
3041; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -32
3042; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[TMP1]], -64
3043; CHECK-NEXT:    ret i1 [[C]]
3044;
3045  %i = add i8 %x, 32
3046  %c = icmp ult i8 %i, -32
3047  ret i1 %c
3048}
3049
3050define i1 @ult_add_nsw_C2_pow2_C_neg(i8 %x) {
3051; CHECK-LABEL: @ult_add_nsw_C2_pow2_C_neg(
3052; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -32
3053; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[TMP1]], -64
3054; CHECK-NEXT:    ret i1 [[C]]
3055;
3056  %i = add nsw i8 %x, 32
3057  %c = icmp ult i8 %i, -32
3058  ret i1 %c
3059}
3060
3061define i1 @ult_add_nuw_nsw_C2_pow2_C_neg(i8 %x) {
3062; CHECK-LABEL: @ult_add_nuw_nsw_C2_pow2_C_neg(
3063; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[X:%.*]], -64
3064; CHECK-NEXT:    ret i1 [[C]]
3065;
3066  %i = add nuw nsw i8 %x, 32
3067  %c = icmp ult i8 %i, -32
3068  ret i1 %c
3069}
3070
3071define i1 @ult_add_C2_neg_C_pow2(i8 %x) {
3072; CHECK-LABEL: @ult_add_C2_neg_C_pow2(
3073; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -32
3074; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[TMP1]], 32
3075; CHECK-NEXT:    ret i1 [[C]]
3076;
3077  %i = add i8 %x, -32
3078  %c = icmp ult i8 %i, 32
3079  ret i1 %c
3080}
3081
3082define <2 x i1> @ult_add_C2_pow2_C_neg_vec(<2 x i8> %x) {
3083; CHECK-LABEL: @ult_add_C2_pow2_C_neg_vec(
3084; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 -32)
3085; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i8> [[TMP1]], splat (i8 -64)
3086; CHECK-NEXT:    ret <2 x i1> [[C]]
3087;
3088  %i = add <2 x i8> %x, <i8 32, i8 32>
3089  %c = icmp ult <2 x i8> %i, <i8 -32, i8 -32>
3090  ret <2 x i1> %c
3091}
3092
3093define i1 @ult_add_C2_pow2_C_neg_multiuse(i8 %x) {
3094; CHECK-LABEL: @ult_add_C2_pow2_C_neg_multiuse(
3095; CHECK-NEXT:    [[I:%.*]] = add i8 [[X:%.*]], 32
3096; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[I]], -32
3097; CHECK-NEXT:    call void @use(i8 [[I]])
3098; CHECK-NEXT:    ret i1 [[C]]
3099;
3100  %i = add i8 %x, 32
3101  %c = icmp ult i8 %i, -32
3102  call void @use(i8 %i)
3103  ret i1 %c
3104}
3105
3106define i1 @uge_add_C2_pow2_C_neg(i8 %x) {
3107; CHECK-LABEL: @uge_add_C2_pow2_C_neg(
3108; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -32
3109; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[TMP1]], -64
3110; CHECK-NEXT:    ret i1 [[C]]
3111;
3112  %i = add i8 %x, 32
3113  %c = icmp uge i8 %i, -32
3114  ret i1 %c
3115}
3116
3117declare void @llvm.assume(i1)
3118
3119; Change an unsigned predicate to signed in icmp (add x, C1), C2
3120define i1 @icmp_add_constant_with_constant_ult_to_slt(i32 range(i32 -4, 10) %x) {
3121; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt(
3122; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 8
3123; CHECK-NEXT:    ret i1 [[CMP]]
3124;
3125  %add = add nsw i32 %x, 5
3126  %cmp = icmp ult i32 %add, 13
3127  ret i1 %cmp
3128}
3129
3130define i1 @icmp_add_constant_with_constant_ugt_to_sgt(i32 range(i32 -4, 10) %x) {
3131; CHECK-LABEL: @icmp_add_constant_with_constant_ugt_to_sgt(
3132; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 2
3133; CHECK-NEXT:    ret i1 [[CMP]]
3134;
3135  %add = add nsw i32 %x, 10
3136  %cmp = icmp ugt i32 %add, 12
3137  ret i1 %cmp
3138}
3139
3140; Negative test: x + C1 may be negative
3141define i1 @icmp_add_constant_with_constant_ult_to_slt_neg1(i32 range(i32 -5, 10) %x) {
3142; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt_neg1(
3143; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 4
3144; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD]], 20
3145; CHECK-NEXT:    ret i1 [[CMP]]
3146;
3147  %add = add nsw i32 %x, 4
3148  %cmp = icmp ult i32 %add, 20
3149  ret i1 %cmp
3150}
3151
3152; Negative test: missing nsw flag
3153define i1 @icmp_add_constant_with_constant_ult_to_slt_neg2(i8 range(i8 -4, 120) %x) {
3154; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt_neg2(
3155; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X:%.*]], 15
3156; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[ADD]], 20
3157; CHECK-NEXT:    ret i1 [[CMP]]
3158;
3159  %add = add i8 %x, 15
3160  %cmp = icmp ult i8 %add, 20
3161  ret i1 %cmp
3162}
3163
3164; Negative test: C2 is negative
3165define i1 @icmp_add_constant_with_constant_ult_to_slt_neg3(i32 range(i32 -4, 10) %x) {
3166; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt_neg3(
3167; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 4
3168; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD]], -6
3169; CHECK-NEXT:    ret i1 [[CMP]]
3170;
3171  %add = add nsw i32 %x, 4
3172  %cmp = icmp ult i32 %add, -6
3173  ret i1 %cmp
3174}
3175
3176; Negative test: C2 - C1 is negative
3177define i1 @icmp_add_constant_with_constant_ult_to_slt_neg4(i32 range(i32 -4, 10) %x) {
3178; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt_neg4(
3179; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 5
3180; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD]], 2
3181; CHECK-NEXT:    ret i1 [[CMP]]
3182;
3183  %add = add nsw i32 %x, 5
3184  %cmp = icmp ult i32 %add, 2
3185  ret i1 %cmp
3186}
3187
3188; Same as before, but infer the range of ucmp
3189define i1 @icmp_of_ucmp_plus_const_with_const(i32 %x, i32 %y) {
3190; CHECK-LABEL: @icmp_of_ucmp_plus_const_with_const(
3191; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 [[X:%.*]], [[Y:%.*]]
3192; CHECK-NEXT:    ret i1 [[CMP2]]
3193;
3194  %cmp1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
3195  %add = add i8 %cmp1, 1
3196  %cmp2 = icmp ult i8 %add, 2
3197  ret i1 %cmp2
3198}
3199
3200define i1 @zext_range_check_ult(i8 %x) {
3201; CHECK-LABEL: @zext_range_check_ult(
3202; CHECK-NEXT:  entry:
3203; CHECK-NEXT:    [[TMP0:%.*]] = add i8 [[X:%.*]], -4
3204; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[TMP0]], 3
3205; CHECK-NEXT:    ret i1 [[CMP]]
3206;
3207entry:
3208  %conv = zext i8 %x to i32
3209  %add = add i32 %conv, -4
3210  %cmp = icmp ult i32 %add, 3
3211  ret i1 %cmp
3212}
3213
3214; TODO: should be canonicalized to (x - 4) u> 2
3215define i1 @zext_range_check_ugt(i8 %x) {
3216; CHECK-LABEL: @zext_range_check_ugt(
3217; CHECK-NEXT:  entry:
3218; CHECK-NEXT:    [[CONV:%.*]] = zext i8 [[X:%.*]] to i32
3219; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i32 [[CONV]], -7
3220; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[TMP0]], -3
3221; CHECK-NEXT:    ret i1 [[CMP]]
3222;
3223entry:
3224  %conv = zext i8 %x to i32
3225  %add = add i32 %conv, -4
3226  %cmp = icmp ugt i32 %add, 2
3227  ret i1 %cmp
3228}
3229
3230; TODO: should be canonicalized to (x - 4) u> 2
3231define i1 @zext_range_check_ult_alter(i8 %x) {
3232; CHECK-LABEL: @zext_range_check_ult_alter(
3233; CHECK-NEXT:  entry:
3234; CHECK-NEXT:    [[CONV:%.*]] = zext i8 [[X:%.*]] to i32
3235; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[CONV]], -7
3236; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD]], -3
3237; CHECK-NEXT:    ret i1 [[CMP]]
3238;
3239entry:
3240  %conv = zext i8 %x to i32
3241  %add = add i32 %conv, -7
3242  %cmp = icmp ult i32 %add, -3
3243  ret i1 %cmp
3244}
3245
3246define i1 @zext_range_check_mergable(i8 %x) {
3247; CHECK-LABEL: @zext_range_check_mergable(
3248; CHECK-NEXT:    [[COND:%.*]] = icmp slt i8 [[X:%.*]], 7
3249; CHECK-NEXT:    ret i1 [[COND]]
3250;
3251  %conv = zext i8 %x to i32
3252  %add = add nsw i32 %conv, -4
3253  %cmp1 = icmp ult i32 %add, 3
3254  %cmp2 = icmp slt i8 %x, 4
3255  %cond = select i1 %cmp2, i1 true, i1 %cmp1
3256  ret i1 %cond
3257}
3258
3259; Negative tests
3260
3261define i1 @sext_range_check_ult(i8 %x) {
3262; CHECK-LABEL: @sext_range_check_ult(
3263; CHECK-NEXT:  entry:
3264; CHECK-NEXT:    [[CONV:%.*]] = sext i8 [[X:%.*]] to i32
3265; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[CONV]], -4
3266; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD]], 3
3267; CHECK-NEXT:    ret i1 [[CMP]]
3268;
3269entry:
3270  %conv = sext i8 %x to i32
3271  %add = add i32 %conv, -4
3272  %cmp = icmp ult i32 %add, 3
3273  ret i1 %cmp
3274}
3275
3276define i1 @zext_range_check_ult_illegal_type(i7 %x) {
3277; CHECK-LABEL: @zext_range_check_ult_illegal_type(
3278; CHECK-NEXT:  entry:
3279; CHECK-NEXT:    [[CONV:%.*]] = zext i7 [[X:%.*]] to i32
3280; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[CONV]], -4
3281; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD]], 3
3282; CHECK-NEXT:    ret i1 [[CMP]]
3283;
3284entry:
3285  %conv = zext i7 %x to i32
3286  %add = add i32 %conv, -4
3287  %cmp = icmp ult i32 %add, 3
3288  ret i1 %cmp
3289}
3290
3291define i1 @zext_range_check_ult_range_check_failure(i8 %x) {
3292; CHECK-LABEL: @zext_range_check_ult_range_check_failure(
3293; CHECK-NEXT:  entry:
3294; CHECK-NEXT:    [[CONV:%.*]] = zext i8 [[X:%.*]] to i32
3295; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[CONV]], -4
3296; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD]], 253
3297; CHECK-NEXT:    ret i1 [[CMP]]
3298;
3299entry:
3300  %conv = zext i8 %x to i32
3301  %add = add i32 %conv, -4
3302  %cmp = icmp ult i32 %add, 253
3303  ret i1 %cmp
3304}
3305