Revert "[InstCombine] Support gep nuw in icmp folds" (#118698)
[llvm-project.git] / llvm / test / Transforms / InstCombine / icmp-add.ll
blob579247aaccf282db78f0bc02f89e5a3a5d6fb30a
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 declare void @use(i32)
6 ; PR1949
8 ; negative test for zext/zext additions with i16
9 define 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]]
16 bb:
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
24 ; negative test for zext/zext addtions with i8
25 define 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]]
32 bb:
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
40 ; start of positive tests
41 define 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
46 bb:
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
54 define 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
59 bb:
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
67 define 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]]
74 bb:
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
82 define i1 @cvt_icmp_1_zext_plus_zext_eq(i1 %arg, i1 %arg1) {
83 ; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_eq(
84 ; CHECK-NEXT:  bb:
85 ; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
86 ; CHECK-NEXT:    ret i1 [[I4]]
88 bb:
89   %i = zext i1 %arg to i32
90   %i2 = zext i1 %arg1 to i32
91   %i3 = add i32 %i2, %i
92   %i4 = icmp eq i32 %i3, 1
93   ret i1 %i4
96 define <2 x i1> @cvt_icmp_1_zext_plus_zext_eq_vec(<2 x i1> %arg, <2 x i1> %arg1) {
97 ; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_eq_vec(
98 ; CHECK-NEXT:  bb:
99 ; CHECK-NEXT:    [[I4:%.*]] = xor <2 x i1> [[ARG1:%.*]], [[ARG:%.*]]
100 ; CHECK-NEXT:    ret <2 x i1> [[I4]]
103   %i = zext <2 x i1> %arg to <2 x i32>
104   %i2 = zext <2 x i1> %arg1 to <2 x i32>
105   %i3 = add <2 x i32> %i2, %i
106   %i4 = icmp eq <2 x i32> %i3, <i32 1, i32 1>
107   ret <2 x i1> %i4
110 define i1 @cvt_icmp_2_zext_plus_zext_eq(i1 %arg, i1 %arg1) {
111 ; CHECK-LABEL: @cvt_icmp_2_zext_plus_zext_eq(
112 ; CHECK-NEXT:  bb:
113 ; CHECK-NEXT:    [[T:%.*]] = and i1 [[ARG:%.*]], [[ARG1:%.*]]
114 ; CHECK-NEXT:    ret i1 [[T]]
117   %i = zext i1 %arg to i32
118   %i2 = zext i1 %arg1 to i32
119   %i3 = add i32 %i, %i2
120   %t = icmp eq i32 %i3, 2
121   ret i1 %t
124 define i1 @cvt_icmp_neg_2_sext_plus_sext_eq(i1 %arg, i1 %arg1) {
125 ; CHECK-LABEL: @cvt_icmp_neg_2_sext_plus_sext_eq(
126 ; CHECK-NEXT:  bb:
127 ; CHECK-NEXT:    [[T:%.*]] = and i1 [[ARG:%.*]], [[ARG1:%.*]]
128 ; CHECK-NEXT:    ret i1 [[T]]
131   %i = sext i1 %arg to i32
132   %i2 = sext i1 %arg1 to i32
133   %i3 = add i32 %i, %i2
134   %t = icmp eq i32 %i3, -2
135   ret i1 %t
138 define i1 @cvt_icmp_neg_1_sext_plus_sext_eq(i1 %arg, i1 %arg1) {
139 ; CHECK-LABEL: @cvt_icmp_neg_1_sext_plus_sext_eq(
140 ; CHECK-NEXT:  bb:
141 ; CHECK-NEXT:    [[T:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]]
142 ; CHECK-NEXT:    ret i1 [[T]]
145   %i = sext i1 %arg to i32
146   %i2 = sext i1 %arg1 to i32
147   %i3 = add i32 %i, %i2
148   %t = icmp eq i32 %i3, -1
149   ret i1 %t
152 define i1 @cvt_icmp_0_sext_plus_sext_eq(i1 %arg, i1 %arg1) {
153 ; CHECK-LABEL: @cvt_icmp_0_sext_plus_sext_eq(
154 ; CHECK-NEXT:  bb:
155 ; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[ARG:%.*]], [[ARG1:%.*]]
156 ; CHECK-NEXT:    [[T:%.*]] = xor i1 [[TMP0]], true
157 ; CHECK-NEXT:    ret i1 [[T]]
160   %i = sext i1 %arg to i32
161   %i2 = sext i1 %arg1 to i32
162   %i3 = add i32 %i, %i2
163   %t = icmp eq i32 %i3, 0
164   ret i1 %t
167 define i1 @cvt_icmp_1_sext_plus_sext_eq(i1 %arg, i1 %arg1) {
168 ; CHECK-LABEL: @cvt_icmp_1_sext_plus_sext_eq(
169 ; CHECK-NEXT:  bb:
170 ; CHECK-NEXT:    ret i1 false
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, 1
177   ret i1 %t
180 define i1 @cvt_icmp_2_sext_plus_sext_eq(i1 %arg, i1 %arg1) {
181 ; CHECK-LABEL: @cvt_icmp_2_sext_plus_sext_eq(
182 ; CHECK-NEXT:  bb:
183 ; CHECK-NEXT:    ret i1 false
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, 2
190   ret i1 %t
193 define i1 @cvt_icmp_neg_2_sext_plus_zext_eq(i1 %arg, i1 %arg1) {
194 ; CHECK-LABEL: @cvt_icmp_neg_2_sext_plus_zext_eq(
195 ; CHECK-NEXT:  bb:
196 ; CHECK-NEXT:    ret i1 false
199   %i = sext i1 %arg to i32
200   %i2 = zext i1 %arg1 to i32
201   %i3 = add i32 %i, %i2
202   %t = icmp eq i32 %i3, -2
203   ret i1 %t
206 define i1 @cvt_icmp_neg_1_sext_plus_zext_eq(i1 %arg, i1 %arg1) {
207 ; CHECK-LABEL: @cvt_icmp_neg_1_sext_plus_zext_eq(
208 ; CHECK-NEXT:  bb:
209 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
210 ; CHECK-NEXT:    [[T:%.*]] = and i1 [[ARG:%.*]], [[TMP0]]
211 ; CHECK-NEXT:    ret i1 [[T]]
214   %i = sext i1 %arg to i32
215   %i2 = zext i1 %arg1 to i32
216   %i3 = add i32 %i, %i2
217   %t = icmp eq i32 %i3, -1
218   ret i1 %t
221 define i1 @cvt_icmp_0_sext_plus_zext_eq(i1 %arg, i1 %arg1) {
222 ; CHECK-LABEL: @cvt_icmp_0_sext_plus_zext_eq(
223 ; CHECK-NEXT:  bb:
224 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]]
225 ; CHECK-NEXT:    [[T:%.*]] = xor i1 [[TMP0]], true
226 ; CHECK-NEXT:    ret i1 [[T]]
229   %i = sext i1 %arg to i32
230   %i2 = zext i1 %arg1 to i32
231   %i3 = add i32 %i, %i2
232   %t = icmp eq i32 %i3, 0
233   ret i1 %t
236 define i1 @cvt_icmp_1_sext_plus_zext_eq(i1 %arg, i1 %arg1) {
237 ; CHECK-LABEL: @cvt_icmp_1_sext_plus_zext_eq(
238 ; CHECK-NEXT:  bb:
239 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
240 ; CHECK-NEXT:    [[T:%.*]] = and i1 [[ARG1:%.*]], [[TMP0]]
241 ; CHECK-NEXT:    ret i1 [[T]]
244   %i = sext i1 %arg to i32
245   %i2 = zext i1 %arg1 to i32
246   %i3 = add i32 %i, %i2
247   %t = icmp eq i32 %i3, 1
248   ret i1 %t
251 define i1 @cvt_icmp_2_sext_plus_zext_eq(i1 %arg, i1 %arg1) {
252 ; CHECK-LABEL: @cvt_icmp_2_sext_plus_zext_eq(
253 ; CHECK-NEXT:  bb:
254 ; CHECK-NEXT:    ret i1 false
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, 2
261   ret i1 %t
264 define i1 @cvt_icmp_neg_2_zext_plus_zext_ne(i1 %arg, i1 %arg1) {
265 ; CHECK-LABEL: @cvt_icmp_neg_2_zext_plus_zext_ne(
266 ; CHECK-NEXT:  bb:
267 ; CHECK-NEXT:    ret i1 true
270   %i = zext i1 %arg to i32
271   %i2 = zext i1 %arg1 to i32
272   %i3 = add i32 %i2, %i
273   %i4 = icmp ne i32 %i3, -2
274   ret i1 %i4
277 define i1 @cvt_icmp_neg_1_zext_plus_zext_ne(i1 %arg, i1 %arg1) {
278 ; CHECK-LABEL: @cvt_icmp_neg_1_zext_plus_zext_ne(
279 ; CHECK-NEXT:  bb:
280 ; CHECK-NEXT:    ret i1 true
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, -1
287   ret i1 %i4
290 define i1 @cvt_icmp_0_zext_plus_zext_ne(i1 %arg, i1 %arg1) {
291 ; CHECK-LABEL: @cvt_icmp_0_zext_plus_zext_ne(
292 ; CHECK-NEXT:  bb:
293 ; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
294 ; CHECK-NEXT:    ret i1 [[I4]]
297   %i = zext i1 %arg to i32
298   %i2 = zext i1 %arg1 to i32
299   %i3 = add i32 %i2, %i
300   %i4 = icmp ne i32 %i3, 0
301   ret i1 %i4
304 define i1 @cvt_icmp_1_zext_plus_zext_ne(i1 %arg, i1 %arg1) {
305 ; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_ne(
306 ; CHECK-NEXT:  bb:
307 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
308 ; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
309 ; CHECK-NEXT:    ret i1 [[I4]]
312   %i = zext i1 %arg to i32
313   %i2 = zext i1 %arg1 to i32
314   %i3 = add i32 %i2, %i
315   %i4 = icmp ne i32 %i3, 1
316   ret i1 %i4
319 define i1 @cvt_icmp_1_zext_plus_zext_ne_extra_use_1(i1 %arg, i1 %arg1) {
320 ; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_ne_extra_use_1(
321 ; CHECK-NEXT:  bb:
322 ; CHECK-NEXT:    [[I:%.*]] = zext i1 [[ARG:%.*]] to i32
323 ; CHECK-NEXT:    [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32
324 ; CHECK-NEXT:    [[I3:%.*]] = add nuw nsw i32 [[I2]], [[I]]
325 ; CHECK-NEXT:    call void @use(i32 [[I3]])
326 ; CHECK-NEXT:    [[I4:%.*]] = icmp ne i32 [[I3]], 1
327 ; CHECK-NEXT:    ret i1 [[I4]]
330   %i = zext i1 %arg to i32
331   %i2 = zext i1 %arg1 to i32
332   %i3 = add i32 %i2, %i
333   call void @use(i32 %i3)
334   %i4 = icmp ne i32 %i3, 1
335   ret i1 %i4
338 define i1 @cvt_icmp_1_zext_plus_zext_ne_extra_use_2(i1 %arg, i1 %arg1) {
339 ; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_ne_extra_use_2(
340 ; CHECK-NEXT:  bb:
341 ; CHECK-NEXT:    [[I:%.*]] = zext i1 [[ARG:%.*]] to i32
342 ; CHECK-NEXT:    call void @use(i32 [[I]])
343 ; CHECK-NEXT:    [[I2:%.*]] = zext i1 [[ARG1:%.*]] to i32
344 ; CHECK-NEXT:    call void @use(i32 [[I2]])
345 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1]], [[ARG]]
346 ; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
347 ; CHECK-NEXT:    ret i1 [[I4]]
350   %i = zext i1 %arg to i32
351   call void @use(i32 %i)
352   %i2 = zext i1 %arg1 to i32
353   call void @use(i32 %i2)
354   %i3 = add i32 %i2, %i
355   %i4 = icmp ne i32 %i3, 1
356   ret i1 %i4
359 define i1 @cvt_icmp_2_zext_plus_zext_ne(i1 %arg, i1 %arg1) {
360 ; CHECK-LABEL: @cvt_icmp_2_zext_plus_zext_ne(
361 ; CHECK-NEXT:  bb:
362 ; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[ARG:%.*]], [[ARG1:%.*]]
363 ; CHECK-NEXT:    [[T:%.*]] = xor i1 [[TMP0]], true
364 ; CHECK-NEXT:    ret i1 [[T]]
367   %i = zext i1 %arg to i32
368   %i2 = zext i1 %arg1 to i32
369   %i3 = add i32 %i, %i2
370   %t = icmp ne i32 %i3, 2
371   ret i1 %t
374 define i1 @cvt_icmp_neg_2_sext_plus_sext_ne(i1 %arg, i1 %arg1) {
375 ; CHECK-LABEL: @cvt_icmp_neg_2_sext_plus_sext_ne(
376 ; CHECK-NEXT:  bb:
377 ; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[ARG:%.*]], [[ARG1:%.*]]
378 ; CHECK-NEXT:    [[T:%.*]] = xor i1 [[TMP0]], true
379 ; CHECK-NEXT:    ret i1 [[T]]
382   %i = sext i1 %arg to i32
383   %i2 = sext i1 %arg1 to i32
384   %i3 = add i32 %i, %i2
385   %t = icmp ne i32 %i3, -2
386   ret i1 %t
389 define i1 @cvt_icmp_neg_1_sext_plus_sext_ne(i1 %arg, i1 %arg1) {
390 ; CHECK-LABEL: @cvt_icmp_neg_1_sext_plus_sext_ne(
391 ; CHECK-NEXT:  bb:
392 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]]
393 ; CHECK-NEXT:    [[T:%.*]] = xor i1 [[TMP0]], true
394 ; CHECK-NEXT:    ret i1 [[T]]
397   %i = sext i1 %arg to i32
398   %i2 = sext i1 %arg1 to i32
399   %i3 = add i32 %i, %i2
400   %t = icmp ne i32 %i3, -1
401   ret i1 %t
404 define i1 @cvt_icmp_0_sext_plus_sext_ne(i1 %arg, i1 %arg1) {
405 ; CHECK-LABEL: @cvt_icmp_0_sext_plus_sext_ne(
406 ; CHECK-NEXT:  bb:
407 ; CHECK-NEXT:    [[T:%.*]] = or i1 [[ARG:%.*]], [[ARG1:%.*]]
408 ; CHECK-NEXT:    ret i1 [[T]]
411   %i = sext i1 %arg to i32
412   %i2 = sext i1 %arg1 to i32
413   %i3 = add i32 %i, %i2
414   %t = icmp ne i32 %i3, 0
415   ret i1 %t
418 define i1 @cvt_icmp_1_sext_plus_sext_ne(i1 %arg, i1 %arg1) {
419 ; CHECK-LABEL: @cvt_icmp_1_sext_plus_sext_ne(
420 ; CHECK-NEXT:  bb:
421 ; CHECK-NEXT:    ret i1 true
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, 1
428   ret i1 %t
431 define i1 @cvt_icmp_2_sext_plus_sext_ne(i1 %arg, i1 %arg1) {
432 ; CHECK-LABEL: @cvt_icmp_2_sext_plus_sext_ne(
433 ; CHECK-NEXT:  bb:
434 ; CHECK-NEXT:    ret i1 true
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, 2
441   ret i1 %t
444 define i1 @cvt_icmp_neg_2_sext_plus_zext_ne(i1 %arg, i1 %arg1) {
445 ; CHECK-LABEL: @cvt_icmp_neg_2_sext_plus_zext_ne(
446 ; CHECK-NEXT:  bb:
447 ; CHECK-NEXT:    ret i1 true
450   %i = sext i1 %arg to i32
451   %i2 = zext i1 %arg1 to i32
452   %i3 = add i32 %i, %i2
453   %t = icmp ne i32 %i3, -2
454   ret i1 %t
457 define i1 @cvt_icmp_neg_1_sext_plus_zext_ne(i1 %arg, i1 %arg1) {
458 ; CHECK-LABEL: @cvt_icmp_neg_1_sext_plus_zext_ne(
459 ; CHECK-NEXT:  bb:
460 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
461 ; CHECK-NEXT:    [[T:%.*]] = or i1 [[ARG1:%.*]], [[TMP0]]
462 ; CHECK-NEXT:    ret i1 [[T]]
465   %i = sext i1 %arg to i32
466   %i2 = zext i1 %arg1 to i32
467   %i3 = add i32 %i, %i2
468   %t = icmp ne i32 %i3, -1
469   ret i1 %t
472 define i1 @cvt_icmp_0_sext_plus_zext_ne(i1 %arg, i1 %arg1) {
473 ; CHECK-LABEL: @cvt_icmp_0_sext_plus_zext_ne(
474 ; CHECK-NEXT:  bb:
475 ; CHECK-NEXT:    [[T:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]]
476 ; CHECK-NEXT:    ret i1 [[T]]
479   %i = sext i1 %arg to i32
480   %i2 = zext i1 %arg1 to i32
481   %i3 = add i32 %i, %i2
482   %t = icmp ne i32 %i3, 0
483   ret i1 %t
486 define i1 @cvt_icmp_1_sext_plus_zext_ne(i1 %arg, i1 %arg1) {
487 ; CHECK-LABEL: @cvt_icmp_1_sext_plus_zext_ne(
488 ; CHECK-NEXT:  bb:
489 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
490 ; CHECK-NEXT:    [[T:%.*]] = or i1 [[ARG:%.*]], [[TMP0]]
491 ; CHECK-NEXT:    ret i1 [[T]]
494   %i = sext i1 %arg to i32
495   %i2 = zext i1 %arg1 to i32
496   %i3 = add i32 %i, %i2
497   %t = icmp ne i32 %i3, 1
498   ret i1 %t
501 define i1 @cvt_icmp_2_sext_plus_zext_ne(i1 %arg, i1 %arg1) {
502 ; CHECK-LABEL: @cvt_icmp_2_sext_plus_zext_ne(
503 ; CHECK-NEXT:  bb:
504 ; CHECK-NEXT:    ret i1 true
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, 2
511   ret i1 %t
514 define <2 x i1> @cvt_icmp_2_sext_plus_zext_ne_vec(<2 x i1> %arg, <2 x i1> %arg1) {
515 ; CHECK-LABEL: @cvt_icmp_2_sext_plus_zext_ne_vec(
516 ; CHECK-NEXT:  bb:
517 ; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
520   %i = sext <2 x i1> %arg to <2 x i32>
521   %i2 = zext <2 x i1> %arg1 to <2 x i32>
522   %i3 = add nsw <2 x i32> %i, %i2
523   %i4 = icmp ne <2 x i32> %i3, <i32 2, i32 2>
524   ret <2 x i1> %i4
527 ; test if zext i1 X + sext i1 Y converted to sext i1 X + zext i1 Y
528 ; and then processed
530 define i1 @cvt_icmp_neg_2_zext_plus_sext_eq(i1 %arg, i1 %arg1) {
531 ; CHECK-LABEL: @cvt_icmp_neg_2_zext_plus_sext_eq(
532 ; CHECK-NEXT:  bb:
533 ; CHECK-NEXT:    ret i1 false
536   %i = zext i1 %arg to i32
537   %i2 = sext i1 %arg1 to i32
538   %i3 = add i32 %i, %i2
539   %t = icmp eq i32 %i3, -2
540   ret i1 %t
543 define <2 x i1> @cvt_icmp_neg_2_zext_plus_sext_eq_vec(<2 x i1> %arg, <2 x i1> %arg1) {
544 ; CHECK-LABEL: @cvt_icmp_neg_2_zext_plus_sext_eq_vec(
545 ; CHECK-NEXT:  bb:
546 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
549   %i = zext <2 x i1> %arg to <2 x i32>
550   %i2 = sext <2 x i1> %arg1 to <2 x i32>
551   %i3 = add nsw <2 x i32> %i2, %i
552   %i4 = icmp eq <2 x i32> %i3, <i32 2, i32 2>
553   ret <2 x i1> %i4
556 define i1 @cvt_icmp_neg_1_zext_plus_sext_eq(i1 %arg, i1 %arg1) {
557 ; CHECK-LABEL: @cvt_icmp_neg_1_zext_plus_sext_eq(
558 ; CHECK-NEXT:  bb:
559 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
560 ; CHECK-NEXT:    [[T:%.*]] = and i1 [[ARG1:%.*]], [[TMP0]]
561 ; CHECK-NEXT:    ret i1 [[T]]
564   %i = zext i1 %arg to i32
565   %i2 = sext i1 %arg1 to i32
566   %i3 = add i32 %i, %i2
567   %t = icmp eq i32 %i3, -1
568   ret i1 %t
571 define i1 @cvt_icmp_0_zext_plus_sext_eq(i1 %arg, i1 %arg1) {
572 ; CHECK-LABEL: @cvt_icmp_0_zext_plus_sext_eq(
573 ; CHECK-NEXT:  bb:
574 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]]
575 ; CHECK-NEXT:    [[T:%.*]] = xor i1 [[TMP0]], true
576 ; CHECK-NEXT:    ret i1 [[T]]
579   %i = zext i1 %arg to i32
580   %i2 = sext i1 %arg1 to i32
581   %i3 = add i32 %i, %i2
582   %t = icmp eq i32 %i3, 0
583   ret i1 %t
586 define i1 @cvt_icmp_1_zext_plus_sext_eq(i1 %arg, i1 %arg1) {
587 ; CHECK-LABEL: @cvt_icmp_1_zext_plus_sext_eq(
588 ; CHECK-NEXT:  bb:
589 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
590 ; CHECK-NEXT:    [[T:%.*]] = and i1 [[ARG:%.*]], [[TMP0]]
591 ; CHECK-NEXT:    ret i1 [[T]]
594   %i = zext i1 %arg to i32
595   %i2 = sext i1 %arg1 to i32
596   %i3 = add i32 %i, %i2
597   %t = icmp eq i32 %i3, 1
598   ret i1 %t
601 define i1 @cvt_icmp_2_zext_plus_sext_eq(i1 %arg, i1 %arg1) {
602 ; CHECK-LABEL: @cvt_icmp_2_zext_plus_sext_eq(
603 ; CHECK-NEXT:  bb:
604 ; CHECK-NEXT:    ret i1 false
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, 2
611   ret i1 %t
614 define i1 @cvt_icmp_neg_2_zext_plus_sext_ne(i1 %arg, i1 %arg1) {
615 ; CHECK-LABEL: @cvt_icmp_neg_2_zext_plus_sext_ne(
616 ; CHECK-NEXT:  bb:
617 ; CHECK-NEXT:    ret i1 true
620   %i = zext i1 %arg to i32
621   %i2 = sext i1 %arg1 to i32
622   %i3 = add i32 %i, %i2
623   %t = icmp ne i32 %i3, -2
624   ret i1 %t
627 define i1 @cvt_icmp_neg_1_zext_plus_sext_ne(i1 %arg, i1 %arg1) {
628 ; CHECK-LABEL: @cvt_icmp_neg_1_zext_plus_sext_ne(
629 ; CHECK-NEXT:  bb:
630 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
631 ; CHECK-NEXT:    [[T:%.*]] = or i1 [[ARG:%.*]], [[TMP0]]
632 ; CHECK-NEXT:    ret i1 [[T]]
635   %i = zext i1 %arg to i32
636   %i2 = sext i1 %arg1 to i32
637   %i3 = add i32 %i, %i2
638   %t = icmp ne i32 %i3, -1
639   ret i1 %t
642 define i1 @cvt_icmp_0_zext_plus_sext_ne(i1 %arg, i1 %arg1) {
643 ; CHECK-LABEL: @cvt_icmp_0_zext_plus_sext_ne(
644 ; CHECK-NEXT:  bb:
645 ; CHECK-NEXT:    [[T:%.*]] = xor i1 [[ARG:%.*]], [[ARG1:%.*]]
646 ; CHECK-NEXT:    ret i1 [[T]]
649   %i = zext i1 %arg to i32
650   %i2 = sext i1 %arg1 to i32
651   %i3 = add i32 %i, %i2
652   %t = icmp ne i32 %i3, 0
653   ret i1 %t
656 define i1 @cvt_icmp_1_zext_plus_sext_ne(i1 %arg, i1 %arg1) {
657 ; CHECK-LABEL: @cvt_icmp_1_zext_plus_sext_ne(
658 ; CHECK-NEXT:  bb:
659 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
660 ; CHECK-NEXT:    [[T:%.*]] = or i1 [[ARG1:%.*]], [[TMP0]]
661 ; CHECK-NEXT:    ret i1 [[T]]
664   %i = zext i1 %arg to i32
665   %i2 = sext i1 %arg1 to i32
666   %i3 = add i32 %i, %i2
667   %t = icmp ne i32 %i3, 1
668   ret i1 %t
671 define i1 @cvt_icmp_2_zext_plus_sext_ne(i1 %arg, i1 %arg1) {
672 ; CHECK-LABEL: @cvt_icmp_2_zext_plus_sext_ne(
673 ; CHECK-NEXT:  bb:
674 ; CHECK-NEXT:    ret i1 true
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, 2
681   ret i1 %t
684 ; test zext/zext additions with more than one use
686 define i1 @test_cvt_icmp1(i1 %arg, i1 %arg1, ptr %p) {
687 ; CHECK-LABEL: @test_cvt_icmp1(
688 ; CHECK-NEXT:  bb:
689 ; CHECK-NEXT:    [[I2:%.*]] = zext i1 [[ARG:%.*]] to i32
690 ; CHECK-NEXT:    store i32 [[I2]], ptr [[P:%.*]], align 4
691 ; CHECK-NEXT:    ret i1 false
694   %i = zext i1 %arg to i32
695   %i2 = zext i1 %arg to i32
696   store i32 %i2, ptr %p
697   %i3 = load i32, ptr %p
698   %i4 = add i32 %i3, %i
699   %t = icmp eq i32 %i4, 1
700   ret i1 %t
703 define i1 @test_cvt_icmp2(i1 %arg, i1 %arg1, ptr %p) {
704 ; CHECK-LABEL: @test_cvt_icmp2(
705 ; CHECK-NEXT:  bb:
706 ; CHECK-NEXT:    [[I2:%.*]] = zext i1 [[ARG:%.*]] to i32
707 ; CHECK-NEXT:    store i32 [[I2]], ptr [[P:%.*]], align 4
708 ; CHECK-NEXT:    ret i1 false
711   %i = sext i1 %arg to i32
712   %i2 = zext i1 %arg to i32
713   store i32 %i2, ptr %p
714   %i3 = load i32, ptr %p
715   %i4 = add i32 %i3, %i
716   %t = icmp eq i32 %i4, 1
717   ret i1 %t
720 ; tests for ult
721 define i1 @test_zext_zext_cvt_neg_2_ult_icmp(i1 %arg, i1 %arg1) {
722 ; CHECK-LABEL: @test_zext_zext_cvt_neg_2_ult_icmp(
723 ; CHECK-NEXT:  bb:
724 ; CHECK-NEXT:    ret i1 true
727   %i = zext i1 %arg to i32
728   %i2 = zext i1 %arg1 to i32
729   %i3 = add i32 %i2, %i
730   %i4 = icmp ult i32 %i3, -2
731   ret i1 %i4
734 define i1 @test_zext_zext_cvt_neg_1_ult_icmp(i1 %arg, i1 %arg1) {
735 ; CHECK-LABEL: @test_zext_zext_cvt_neg_1_ult_icmp(
736 ; CHECK-NEXT:  bb:
737 ; CHECK-NEXT:    ret i1 true
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, -1
744   ret i1 %i4
747 define i1 @test_zext_zext_cvt_0_ult_icmp(i1 %arg, i1 %arg1) {
748 ; CHECK-LABEL: @test_zext_zext_cvt_0_ult_icmp(
749 ; CHECK-NEXT:  bb:
750 ; CHECK-NEXT:    ret i1 false
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, 0
757   ret i1 %i4
760 define i1 @test_zext_zext_cvt_2_ult_icmp(i1 %arg, i1 %arg1) {
761 ; CHECK-LABEL: @test_zext_zext_cvt_2_ult_icmp(
762 ; CHECK-NEXT:  bb:
763 ; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]]
764 ; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
765 ; CHECK-NEXT:    ret i1 [[I4]]
768   %i = zext i1 %arg to i32
769   %i2 = zext i1 %arg1 to i32
770   %i3 = add i32 %i2, %i
771   %i4 = icmp ult i32 %i3, 2
772   ret i1 %i4
775 define i1 @test_sext_sext_cvt_neg_2_ult_icmp(i1 %arg, i1 %arg1) {
776 ; CHECK-LABEL: @test_sext_sext_cvt_neg_2_ult_icmp(
777 ; CHECK-NEXT:  bb:
778 ; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
779 ; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
780 ; CHECK-NEXT:    ret i1 [[I4]]
783   %i = sext i1 %arg to i32
784   %i2 = sext i1 %arg1 to i32
785   %i3 = add i32 %i2, %i
786   %i4 = icmp ult i32 %i3, -2
787   ret i1 %i4
790 define i1 @test_sext_sext_cvt_neg_1_ult_icmp(i1 %arg, i1 %arg1) {
791 ; CHECK-LABEL: @test_sext_sext_cvt_neg_1_ult_icmp(
792 ; CHECK-NEXT:  bb:
793 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
794 ; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
795 ; CHECK-NEXT:    ret i1 [[I4]]
798   %i = sext i1 %arg to i32
799   %i2 = sext i1 %arg1 to i32
800   %i3 = add i32 %i2, %i
801   %i4 = icmp ult i32 %i3, -1
802   ret i1 %i4
805 define i1 @test_sext_sext_cvt_0_ult_icmp(i1 %arg, i1 %arg1) {
806 ; CHECK-LABEL: @test_sext_sext_cvt_0_ult_icmp(
807 ; CHECK-NEXT:  bb:
808 ; CHECK-NEXT:    ret i1 false
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, 0
815   ret i1 %i4
818 define i1 @test_sext_sext_cvt_1_ult_icmp(i1 %arg, i1 %arg1) {
819 ; CHECK-LABEL: @test_sext_sext_cvt_1_ult_icmp(
820 ; CHECK-NEXT:  bb:
821 ; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
822 ; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
823 ; CHECK-NEXT:    ret i1 [[I4]]
826   %i = sext i1 %arg to i32
827   %i2 = sext i1 %arg1 to i32
828   %i3 = add i32 %i2, %i
829   %i4 = icmp ult i32 %i3, 1
830   ret i1 %i4
833 define i1 @test_sext_sext_cvt_2_ult_icmp(i1 %arg, i1 %arg1) {
834 ; CHECK-LABEL: @test_sext_sext_cvt_2_ult_icmp(
835 ; CHECK-NEXT:  bb:
836 ; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
837 ; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
838 ; CHECK-NEXT:    ret i1 [[I4]]
841   %i = sext i1 %arg to i32
842   %i2 = sext i1 %arg1 to i32
843   %i3 = add i32 %i2, %i
844   %i4 = icmp ult i32 %i3, 2
845   ret i1 %i4
848 define i1 @test_sext_zext_cvt_neg_2_ult_icmp(i1 %arg, i1 %arg1) {
849 ; CHECK-LABEL: @test_sext_zext_cvt_neg_2_ult_icmp(
850 ; CHECK-NEXT:  bb:
851 ; CHECK-NEXT:    [[ARG_NOT:%.*]] = xor i1 [[ARG:%.*]], true
852 ; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG_NOT]]
853 ; CHECK-NEXT:    ret i1 [[I4]]
856   %i = sext i1 %arg to i32
857   %i2 = zext i1 %arg1 to i32
858   %i3 = add i32 %i2, %i
859   %i4 = icmp ult i32 %i3, -2
860   ret i1 %i4
863 define i1 @test_sext_zext_cvt_neg_1_ult_icmp(i1 %arg, i1 %arg1) {
864 ; CHECK-LABEL: @test_sext_zext_cvt_neg_1_ult_icmp(
865 ; CHECK-NEXT:  bb:
866 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
867 ; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[TMP0]]
868 ; CHECK-NEXT:    ret i1 [[I4]]
871   %i = sext i1 %arg to i32
872   %i2 = zext i1 %arg1 to i32
873   %i3 = add i32 %i2, %i
874   %i4 = icmp ult i32 %i3, -1
875   ret i1 %i4
878 define i1 @test_sext_zext_cvt_0_ult_icmp(i1 %arg, i1 %arg1) {
879 ; CHECK-LABEL: @test_sext_zext_cvt_0_ult_icmp(
880 ; CHECK-NEXT:  bb:
881 ; CHECK-NEXT:    ret i1 false
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, 0
888   ret i1 %i4
891 define i1 @test_sext_zext_cvt_2_ult_icmp(i1 %arg, i1 %arg1) {
892 ; CHECK-LABEL: @test_sext_zext_cvt_2_ult_icmp(
893 ; CHECK-NEXT:  bb:
894 ; CHECK-NEXT:    [[ARG_NOT:%.*]] = xor i1 [[ARG:%.*]], true
895 ; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG_NOT]]
896 ; CHECK-NEXT:    ret i1 [[I4]]
899   %i = sext i1 %arg to i32
900   %i2 = zext i1 %arg1 to i32
901   %i3 = add i32 %i2, %i
902   %i4 = icmp ult i32 %i3, 2
903   ret i1 %i4
906 define i1 @test_zext_sext_cvt_neg_1_ult_icmp(i1 %arg, i1 %arg1) {
907 ; CHECK-LABEL: @test_zext_sext_cvt_neg_1_ult_icmp(
908 ; CHECK-NEXT:  bb:
909 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
910 ; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG:%.*]], [[TMP0]]
911 ; CHECK-NEXT:    ret i1 [[I4]]
914   %i = zext i1 %arg to i32
915   %i2 = sext i1 %arg1 to i32
916   %i3 = add i32 %i2, %i
917   %i4 = icmp ult i32 %i3, -1
918   ret i1 %i4
921 define i1 @test_zext_sext_cvt_0_ult_icmp(i1 %arg, i1 %arg1) {
922 ; CHECK-LABEL: @test_zext_sext_cvt_0_ult_icmp(
923 ; CHECK-NEXT:  bb:
924 ; CHECK-NEXT:    ret i1 false
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, 0
931   ret i1 %i4
934 define i1 @test_zext_sext_cvt_1_ult_icmp(i1 %arg, i1 %arg1) {
935 ; CHECK-LABEL: @test_zext_sext_cvt_1_ult_icmp(
936 ; CHECK-NEXT:  bb:
937 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
938 ; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
939 ; CHECK-NEXT:    ret i1 [[I4]]
942   %i = zext i1 %arg to i32
943   %i2 = sext i1 %arg1 to i32
944   %i3 = add i32 %i2, %i
945   %i4 = icmp ult i32 %i3, 1
946   ret i1 %i4
949 ; tests for ugt
950 define i1 @test_cvt_icmp4(i1 %arg, i1 %arg1) {
951 ; CHECK-LABEL: @test_cvt_icmp4(
952 ; CHECK-NEXT:  bb:
953 ; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
954 ; CHECK-NEXT:    ret i1 [[I4]]
957   %i = zext i1 %arg to i32
958   %i2 = zext i1 %arg1 to i32
959   %i3 = add i32 %i2, %i
960   %i4 = icmp ugt i32 %i3, 0
961   ret i1 %i4
964 define i1 @test_zext_zext_cvt_neg_2_ugt_icmp(i1 %arg, i1 %arg1) {
965 ; CHECK-LABEL: @test_zext_zext_cvt_neg_2_ugt_icmp(
966 ; CHECK-NEXT:  bb:
967 ; CHECK-NEXT:    ret i1 false
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, -2
974   ret i1 %i4
977 define i1 @test_zext_zext_cvt_1_ugt_icmp(i1 %arg, i1 %arg1) {
978 ; CHECK-LABEL: @test_zext_zext_cvt_1_ugt_icmp(
979 ; CHECK-NEXT:  bb:
980 ; CHECK-NEXT:    [[I4:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]]
981 ; CHECK-NEXT:    ret i1 [[I4]]
984   %i = zext i1 %arg to i32
985   %i2 = zext i1 %arg1 to i32
986   %i3 = add i32 %i2, %i
987   %i4 = icmp ugt i32 %i3, 1
988   ret i1 %i4
991 define i1 @test_zext_zext_cvt_2_ugt_icmp(i1 %arg, i1 %arg1) {
992 ; CHECK-LABEL: @test_zext_zext_cvt_2_ugt_icmp(
993 ; CHECK-NEXT:  bb:
994 ; CHECK-NEXT:    ret i1 false
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, 2
1001   ret i1 %i4
1004 define i1 @test_sext_sext_cvt_neg_2_ugt_icmp(i1 %arg, i1 %arg1) {
1005 ; CHECK-LABEL: @test_sext_sext_cvt_neg_2_ugt_icmp(
1006 ; CHECK-NEXT:  bb:
1007 ; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
1008 ; CHECK-NEXT:    ret i1 [[I4]]
1011   %i = sext i1 %arg to i32
1012   %i2 = sext i1 %arg1 to i32
1013   %i3 = add i32 %i2, %i
1014   %i4 = icmp ugt i32 %i3, -2
1015   ret i1 %i4
1018 define i1 @test_sext_sext_cvt_0_ugt_icmp(i1 %arg, i1 %arg1) {
1019 ; CHECK-LABEL: @test_sext_sext_cvt_0_ugt_icmp(
1020 ; CHECK-NEXT:  bb:
1021 ; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
1022 ; CHECK-NEXT:    ret i1 [[I4]]
1025   %i = sext i1 %arg to i32
1026   %i2 = sext i1 %arg1 to i32
1027   %i3 = add i32 %i2, %i
1028   %i4 = icmp ugt i32 %i3, 0
1029   ret i1 %i4
1032 define i1 @test_sext_sext_cvt_2_ugt_icmp(i1 %arg, i1 %arg1) {
1033 ; CHECK-LABEL: @test_sext_sext_cvt_2_ugt_icmp(
1034 ; CHECK-NEXT:  bb:
1035 ; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
1036 ; CHECK-NEXT:    ret i1 [[I4]]
1039   %i = sext i1 %arg to i32
1040   %i2 = sext i1 %arg1 to i32
1041   %i3 = add i32 %i2, %i
1042   %i4 = icmp ugt i32 %i3, 2
1043   ret i1 %i4
1046 define i1 @test_zext_sext_cvt_neg_2_ugt_icmp(i1 %arg, i1 %arg1) {
1047 ; CHECK-LABEL: @test_zext_sext_cvt_neg_2_ugt_icmp(
1048 ; CHECK-NEXT:  bb:
1049 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
1050 ; CHECK-NEXT:    [[I4:%.*]] = and i1 [[ARG1:%.*]], [[TMP0]]
1051 ; CHECK-NEXT:    ret i1 [[I4]]
1054   %i = zext i1 %arg to i32
1055   %i2 = sext i1 %arg1 to i32
1056   %i3 = add i32 %i2, %i
1057   %i4 = icmp ugt i32 %i3, -2
1058   ret i1 %i4
1061 define i1 @test_zext_sext_cvt_neg_1_ugt_icmp(i1 %arg, i1 %arg1) {
1062 ; CHECK-LABEL: @test_zext_sext_cvt_neg_1_ugt_icmp(
1063 ; CHECK-NEXT:  bb:
1064 ; CHECK-NEXT:    ret i1 false
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, -1
1071   ret i1 %i4
1074 define i1 @test_zext_sext_cvt_0_ugt_icmp(i1 %arg, i1 %arg1) {
1075 ; CHECK-LABEL: @test_zext_sext_cvt_0_ugt_icmp(
1076 ; CHECK-NEXT:  bb:
1077 ; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
1078 ; CHECK-NEXT:    ret i1 [[I4]]
1081   %i = zext i1 %arg to i32
1082   %i2 = sext i1 %arg1 to i32
1083   %i3 = add i32 %i2, %i
1084   %i4 = icmp ugt i32 %i3, 0
1085   ret i1 %i4
1088 define i1 @test_zext_sext_cvt_1_ugt_icmp(i1 %arg, i1 %arg1) {
1089 ; CHECK-LABEL: @test_zext_sext_cvt_1_ugt_icmp(
1090 ; CHECK-NEXT:  bb:
1091 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
1092 ; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[ARG1:%.*]], [[TMP0]]
1093 ; CHECK-NEXT:    ret i1 [[TMP1]]
1096   %i = zext i1 %arg to i32
1097   %i2 = sext i1 %arg1 to i32
1098   %i3 = add i32 %i2, %i
1099   %i4 = icmp ugt i32 %i3, 1
1100   ret i1 %i4
1103 define i1 @test_zext_sext_cvt_2_ugt_icmp(i1 %arg, i1 %arg1) {
1104 ; CHECK-LABEL: @test_zext_sext_cvt_2_ugt_icmp(
1105 ; CHECK-NEXT:  bb:
1106 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
1107 ; CHECK-NEXT:    [[I4:%.*]] = and i1 [[ARG1:%.*]], [[TMP0]]
1108 ; CHECK-NEXT:    ret i1 [[I4]]
1111   %i = zext i1 %arg to i32
1112   %i2 = sext i1 %arg1 to i32
1113   %i3 = add i32 %i2, %i
1114   %i4 = icmp ugt i32 %i3, 2
1115   ret i1 %i4
1118 define i1 @test_cvt_icmp5(i1 %arg, i1 %arg1) {
1119 ; CHECK-LABEL: @test_cvt_icmp5(
1120 ; CHECK-NEXT:  bb:
1121 ; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
1122 ; CHECK-NEXT:    ret i1 [[I4]]
1125   %i = zext i1 %arg to i32
1126   %i2 = zext i1 %arg1 to i32
1127   %i3 = add i32 %i2, %i
1128   %i4 = icmp uge i32 %i3, 1
1129   ret i1 %i4
1132 define i1 @test_cvt_icmp6(i1 %arg, i1 %arg1) {
1133 ; CHECK-LABEL: @test_cvt_icmp6(
1134 ; CHECK-NEXT:  bb:
1135 ; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]]
1136 ; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
1137 ; CHECK-NEXT:    ret i1 [[I4]]
1140   %i = zext i1 %arg to i32
1141   %i2 = zext i1 %arg1 to i32
1142   %i3 = add i32 %i2, %i
1143   %i4 = icmp ule i32 %i3, 1
1144   ret i1 %i4
1147 ; tests for sgt
1148 define i1 @test_cvt_icmp7(i1 %arg, i1 %arg1) {
1149 ; CHECK-LABEL: @test_cvt_icmp7(
1150 ; CHECK-NEXT:  bb:
1151 ; CHECK-NEXT:    [[I4:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]]
1152 ; CHECK-NEXT:    ret i1 [[I4]]
1155   %i = zext i1 %arg to i32
1156   %i2 = zext i1 %arg1 to i32
1157   %i3 = add i32 %i2, %i
1158   %i4 = icmp sgt i32 %i3, 1
1159   ret i1 %i4
1162 define i1 @test_zext_zext_cvt_neg_2_sgt_icmp(i1 %arg, i1 %arg1) {
1163 ; CHECK-LABEL: @test_zext_zext_cvt_neg_2_sgt_icmp(
1164 ; CHECK-NEXT:  bb:
1165 ; CHECK-NEXT:    ret i1 true
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, -2
1172   ret i1 %i4
1175 define i1 @test_zext_zext_cvt_neg_1_sgt_icmp(i1 %arg, i1 %arg1) {
1176 ; CHECK-LABEL: @test_zext_zext_cvt_neg_1_sgt_icmp(
1177 ; CHECK-NEXT:  bb:
1178 ; CHECK-NEXT:    ret i1 true
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, -1
1185   ret i1 %i4
1188 define i1 @test_zext_zext_cvt_2_sgt_icmp(i1 %arg, i1 %arg1) {
1189 ; CHECK-LABEL: @test_zext_zext_cvt_2_sgt_icmp(
1190 ; CHECK-NEXT:  bb:
1191 ; CHECK-NEXT:    ret i1 false
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, 2
1198   ret i1 %i4
1201 define i1 @test_sext_sext_cvt_neg_2_sgt_icmp(i1 %arg, i1 %arg1) {
1202 ; CHECK-LABEL: @test_sext_sext_cvt_neg_2_sgt_icmp(
1203 ; CHECK-NEXT:  bb:
1204 ; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]]
1205 ; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
1206 ; CHECK-NEXT:    ret i1 [[I4]]
1209   %i = sext i1 %arg to i32
1210   %i2 = sext i1 %arg1 to i32
1211   %i3 = add i32 %i2, %i
1212   %i4 = icmp sgt i32 %i3, -2
1213   ret i1 %i4
1216 define i1 @test_sext_sext_cvt_0_sgt_icmp(i1 %arg, i1 %arg1) {
1217 ; CHECK-LABEL: @test_sext_sext_cvt_0_sgt_icmp(
1218 ; CHECK-NEXT:  bb:
1219 ; CHECK-NEXT:    ret i1 false
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, 0
1226   ret i1 %i4
1229 define i1 @test_sext_sext_cvt_2_sgt_icmp(i1 %arg, i1 %arg1) {
1230 ; CHECK-LABEL: @test_sext_sext_cvt_2_sgt_icmp(
1231 ; CHECK-NEXT:  bb:
1232 ; CHECK-NEXT:    ret i1 false
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, 2
1239   ret i1 %i4
1242 define i1 @test_zext_sext_cvt_neg_2_sgt_icmp(i1 %arg, i1 %arg1) {
1243 ; CHECK-LABEL: @test_zext_sext_cvt_neg_2_sgt_icmp(
1244 ; CHECK-NEXT:  bb:
1245 ; CHECK-NEXT:    ret i1 true
1248   %i = zext 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
1255 define i1 @test_zext_sext_cvt_neg_1_sgt_icmp(i1 %arg, i1 %arg1) {
1256 ; CHECK-LABEL: @test_zext_sext_cvt_neg_1_sgt_icmp(
1257 ; CHECK-NEXT:  bb:
1258 ; CHECK-NEXT:    [[ARG1_NOT:%.*]] = xor i1 [[ARG1:%.*]], true
1259 ; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG:%.*]], [[ARG1_NOT]]
1260 ; CHECK-NEXT:    ret i1 [[I4]]
1263   %i = zext i1 %arg to i32
1264   %i2 = sext i1 %arg1 to i32
1265   %i3 = add i32 %i2, %i
1266   %i4 = icmp sgt i32 %i3, -1
1267   ret i1 %i4
1270 define i1 @test_zext_sext_cvt_0_sgt_icmp(i1 %arg, i1 %arg1) {
1271 ; CHECK-LABEL: @test_zext_sext_cvt_0_sgt_icmp(
1272 ; CHECK-NEXT:  bb:
1273 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
1274 ; CHECK-NEXT:    [[I4:%.*]] = and i1 [[ARG:%.*]], [[TMP0]]
1275 ; CHECK-NEXT:    ret i1 [[I4]]
1278   %i = zext i1 %arg to i32
1279   %i2 = sext i1 %arg1 to i32
1280   %i3 = add i32 %i2, %i
1281   %i4 = icmp sgt i32 %i3, 0
1282   ret i1 %i4
1285 define i1 @test_zext_sext_cvt_1_sgt_icmp(i1 %arg, i1 %arg1) {
1286 ; CHECK-LABEL: @test_zext_sext_cvt_1_sgt_icmp(
1287 ; CHECK-NEXT:  bb:
1288 ; CHECK-NEXT:    ret i1 false
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, 1
1295   ret i1 %i4
1298 define i1 @test_zext_sext_cvt_2_sgt_icmp(i1 %arg, i1 %arg1) {
1299 ; CHECK-LABEL: @test_zext_sext_cvt_2_sgt_icmp(
1300 ; CHECK-NEXT:  bb:
1301 ; CHECK-NEXT:    ret i1 false
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, 2
1308   ret i1 %i4
1311 ; tests for slt
1312 define i1 @test_zext_zext_cvt_neg_2_slt_icmp(i1 %arg, i1 %arg1) {
1313 ; CHECK-LABEL: @test_zext_zext_cvt_neg_2_slt_icmp(
1314 ; CHECK-NEXT:  bb:
1315 ; CHECK-NEXT:    ret i1 false
1318   %i = zext i1 %arg to i32
1319   %i2 = zext i1 %arg1 to i32
1320   %i3 = add i32 %i2, %i
1321   %i4 = icmp slt i32 %i3, -2
1322   ret i1 %i4
1325 define i1 @test_zext_zext_cvt_neg_1_slt_icmp(i1 %arg, i1 %arg1) {
1326 ; CHECK-LABEL: @test_zext_zext_cvt_neg_1_slt_icmp(
1327 ; CHECK-NEXT:  bb:
1328 ; CHECK-NEXT:    ret i1 false
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, -1
1335   ret i1 %i4
1338 define i1 @test_zext_zext_cvt_2_slt_icmp(i1 %arg, i1 %arg1) {
1339 ; CHECK-LABEL: @test_zext_zext_cvt_2_slt_icmp(
1340 ; CHECK-NEXT:  bb:
1341 ; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]]
1342 ; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
1343 ; CHECK-NEXT:    ret i1 [[I4]]
1346   %i = zext i1 %arg to i32
1347   %i2 = zext i1 %arg1 to i32
1348   %i3 = add i32 %i2, %i
1349   %i4 = icmp slt i32 %i3, 2
1350   ret i1 %i4
1353 define i1 @test_sext_sext_cvt_neg_2_slt_icmp(i1 %arg, i1 %arg1) {
1354 ; CHECK-LABEL: @test_sext_sext_cvt_neg_2_slt_icmp(
1355 ; CHECK-NEXT:  bb:
1356 ; CHECK-NEXT:    ret i1 false
1359   %i = sext i1 %arg to i32
1360   %i2 = sext i1 %arg1 to i32
1361   %i3 = add i32 %i2, %i
1362   %i4 = icmp slt i32 %i3, -2
1363   ret i1 %i4
1366 define i1 @test_sext_sext_cvt_0_slt_icmp(i1 %arg, i1 %arg1) {
1367 ; CHECK-LABEL: @test_sext_sext_cvt_0_slt_icmp(
1368 ; CHECK-NEXT:  bb:
1369 ; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
1370 ; CHECK-NEXT:    ret i1 [[TMP0]]
1373   %i = sext i1 %arg to i32
1374   %i2 = sext i1 %arg1 to i32
1375   %i3 = add i32 %i2, %i
1376   %i4 = icmp slt i32 %i3, 0
1377   ret i1 %i4
1380 define i1 @test_sext_sext_cvt_2_slt_icmp(i1 %arg, i1 %arg1) {
1381 ; CHECK-LABEL: @test_sext_sext_cvt_2_slt_icmp(
1382 ; CHECK-NEXT:  bb:
1383 ; CHECK-NEXT:    ret i1 true
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, 2
1390   ret i1 %i4
1393 define i1 @test_zext_sext_cvt_neg_2_slt_icmp(i1 %arg, i1 %arg1) {
1394 ; CHECK-LABEL: @test_zext_sext_cvt_neg_2_slt_icmp(
1395 ; CHECK-NEXT:  bb:
1396 ; CHECK-NEXT:    ret i1 false
1399   %i = zext 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
1406 define i1 @test_zext_sext_cvt_neg_1_slt_icmp(i1 %arg, i1 %arg1) {
1407 ; CHECK-LABEL: @test_zext_sext_cvt_neg_1_slt_icmp(
1408 ; CHECK-NEXT:  bb:
1409 ; CHECK-NEXT:    ret i1 false
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, -1
1416   ret i1 %i4
1419 define i1 @test_zext_sext_cvt_0_slt_icmp(i1 %arg, i1 %arg1) {
1420 ; CHECK-LABEL: @test_zext_sext_cvt_0_slt_icmp(
1421 ; CHECK-NEXT:  bb:
1422 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
1423 ; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[ARG1:%.*]], [[TMP0]]
1424 ; CHECK-NEXT:    ret i1 [[TMP1]]
1427   %i = zext i1 %arg to i32
1428   %i2 = sext i1 %arg1 to i32
1429   %i3 = add i32 %i2, %i
1430   %i4 = icmp slt i32 %i3, 0
1431   ret i1 %i4
1434 define i1 @test_zext_sext_cvt_1_slt_icmp(i1 %arg, i1 %arg1) {
1435 ; CHECK-LABEL: @test_zext_sext_cvt_1_slt_icmp(
1436 ; CHECK-NEXT:  bb:
1437 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
1438 ; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[TMP0]]
1439 ; CHECK-NEXT:    ret i1 [[I4]]
1442   %i = zext i1 %arg to i32
1443   %i2 = sext i1 %arg1 to i32
1444   %i3 = add i32 %i2, %i
1445   %i4 = icmp slt i32 %i3, 1
1446   ret i1 %i4
1449 define i1 @test_zext_sext_cvt_2_slt_icmp(i1 %arg, i1 %arg1) {
1450 ; CHECK-LABEL: @test_zext_sext_cvt_2_slt_icmp(
1451 ; CHECK-NEXT:  bb:
1452 ; CHECK-NEXT:    ret i1 true
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, 2
1459   ret i1 %i4
1462 define i1 @test_cvt_icmp8(i1 %arg, i1 %arg1) {
1463 ; CHECK-LABEL: @test_cvt_icmp8(
1464 ; CHECK-NEXT:  bb:
1465 ; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
1466 ; CHECK-NEXT:    ret i1 [[I4]]
1469   %i = zext i1 %arg to i32
1470   %i2 = zext i1 %arg1 to i32
1471   %i3 = add i32 %i2, %i
1472   %i4 = icmp sge i32 %i3, 1
1473   ret i1 %i4
1476 define i1 @test_cvt_icmp9(i1 %arg, i1 %arg1) {
1477 ; CHECK-LABEL: @test_cvt_icmp9(
1478 ; CHECK-NEXT:  bb:
1479 ; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
1480 ; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
1481 ; CHECK-NEXT:    ret i1 [[I4]]
1484   %i = zext i1 %arg to i32
1485   %i2 = zext i1 %arg1 to i32
1486   %i3 = add i32 %i2, %i
1487   %i4 = icmp slt i32 %i3, 1
1488   ret i1 %i4
1491 define i1 @test_cvt_icmp10(i1 %arg, i1 %arg1) {
1492 ; CHECK-LABEL: @test_cvt_icmp10(
1493 ; CHECK-NEXT:  bb:
1494 ; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[ARG1:%.*]], [[ARG:%.*]]
1495 ; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
1496 ; CHECK-NEXT:    ret i1 [[I4]]
1499   %i = zext i1 %arg to i32
1500   %i2 = zext i1 %arg1 to i32
1501   %i3 = add i32 %i2, %i
1502   %i4 = icmp sle i32 %i3, 1
1503   ret i1 %i4
1506 define i1 @test_cvt_icmp11(i1 %arg, i1 %arg1) {
1507 ; CHECK-LABEL: @test_cvt_icmp11(
1508 ; CHECK-NEXT:  bb:
1509 ; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
1510 ; CHECK-NEXT:    ret i1 [[I4]]
1513   %i = sext i1 %arg to i32
1514   %i2 = sext i1 %arg1 to i32
1515   %i3 = add i32 %i2, %i
1516   %i4 = icmp ugt i32 %i3, 2
1517   ret i1 %i4
1520 define i1 @test_cvt_icmp12(i1 %arg, i1 %arg1) {
1521 ; CHECK-LABEL: @test_cvt_icmp12(
1522 ; CHECK-NEXT:  bb:
1523 ; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
1524 ; CHECK-NEXT:    ret i1 [[I4]]
1527   %i = sext i1 %arg to i32
1528   %i2 = sext i1 %arg1 to i32
1529   %i3 = add i32 %i2, %i
1530   %i4 = icmp uge i32 %i3, 1
1531   ret i1 %i4
1534 define i1 @test_cvt_icmp13(i1 %arg, i1 %arg1) {
1535 ; CHECK-LABEL: @test_cvt_icmp13(
1536 ; CHECK-NEXT:  bb:
1537 ; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
1538 ; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
1539 ; CHECK-NEXT:    ret i1 [[I4]]
1542   %i = sext i1 %arg to i32
1543   %i2 = sext i1 %arg1 to i32
1544   %i3 = add i32 %i2, %i
1545   %i4 = icmp ult i32 %i3, 1
1546   ret i1 %i4
1549 define i1 @test_cvt_icmp14(i1 %arg, i1 %arg1) {
1550 ; CHECK-LABEL: @test_cvt_icmp14(
1551 ; CHECK-NEXT:  bb:
1552 ; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
1553 ; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[TMP0]], true
1554 ; CHECK-NEXT:    ret i1 [[I4]]
1557   %i = sext i1 %arg to i32
1558   %i2 = sext i1 %arg1 to i32
1559   %i3 = add i32 %i2, %i
1560   %i4 = icmp ule i32 %i3, 2
1561   ret i1 %i4
1564 define i1 @test_cvt_icmp15(i1 %arg, i1 %arg1) {
1565 ; CHECK-LABEL: @test_cvt_icmp15(
1566 ; CHECK-NEXT:  bb:
1567 ; CHECK-NEXT:    ret i1 false
1570   %i = sext i1 %arg to i32
1571   %i2 = sext i1 %arg1 to i32
1572   %i3 = add i32 %i2, %i
1573   %i4 = icmp sgt i32 %i3, 2
1574   ret i1 %i4
1577 define i1 @test_cvt_icmp16(i1 %arg, i1 %arg1) {
1578 ; CHECK-LABEL: @test_cvt_icmp16(
1579 ; CHECK-NEXT:  bb:
1580 ; CHECK-NEXT:    ret i1 false
1583   %i = sext i1 %arg to i32
1584   %i2 = sext i1 %arg1 to i32
1585   %i3 = add i32 %i2, %i
1586   %i4 = icmp sge i32 %i3, 2
1587   ret i1 %i4
1590 define i1 @test_cvt_icmp17(i1 %arg, i1 %arg1) {
1591 ; CHECK-LABEL: @test_cvt_icmp17(
1592 ; CHECK-NEXT:  bb:
1593 ; CHECK-NEXT:    ret i1 true
1596   %i = sext i1 %arg to i32
1597   %i2 = sext i1 %arg1 to i32
1598   %i3 = add i32 %i2, %i
1599   %i4 = icmp slt i32 %i3, 2
1600   ret i1 %i4
1603 define i1 @test_cvt_icmp18(i1 %arg, i1 %arg1) {
1604 ; CHECK-LABEL: @test_cvt_icmp18(
1605 ; CHECK-NEXT:  bb:
1606 ; CHECK-NEXT:    ret i1 true
1609   %i = sext i1 %arg to i32
1610   %i2 = sext i1 %arg1 to i32
1611   %i3 = add i32 %i2, %i
1612   %i4 = icmp sle i32 %i3, 2
1613   ret i1 %i4
1616 define i1 @test_cvt_icmp19(i1 %arg, i1 %arg1) {
1617 ; CHECK-LABEL: @test_cvt_icmp19(
1618 ; CHECK-NEXT:  bb:
1619 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
1620 ; CHECK-NEXT:    [[I4:%.*]] = and i1 [[ARG:%.*]], [[TMP0]]
1621 ; CHECK-NEXT:    ret i1 [[I4]]
1624   %i = sext i1 %arg to i32
1625   %i2 = zext i1 %arg1 to i32
1626   %i3 = add i32 %i2, %i
1627   %i4 = icmp ugt i32 %i3, 2
1628   ret i1 %i4
1631 define i1 @test_cvt_icmp20(i1 %arg, i1 %arg1) {
1632 ; CHECK-LABEL: @test_cvt_icmp20(
1633 ; CHECK-NEXT:  bb:
1634 ; CHECK-NEXT:    [[I4:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
1635 ; CHECK-NEXT:    ret i1 [[I4]]
1638   %i = sext i1 %arg to i32
1639   %i2 = zext i1 %arg1 to i32
1640   %i3 = add i32 %i2, %i
1641   %i4 = icmp uge i32 %i3, 1
1642   ret i1 %i4
1645 define i1 @test_cvt_icmp21(i1 %arg, i1 %arg1) {
1646 ; CHECK-LABEL: @test_cvt_icmp21(
1647 ; CHECK-NEXT:  bb:
1648 ; CHECK-NEXT:    [[ARG_NOT:%.*]] = xor i1 [[ARG:%.*]], true
1649 ; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG_NOT]]
1650 ; CHECK-NEXT:    ret i1 [[I4]]
1653   %i = sext i1 %arg to i32
1654   %i2 = zext i1 %arg1 to i32
1655   %i3 = add i32 %i2, %i
1656   %i4 = icmp ult i32 %i3, 2
1657   ret i1 %i4
1660 define i1 @test_cvt_icmp22(i1 %arg, i1 %arg1) {
1661 ; CHECK-LABEL: @test_cvt_icmp22(
1662 ; CHECK-NEXT:  bb:
1663 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG:%.*]], true
1664 ; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[TMP0]]
1665 ; CHECK-NEXT:    ret i1 [[I4]]
1668   %i = sext i1 %arg to i32
1669   %i2 = zext i1 %arg1 to i32
1670   %i3 = add i32 %i2, %i
1671   %i4 = icmp ule i32 %i3, 2
1672   ret i1 %i4
1675 define i1 @test_cvt_icmp23(i1 %arg, i1 %arg1) {
1676 ; CHECK-LABEL: @test_cvt_icmp23(
1677 ; CHECK-NEXT:  bb:
1678 ; CHECK-NEXT:    ret i1 false
1681   %i = sext i1 %arg to i32
1682   %i2 = zext i1 %arg1 to i32
1683   %i3 = add i32 %i2, %i
1684   %i4 = icmp sgt i32 %i3, 2
1685   ret i1 %i4
1688 define i1 @test_cvt_icmp24(i1 %arg, i1 %arg1) {
1689 ; CHECK-LABEL: @test_cvt_icmp24(
1690 ; CHECK-NEXT:  bb:
1691 ; CHECK-NEXT:    [[ARG_NOT:%.*]] = xor i1 [[ARG:%.*]], true
1692 ; CHECK-NEXT:    [[I4:%.*]] = or i1 [[ARG1:%.*]], [[ARG_NOT]]
1693 ; CHECK-NEXT:    ret i1 [[I4]]
1696   %i = sext i1 %arg to i32
1697   %i2 = zext i1 %arg1 to i32
1698   %i3 = add i32 %i2, %i
1699   %i4 = icmp sge i32 %i3, 0
1700   ret i1 %i4
1703 define i1 @test_cvt_icmp25(i1 %arg, i1 %arg1) {
1704 ; CHECK-LABEL: @test_cvt_icmp25(
1705 ; CHECK-NEXT:  bb:
1706 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[ARG1:%.*]], true
1707 ; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[ARG:%.*]], [[TMP0]]
1708 ; CHECK-NEXT:    ret i1 [[TMP1]]
1711   %i = sext i1 %arg to i32
1712   %i2 = zext i1 %arg1 to i32
1713   %i3 = add i32 %i2, %i
1714   %i4 = icmp slt i32 %i3, 0
1715   ret i1 %i4
1718 define i1 @test_cvt_icmp26(i1 %arg, i1 %arg1) {
1719 ; CHECK-LABEL: @test_cvt_icmp26(
1720 ; CHECK-NEXT:  bb:
1721 ; CHECK-NEXT:    ret i1 true
1724   %i = sext i1 %arg to i32
1725   %i2 = zext i1 %arg1 to i32
1726   %i3 = add i32 %i2, %i
1727   %i4 = icmp sle i32 %i3, 1
1728   ret i1 %i4
1731 define i1 @test1(i32 %a) {
1732 ; CHECK-LABEL: @test1(
1733 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[A:%.*]], -5
1734 ; CHECK-NEXT:    ret i1 [[C]]
1736   %b = add i32 %a, 4
1737   %c = icmp ult i32 %b, 4
1738   ret i1 %c
1741 define <2 x i1> @test1vec(<2 x i32> %a) {
1742 ; CHECK-LABEL: @test1vec(
1743 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt <2 x i32> [[A:%.*]], splat (i32 -5)
1744 ; CHECK-NEXT:    ret <2 x i1> [[C]]
1746   %b = add <2 x i32> %a, <i32 4, i32 4>
1747   %c = icmp ult <2 x i32> %b, <i32 4, i32 4>
1748   ret <2 x i1> %c
1751 define i1 @test2(i32 %a) {
1752 ; CHECK-LABEL: @test2(
1753 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[A:%.*]], 4
1754 ; CHECK-NEXT:    ret i1 [[C]]
1756   %b = sub i32 %a, 4
1757   %c = icmp ugt i32 %b, -5
1758   ret i1 %c
1761 define <2 x i1> @test2vec(<2 x i32> %a) {
1762 ; CHECK-LABEL: @test2vec(
1763 ; CHECK-NEXT:    [[C:%.*]] = icmp ult <2 x i32> [[A:%.*]], splat (i32 4)
1764 ; CHECK-NEXT:    ret <2 x i1> [[C]]
1766   %b = sub <2 x i32> %a, <i32 4, i32 4>
1767   %c = icmp ugt <2 x i32> %b, <i32 -5, i32 -5>
1768   ret <2 x i1> %c
1771 define i1 @test3(i32 %a) {
1772 ; CHECK-LABEL: @test3(
1773 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[A:%.*]], 2147483643
1774 ; CHECK-NEXT:    ret i1 [[C]]
1776   %b = add i32 %a, 4
1777   %c = icmp slt i32 %b, 2147483652
1778   ret i1 %c
1781 define <2 x i1> @test3vec(<2 x i32> %a) {
1782 ; CHECK-LABEL: @test3vec(
1783 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt <2 x i32> [[A:%.*]], splat (i32 2147483643)
1784 ; CHECK-NEXT:    ret <2 x i1> [[C]]
1786   %b = add <2 x i32> %a, <i32 4, i32 4>
1787   %c = icmp slt <2 x i32> %b, <i32 2147483652, i32 2147483652>
1788   ret <2 x i1> %c
1791 define i1 @test4(i32 %a) {
1792 ; CHECK-LABEL: @test4(
1793 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[A:%.*]], -4
1794 ; CHECK-NEXT:    ret i1 [[C]]
1796   %b = add i32 %a, 2147483652
1797   %c = icmp sge i32 %b, 4
1798   ret i1 %c
1801 define { i32, i1 } @test4multiuse(i32 %a) {
1802 ; CHECK-LABEL: @test4multiuse(
1803 ; CHECK-NEXT:    [[B:%.*]] = add nsw i32 [[A:%.*]], -2147483644
1804 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[A]], 2147483640
1805 ; CHECK-NEXT:    [[TMP:%.*]] = insertvalue { i32, i1 } undef, i32 [[B]], 0
1806 ; CHECK-NEXT:    [[RES:%.*]] = insertvalue { i32, i1 } [[TMP]], i1 [[C]], 1
1807 ; CHECK-NEXT:    ret { i32, i1 } [[RES]]
1810   %b = add nsw i32 %a, -2147483644
1811   %c = icmp slt i32 %b, -4
1813   %tmp = insertvalue { i32, i1 } undef, i32 %b, 0
1814   %res = insertvalue { i32, i1 } %tmp, i1 %c, 1
1816   ret { i32, i1 } %res
1819 define <2 x i1> @test4vec(<2 x i32> %a) {
1820 ; CHECK-LABEL: @test4vec(
1821 ; CHECK-NEXT:    [[C:%.*]] = icmp slt <2 x i32> [[A:%.*]], splat (i32 -4)
1822 ; CHECK-NEXT:    ret <2 x i1> [[C]]
1824   %b = add <2 x i32> %a, <i32 2147483652, i32 2147483652>
1825   %c = icmp sge <2 x i32> %b, <i32 4, i32 4>
1826   ret <2 x i1> %c
1829 ; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow.
1830 ; This becomes equality because it's at the limit.
1832 define i1 @nsw_slt1(i8 %a) {
1833 ; CHECK-LABEL: @nsw_slt1(
1834 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A:%.*]], -128
1835 ; CHECK-NEXT:    ret i1 [[C]]
1837   %b = add nsw i8 %a, 100
1838   %c = icmp slt i8 %b, -27
1839   ret i1 %c
1842 define <2 x i1> @nsw_slt1_splat_vec(<2 x i8> %a) {
1843 ; CHECK-LABEL: @nsw_slt1_splat_vec(
1844 ; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i8> [[A:%.*]], splat (i8 -128)
1845 ; CHECK-NEXT:    ret <2 x i1> [[C]]
1847   %b = add nsw <2 x i8> %a, <i8 100, i8 100>
1848   %c = icmp slt <2 x i8> %b, <i8 -27, i8 -27>
1849   ret <2 x i1> %c
1852 ; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow.
1853 ; This becomes equality because it's at the limit.
1855 define i1 @nsw_slt2(i8 %a) {
1856 ; CHECK-LABEL: @nsw_slt2(
1857 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A:%.*]], 127
1858 ; CHECK-NEXT:    ret i1 [[C]]
1860   %b = add nsw i8 %a, -100
1861   %c = icmp slt i8 %b, 27
1862   ret i1 %c
1865 define <2 x i1> @nsw_slt2_splat_vec(<2 x i8> %a) {
1866 ; CHECK-LABEL: @nsw_slt2_splat_vec(
1867 ; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i8> [[A:%.*]], splat (i8 127)
1868 ; CHECK-NEXT:    ret <2 x i1> [[C]]
1870   %b = add nsw <2 x i8> %a, <i8 -100, i8 -100>
1871   %c = icmp slt <2 x i8> %b, <i8 27, i8 27>
1872   ret <2 x i1> %c
1875 ; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow.
1876 ; Less than the limit, so the predicate doesn't change.
1878 define i1 @nsw_slt3(i8 %a) {
1879 ; CHECK-LABEL: @nsw_slt3(
1880 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 [[A:%.*]], -126
1881 ; CHECK-NEXT:    ret i1 [[C]]
1883   %b = add nsw i8 %a, 100
1884   %c = icmp slt i8 %b, -26
1885   ret i1 %c
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.
1891 define i1 @nsw_slt4(i8 %a) {
1892 ; CHECK-LABEL: @nsw_slt4(
1893 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 [[A:%.*]], 126
1894 ; CHECK-NEXT:    ret i1 [[C]]
1896   %b = add nsw i8 %a, -100
1897   %c = icmp slt i8 %b, 26
1898   ret i1 %c
1901 ; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow.
1902 ; Try sgt to make sure that works too.
1904 define i1 @nsw_sgt1(i8 %a) {
1905 ; CHECK-LABEL: @nsw_sgt1(
1906 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A:%.*]], 127
1907 ; CHECK-NEXT:    ret i1 [[C]]
1909   %b = add nsw i8 %a, -100
1910   %c = icmp sgt i8 %b, 26
1911   ret i1 %c
1914 define <2 x i1> @nsw_sgt1_splat_vec(<2 x i8> %a) {
1915 ; CHECK-LABEL: @nsw_sgt1_splat_vec(
1916 ; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i8> [[A:%.*]], splat (i8 127)
1917 ; CHECK-NEXT:    ret <2 x i1> [[C]]
1919   %b = add nsw <2 x i8> %a, <i8 -100, i8 -100>
1920   %c = icmp sgt <2 x i8> %b, <i8 26, i8 26>
1921   ret <2 x i1> %c
1924 define i1 @nsw_sgt2(i8 %a) {
1925 ; CHECK-LABEL: @nsw_sgt2(
1926 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i8 [[A:%.*]], -126
1927 ; CHECK-NEXT:    ret i1 [[C]]
1929   %b = add nsw i8 %a, 100
1930   %c = icmp sgt i8 %b, -26
1931   ret i1 %c
1934 define <2 x i1> @nsw_sgt2_splat_vec(<2 x i8> %a) {
1935 ; CHECK-LABEL: @nsw_sgt2_splat_vec(
1936 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt <2 x i8> [[A:%.*]], splat (i8 -126)
1937 ; CHECK-NEXT:    ret <2 x i1> [[C]]
1939   %b = add nsw <2 x i8> %a, <i8 100, i8 100>
1940   %c = icmp sgt <2 x i8> %b, <i8 -26, i8 -26>
1941   ret <2 x i1> %c
1944 ; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow.
1945 ; Comparison with 0 doesn't need special-casing.
1947 define i1 @slt_zero_add_nsw(i32 %a) {
1948 ; CHECK-LABEL: @slt_zero_add_nsw(
1949 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A:%.*]], -1
1950 ; CHECK-NEXT:    ret i1 [[CMP]]
1952   %add = add nsw i32 %a, 1
1953   %cmp = icmp slt i32 %add, 0
1954   ret i1 %cmp
1957 ; The same fold should work with vectors.
1959 define <2 x i1> @slt_zero_add_nsw_splat_vec(<2 x i8> %a) {
1960 ; CHECK-LABEL: @slt_zero_add_nsw_splat_vec(
1961 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], splat (i8 -1)
1962 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
1964   %add = add nsw <2 x i8> %a, <i8 1, i8 1>
1965   %cmp = icmp slt <2 x i8> %add, zeroinitializer
1966   ret <2 x i1> %cmp
1969 ; Test the edges - instcombine should not interfere with simplification to constants.
1970 ; Constant subtraction does not overflow, but this is false.
1972 define i1 @nsw_slt3_ov_no(i8 %a) {
1973 ; CHECK-LABEL: @nsw_slt3_ov_no(
1974 ; CHECK-NEXT:    ret i1 false
1976   %b = add nsw i8 %a, 100
1977   %c = icmp slt i8 %b, -28
1978   ret i1 %c
1981 ; Test the edges - instcombine should not interfere with simplification to constants.
1982 ; Constant subtraction overflows. This is false.
1984 define i1 @nsw_slt4_ov(i8 %a) {
1985 ; CHECK-LABEL: @nsw_slt4_ov(
1986 ; CHECK-NEXT:    ret i1 false
1988   %b = add nsw i8 %a, 100
1989   %c = icmp slt i8 %b, -29
1990   ret i1 %c
1993 ; Test the edges - instcombine should not interfere with simplification to constants.
1994 ; Constant subtraction overflows. This is true.
1996 define i1 @nsw_slt5_ov(i8 %a) {
1997 ; CHECK-LABEL: @nsw_slt5_ov(
1998 ; CHECK-NEXT:    ret i1 true
2000   %b = add nsw i8 %a, -100
2001   %c = icmp slt i8 %b, 28
2002   ret i1 %c
2005 ; InstCombine should not thwart this opportunity to simplify completely.
2007 define i1 @slt_zero_add_nsw_signbit(i8 %x) {
2008 ; CHECK-LABEL: @slt_zero_add_nsw_signbit(
2009 ; CHECK-NEXT:    ret i1 true
2011   %y = add nsw i8 %x, -128
2012   %z = icmp slt i8 %y, 0
2013   ret i1 %z
2016 ; InstCombine should not thwart this opportunity to simplify completely.
2018 define i1 @slt_zero_add_nuw_signbit(i8 %x) {
2019 ; CHECK-LABEL: @slt_zero_add_nuw_signbit(
2020 ; CHECK-NEXT:    ret i1 true
2022   %y = add nuw i8 %x, 128
2023   %z = icmp slt i8 %y, 0
2024   ret i1 %z
2027 define i1 @reduce_add_ult(i32 %in) {
2028 ; CHECK-LABEL: @reduce_add_ult(
2029 ; CHECK-NEXT:    [[A18:%.*]] = icmp ult i32 [[IN:%.*]], 9
2030 ; CHECK-NEXT:    ret i1 [[A18]]
2032   %a6 = add nuw i32 %in, 3
2033   %a18 = icmp ult i32 %a6, 12
2034   ret i1 %a18
2037 define i1 @reduce_add_ugt(i32 %in) {
2038 ; CHECK-LABEL: @reduce_add_ugt(
2039 ; CHECK-NEXT:    [[A18:%.*]] = icmp ugt i32 [[IN:%.*]], 9
2040 ; CHECK-NEXT:    ret i1 [[A18]]
2042   %a6 = add nuw i32 %in, 3
2043   %a18 = icmp ugt i32 %a6, 12
2044   ret i1 %a18
2047 define i1 @reduce_add_ule(i32 %in) {
2048 ; CHECK-LABEL: @reduce_add_ule(
2049 ; CHECK-NEXT:    [[A18:%.*]] = icmp ult i32 [[IN:%.*]], 10
2050 ; CHECK-NEXT:    ret i1 [[A18]]
2052   %a6 = add nuw i32 %in, 3
2053   %a18 = icmp ule i32 %a6, 12
2054   ret i1 %a18
2057 define i1 @reduce_add_uge(i32 %in) {
2058 ; CHECK-LABEL: @reduce_add_uge(
2059 ; CHECK-NEXT:    [[A18:%.*]] = icmp ugt i32 [[IN:%.*]], 8
2060 ; CHECK-NEXT:    ret i1 [[A18]]
2062   %a6 = add nuw i32 %in, 3
2063   %a18 = icmp uge i32 %a6, 12
2064   ret i1 %a18
2067 define i1 @ult_add_ssubov(i32 %in) {
2068 ; CHECK-LABEL: @ult_add_ssubov(
2069 ; CHECK-NEXT:    ret i1 false
2071   %a6 = add nuw i32 %in, 71
2072   %a18 = icmp ult i32 %a6, 3
2073   ret i1 %a18
2076 define i1 @ult_add_nonuw(i8 %in) {
2077 ; CHECK-LABEL: @ult_add_nonuw(
2078 ; CHECK-NEXT:    [[A6:%.*]] = add i8 [[IN:%.*]], 71
2079 ; CHECK-NEXT:    [[A18:%.*]] = icmp ult i8 [[A6]], 12
2080 ; CHECK-NEXT:    ret i1 [[A18]]
2082   %a6 = add i8 %in, 71
2083   %a18 = icmp ult i8 %a6, 12
2084   ret i1 %a18
2087 define i1 @uge_add_nonuw(i32 %in) {
2088 ; CHECK-LABEL: @uge_add_nonuw(
2089 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[IN:%.*]], -9
2090 ; CHECK-NEXT:    [[A18:%.*]] = icmp ult i32 [[TMP1]], -12
2091 ; CHECK-NEXT:    ret i1 [[A18]]
2093   %a6 = add i32 %in, 3
2094   %a18 = icmp uge i32 %a6, 12
2095   ret i1 %a18
2098 ; Test unsigned add overflow patterns. The div ops are only here to
2099 ; thwart complexity based canonicalization of the operand order.
2101 define i1 @op_ugt_sum_commute1(i8 %p1, i8 %p2) {
2102 ; CHECK-LABEL: @op_ugt_sum_commute1(
2103 ; CHECK-NEXT:    [[X:%.*]] = sdiv i8 42, [[P1:%.*]]
2104 ; CHECK-NEXT:    [[Y:%.*]] = sdiv i8 42, [[P2:%.*]]
2105 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[X]], -1
2106 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 [[Y]], [[TMP1]]
2107 ; CHECK-NEXT:    ret i1 [[C]]
2109   %x = sdiv i8 42, %p1
2110   %y = sdiv i8 42, %p2
2111   %a = add i8 %x, %y
2112   %c = icmp ugt i8 %x, %a
2113   ret i1 %c
2116 define <2 x i1> @op_ugt_sum_vec_commute2(<2 x i8> %p1, <2 x i8> %p2) {
2117 ; CHECK-LABEL: @op_ugt_sum_vec_commute2(
2118 ; CHECK-NEXT:    [[X:%.*]] = sdiv <2 x i8> <i8 42, i8 -42>, [[P1:%.*]]
2119 ; CHECK-NEXT:    [[Y:%.*]] = sdiv <2 x i8> <i8 42, i8 -42>, [[P2:%.*]]
2120 ; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i8> [[X]], splat (i8 -1)
2121 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt <2 x i8> [[Y]], [[TMP1]]
2122 ; CHECK-NEXT:    ret <2 x i1> [[C]]
2124   %x = sdiv <2 x i8> <i8 42, i8 -42>, %p1
2125   %y = sdiv <2 x i8> <i8 42, i8 -42>, %p2
2126   %a = add <2 x i8> %y, %x
2127   %c = icmp ugt <2 x i8> %x, %a
2128   ret <2 x i1> %c
2131 define i1 @sum_ugt_op_uses(i8 %p1, i8 %p2, ptr %p3) {
2132 ; CHECK-LABEL: @sum_ugt_op_uses(
2133 ; CHECK-NEXT:    [[X:%.*]] = sdiv i8 42, [[P1:%.*]]
2134 ; CHECK-NEXT:    [[Y:%.*]] = sdiv i8 42, [[P2:%.*]]
2135 ; CHECK-NEXT:    [[A:%.*]] = add nsw i8 [[X]], [[Y]]
2136 ; CHECK-NEXT:    store i8 [[A]], ptr [[P3:%.*]], align 1
2137 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 [[X]], [[A]]
2138 ; CHECK-NEXT:    ret i1 [[C]]
2140   %x = sdiv i8 42, %p1
2141   %y = sdiv i8 42, %p2
2142   %a = add i8 %x, %y
2143   store i8 %a, ptr %p3
2144   %c = icmp ugt i8 %x, %a
2145   ret i1 %c
2148 define <2 x i1> @sum_ult_op_vec_commute1(<2 x i8> %p1, <2 x i8> %p2) {
2149 ; CHECK-LABEL: @sum_ult_op_vec_commute1(
2150 ; CHECK-NEXT:    [[X:%.*]] = sdiv <2 x i8> <i8 42, i8 -42>, [[P1:%.*]]
2151 ; CHECK-NEXT:    [[Y:%.*]] = sdiv <2 x i8> <i8 -42, i8 42>, [[P2:%.*]]
2152 ; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i8> [[X]], splat (i8 -1)
2153 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt <2 x i8> [[Y]], [[TMP1]]
2154 ; CHECK-NEXT:    ret <2 x i1> [[C]]
2156   %x = sdiv <2 x i8> <i8 42, i8 -42>, %p1
2157   %y = sdiv <2 x i8> <i8 -42, i8 42>, %p2
2158   %a = add <2 x i8> %x, %y
2159   %c = icmp ult <2 x i8> %a, %x
2160   ret <2 x i1> %c
2163 define i1 @sum_ult_op_commute2(i8 %p1, i8 %p2) {
2164 ; CHECK-LABEL: @sum_ult_op_commute2(
2165 ; CHECK-NEXT:    [[X:%.*]] = sdiv i8 42, [[P1:%.*]]
2166 ; CHECK-NEXT:    [[Y:%.*]] = sdiv i8 42, [[P2:%.*]]
2167 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[X]], -1
2168 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 [[Y]], [[TMP1]]
2169 ; CHECK-NEXT:    ret i1 [[C]]
2171   %x = sdiv i8 42, %p1
2172   %y = sdiv i8 42, %p2
2173   %a = add i8 %y, %x
2174   %c = icmp ult i8 %a, %x
2175   ret i1 %c
2178 define i1 @sum_ult_op_uses(i8 %x, i8 %y, ptr %p) {
2179 ; CHECK-LABEL: @sum_ult_op_uses(
2180 ; CHECK-NEXT:    [[A:%.*]] = add i8 [[Y:%.*]], [[X:%.*]]
2181 ; CHECK-NEXT:    store i8 [[A]], ptr [[P:%.*]], align 1
2182 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[A]], [[X]]
2183 ; CHECK-NEXT:    ret i1 [[C]]
2185   %a = add i8 %y, %x
2186   store i8 %a, ptr %p
2187   %c = icmp ult i8 %a, %x
2188   ret i1 %c
2191 ; X + Z >s Y + Z -> X > Y if there is no overflow.
2192 define i1 @common_op_nsw(i32 %x, i32 %y, i32 %z) {
2193 ; CHECK-LABEL: @common_op_nsw(
2194 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
2195 ; CHECK-NEXT:    ret i1 [[C]]
2197   %lhs = add nsw i32 %x, %z
2198   %rhs = add nsw i32 %y, %z
2199   %c = icmp sgt i32 %lhs, %rhs
2200   ret i1 %c
2203 define i1 @common_op_nsw_extra_uses(i32 %x, i32 %y, i32 %z) {
2204 ; CHECK-LABEL: @common_op_nsw_extra_uses(
2205 ; CHECK-NEXT:    [[LHS:%.*]] = add nsw i32 [[X:%.*]], [[Z:%.*]]
2206 ; CHECK-NEXT:    call void @use(i32 [[LHS]])
2207 ; CHECK-NEXT:    [[RHS:%.*]] = add nsw i32 [[Y:%.*]], [[Z]]
2208 ; CHECK-NEXT:    call void @use(i32 [[RHS]])
2209 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[X]], [[Y]]
2210 ; CHECK-NEXT:    ret i1 [[C]]
2212   %lhs = add nsw i32 %x, %z
2213   call void @use(i32 %lhs)
2214   %rhs = add nsw i32 %y, %z
2215   call void @use(i32 %rhs)
2216   %c = icmp sgt i32 %lhs, %rhs
2217   ret i1 %c
2220 ; X + Z >u Z + Y -> X > Y if there is no overflow.
2221 define i1 @common_op_nuw(i32 %x, i32 %y, i32 %z) {
2222 ; CHECK-LABEL: @common_op_nuw(
2223 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
2224 ; CHECK-NEXT:    ret i1 [[C]]
2226   %lhs = add nuw i32 %x, %z
2227   %rhs = add nuw i32 %z, %y
2228   %c = icmp ugt i32 %lhs, %rhs
2229   ret i1 %c
2232 define i1 @common_op_nuw_extra_uses(i32 %x, i32 %y, i32 %z) {
2233 ; CHECK-LABEL: @common_op_nuw_extra_uses(
2234 ; CHECK-NEXT:    [[LHS:%.*]] = add nuw i32 [[X:%.*]], [[Z:%.*]]
2235 ; CHECK-NEXT:    call void @use(i32 [[LHS]])
2236 ; CHECK-NEXT:    [[RHS:%.*]] = add nuw i32 [[Z]], [[Y:%.*]]
2237 ; CHECK-NEXT:    call void @use(i32 [[RHS]])
2238 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 [[X]], [[Y]]
2239 ; CHECK-NEXT:    ret i1 [[C]]
2241   %lhs = add nuw i32 %x, %z
2242   call void @use(i32 %lhs)
2243   %rhs = add nuw i32 %z, %y
2244   call void @use(i32 %rhs)
2245   %c = icmp ugt i32 %lhs, %rhs
2246   ret i1 %c
2249 define i1 @common_op_nsw_commute(i32 %x, i32 %y, i32 %z) {
2250 ; CHECK-LABEL: @common_op_nsw_commute(
2251 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
2252 ; CHECK-NEXT:    ret i1 [[C]]
2254   %lhs = add nsw i32 %z, %x
2255   %rhs = add nsw i32 %y, %z
2256   %c = icmp slt i32 %lhs, %rhs
2257   ret i1 %c
2260 define i1 @common_op_nuw_commute(i32 %x, i32 %y, i32 %z) {
2261 ; CHECK-LABEL: @common_op_nuw_commute(
2262 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
2263 ; CHECK-NEXT:    ret i1 [[C]]
2265   %lhs = add nuw i32 %z, %x
2266   %rhs = add nuw i32 %z, %y
2267   %c = icmp ult i32 %lhs, %rhs
2268   ret i1 %c
2271 ; X + Y > X -> Y > 0 if there is no overflow.
2272 define i1 @common_op_test29(i32 %x, i32 %y) {
2273 ; CHECK-LABEL: @common_op_test29(
2274 ; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[Y:%.*]], 0
2275 ; CHECK-NEXT:    ret i1 [[C]]
2277   %lhs = add nsw i32 %x, %y
2278   %c = icmp sgt i32 %lhs, %x
2279   ret i1 %c
2282 ; X + Y > X -> Y > 0 if there is no overflow.
2283 define i1 @sum_nuw(i32 %x, i32 %y) {
2284 ; CHECK-LABEL: @sum_nuw(
2285 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[Y:%.*]], 0
2286 ; CHECK-NEXT:    ret i1 [[C]]
2288   %lhs = add nuw i32 %x, %y
2289   %c = icmp ugt i32 %lhs, %x
2290   ret i1 %c
2293 ; X > X + Y -> 0 > Y if there is no overflow.
2294 define i1 @sum_nsw_commute(i32 %x, i32 %y) {
2295 ; CHECK-LABEL: @sum_nsw_commute(
2296 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[Y:%.*]], 0
2297 ; CHECK-NEXT:    ret i1 [[C]]
2299   %rhs = add nsw i32 %x, %y
2300   %c = icmp sgt i32 %x, %rhs
2301   ret i1 %c
2304 ; X > X + Y -> 0 > Y if there is no overflow.
2305 define i1 @sum_nuw_commute(i32 %x, i32 %y) {
2306 ; CHECK-LABEL: @sum_nuw_commute(
2307 ; CHECK-NEXT:    ret i1 false
2309   %rhs = add nuw i32 %x, %y
2310   %c = icmp ugt i32 %x, %rhs
2311   ret i1 %c
2314 ; PR2698 - https://bugs.llvm.org/show_bug.cgi?id=2698
2316 declare void @use1(i1)
2317 declare void @use8(i8)
2319 define void @bzip1(i8 %a, i8 %b, i8 %x) {
2320 ; CHECK-LABEL: @bzip1(
2321 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], [[B:%.*]]
2322 ; CHECK-NEXT:    call void @use1(i1 [[CMP]])
2323 ; CHECK-NEXT:    ret void
2325   %add1 = add i8 %a, %x
2326   %add2 = add i8 %b, %x
2327   %cmp = icmp eq i8 %add1, %add2
2328   call void @use1(i1 %cmp)
2329   ret void
2332 define void @bzip2(i8 %a, i8 %b, i8 %x) {
2333 ; CHECK-LABEL: @bzip2(
2334 ; CHECK-NEXT:    [[ADD1:%.*]] = add i8 [[A:%.*]], [[X:%.*]]
2335 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A]], [[B:%.*]]
2336 ; CHECK-NEXT:    call void @use1(i1 [[CMP]])
2337 ; CHECK-NEXT:    call void @use8(i8 [[ADD1]])
2338 ; CHECK-NEXT:    ret void
2340   %add1 = add i8 %a, %x
2341   %add2 = add i8 %b, %x
2342   %cmp = icmp eq i8 %add1, %add2
2343   call void @use1(i1 %cmp)
2344   call void @use8(i8 %add1)
2345   ret void
2348 define <2 x i1> @icmp_eq_add_undef(<2 x i32> %a) {
2349 ; CHECK-LABEL: @icmp_eq_add_undef(
2350 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 5, i32 undef>
2351 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2353   %add = add <2 x i32> %a, <i32 5, i32 undef>
2354   %cmp = icmp eq <2 x i32> %add, <i32 10, i32 10>
2355   ret <2 x i1> %cmp
2358 define <2 x i1> @icmp_eq_add_non_splat(<2 x i32> %a) {
2359 ; CHECK-LABEL: @icmp_eq_add_non_splat(
2360 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 5, i32 4>
2361 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2363   %add = add <2 x i32> %a, <i32 5, i32 6>
2364   %cmp = icmp eq <2 x i32> %add, <i32 10, i32 10>
2365   ret <2 x i1> %cmp
2368 define <2 x i1> @icmp_eq_add_undef2(<2 x i32> %a) {
2369 ; CHECK-LABEL: @icmp_eq_add_undef2(
2370 ; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i32> [[A:%.*]], splat (i32 5)
2371 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[ADD]], <i32 10, i32 undef>
2372 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2374   %add = add <2 x i32> %a, <i32 5, i32 5>
2375   %cmp = icmp eq <2 x i32> %add, <i32 10, i32 undef>
2376   ret <2 x i1> %cmp
2379 define <2 x i1> @icmp_eq_add_non_splat2(<2 x i32> %a) {
2380 ; CHECK-LABEL: @icmp_eq_add_non_splat2(
2381 ; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i32> [[A:%.*]], splat (i32 5)
2382 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[ADD]], <i32 10, i32 11>
2383 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2385   %add = add <2 x i32> %a, <i32 5, i32 5>
2386   %cmp = icmp eq <2 x i32> %add, <i32 10, i32 11>
2387   ret <2 x i1> %cmp
2390 define i1 @without_nsw_nuw(i8 %x, i8 %y) {
2391 ; CHECK-LABEL: @without_nsw_nuw(
2392 ; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[X:%.*]], 2
2393 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8 [[Y:%.*]], [[TMP1]]
2394 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
2396   %t1 = add i8 %x, 37
2397   %t2 = add i8 %y, 35
2398   %tobool = icmp eq i8 %t2, %t1
2399   ret i1 %tobool
2402 define i1 @with_nsw_nuw(i8 %x, i8 %y) {
2403 ; CHECK-LABEL: @with_nsw_nuw(
2404 ; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i8 [[X:%.*]], 2
2405 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8 [[Y:%.*]], [[TMP1]]
2406 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
2408   %t1 = add nsw nuw i8 %x, 37
2409   %t2 = add i8 %y, 35
2410   %tobool = icmp eq i8 %t2, %t1
2411   ret i1 %tobool
2414 define i1 @with_nsw_large(i8 %x, i8 %y) {
2415 ; CHECK-LABEL: @with_nsw_large(
2416 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i8 [[X:%.*]], 2
2417 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8 [[Y:%.*]], [[TMP1]]
2418 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
2420   %t1 = add nsw i8 %x, 37
2421   %t2 = add i8 %y, 35
2422   %tobool = icmp eq i8 %t2, %t1
2423   ret i1 %tobool
2426 define i1 @with_nsw_small(i8 %x, i8 %y) {
2427 ; CHECK-LABEL: @with_nsw_small(
2428 ; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y:%.*]], 2
2429 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8 [[TMP1]], [[X:%.*]]
2430 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
2432   %t1 = add nsw i8 %x, 35
2433   %t2 = add i8 %y, 37
2434   %tobool = icmp eq i8 %t2, %t1
2435   ret i1 %tobool
2438 define i1 @with_nuw_large(i8 %x, i8 %y) {
2439 ; CHECK-LABEL: @with_nuw_large(
2440 ; CHECK-NEXT:    [[TMP1:%.*]] = add nuw i8 [[X:%.*]], 2
2441 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8 [[Y:%.*]], [[TMP1]]
2442 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
2444   %t1 = add nuw i8 %x, 37
2445   %t2 = add i8 %y, 35
2446   %tobool = icmp eq i8 %t2, %t1
2447   ret i1 %tobool
2450 define i1 @with_nuw_small(i8 %x, i8 %y) {
2451 ; CHECK-LABEL: @with_nuw_small(
2452 ; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y:%.*]], 2
2453 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8 [[TMP1]], [[X:%.*]]
2454 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
2456   %t1 = add nuw i8 %x, 35
2457   %t2 = add i8 %y, 37
2458   %tobool = icmp eq i8 %t2, %t1
2459   ret i1 %tobool
2462 define i1 @with_nuw_large_negative(i8 %x, i8 %y) {
2463 ; CHECK-LABEL: @with_nuw_large_negative(
2464 ; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[X:%.*]], -2
2465 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i8 [[Y:%.*]], [[TMP1]]
2466 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
2468   %t1 = add nuw i8 %x, -37
2469   %t2 = add i8 %y, -35
2470   %tobool = icmp eq i8 %t2, %t1
2471   ret i1 %tobool
2474 define i1 @ugt_offset(i8 %a) {
2475 ; CHECK-LABEL: @ugt_offset(
2476 ; CHECK-NEXT:    [[OV:%.*]] = icmp slt i8 [[A:%.*]], -124
2477 ; CHECK-NEXT:    ret i1 [[OV]]
2479   %t = add i8 %a, 124
2480   %ov = icmp ugt i8 %t, 251
2481   ret i1 %ov
2484 define i1 @ugt_offset_use(i32 %a) {
2485 ; CHECK-LABEL: @ugt_offset_use(
2486 ; CHECK-NEXT:    [[T:%.*]] = add i32 [[A:%.*]], 42
2487 ; CHECK-NEXT:    call void @use(i32 [[T]])
2488 ; CHECK-NEXT:    [[OV:%.*]] = icmp slt i32 [[A]], -42
2489 ; CHECK-NEXT:    ret i1 [[OV]]
2491   %t = add i32 %a, 42
2492   call void @use(i32 %t)
2493   %ov = icmp ugt i32 %t, 2147483689
2494   ret i1 %ov
2497 define <2 x i1> @ugt_offset_splat(<2 x i5> %a) {
2498 ; CHECK-LABEL: @ugt_offset_splat(
2499 ; CHECK-NEXT:    [[OV:%.*]] = icmp slt <2 x i5> [[A:%.*]], splat (i5 -9)
2500 ; CHECK-NEXT:    ret <2 x i1> [[OV]]
2502   %t = add <2 x i5> %a, <i5 9, i5 9>
2503   %ov = icmp ugt <2 x i5> %t, <i5 24, i5 24>
2504   ret <2 x i1> %ov
2507 ; negative test - constants must differ by SMAX
2509 define i1 @ugt_wrong_offset(i8 %a) {
2510 ; CHECK-LABEL: @ugt_wrong_offset(
2511 ; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[A:%.*]], 127
2512 ; CHECK-NEXT:    [[OV:%.*]] = icmp ult i8 [[TMP1]], 4
2513 ; CHECK-NEXT:    ret i1 [[OV]]
2515   %t = add i8 %a, 123
2516   %ov = icmp ugt i8 %t, 251
2517   ret i1 %ov
2520 define i1 @ugt_offset_nuw(i8 %a) {
2521 ; CHECK-LABEL: @ugt_offset_nuw(
2522 ; CHECK-NEXT:    [[OV:%.*]] = icmp slt i8 [[A:%.*]], 0
2523 ; CHECK-NEXT:    ret i1 [[OV]]
2525   %t = add nuw i8 %a, 124
2526   %ov = icmp ugt i8 %t, 251
2527   ret i1 %ov
2530 define i1 @ult_offset(i8 %a) {
2531 ; CHECK-LABEL: @ult_offset(
2532 ; CHECK-NEXT:    [[OV:%.*]] = icmp sgt i8 [[A:%.*]], 5
2533 ; CHECK-NEXT:    ret i1 [[OV]]
2535   %t = add i8 %a, 250
2536   %ov = icmp ult i8 %t, 122
2537   ret i1 %ov
2540 define i1 @ult_offset_use(i32 %a) {
2541 ; CHECK-LABEL: @ult_offset_use(
2542 ; CHECK-NEXT:    [[T:%.*]] = add i32 [[A:%.*]], 42
2543 ; CHECK-NEXT:    call void @use(i32 [[T]])
2544 ; CHECK-NEXT:    [[OV:%.*]] = icmp sgt i32 [[A]], -43
2545 ; CHECK-NEXT:    ret i1 [[OV]]
2547   %t = add i32 %a, 42
2548   call void @use(i32 %t)
2549   %ov = icmp ult i32 %t, 2147483690
2550   ret i1 %ov
2553 define <2 x i1> @ult_offset_splat(<2 x i5> %a) {
2554 ; CHECK-LABEL: @ult_offset_splat(
2555 ; CHECK-NEXT:    [[OV:%.*]] = icmp sgt <2 x i5> [[A:%.*]], splat (i5 -10)
2556 ; CHECK-NEXT:    ret <2 x i1> [[OV]]
2558   %t = add <2 x i5> %a, <i5 9, i5 9>
2559   %ov = icmp ult <2 x i5> %t, <i5 25, i5 25>
2560   ret <2 x i1> %ov
2563 ; negative test - constants must differ by SMIN
2565 define i1 @ult_wrong_offset(i8 %a) {
2566 ; CHECK-LABEL: @ult_wrong_offset(
2567 ; CHECK-NEXT:    [[T:%.*]] = add i8 [[A:%.*]], -6
2568 ; CHECK-NEXT:    [[OV:%.*]] = icmp ult i8 [[T]], 123
2569 ; CHECK-NEXT:    ret i1 [[OV]]
2571   %t = add i8 %a, 250
2572   %ov = icmp ult i8 %t, 123
2573   ret i1 %ov
2576 define i1 @ult_offset_nuw(i8 %a) {
2577 ; CHECK-LABEL: @ult_offset_nuw(
2578 ; CHECK-NEXT:    [[OV:%.*]] = icmp sgt i8 [[A:%.*]], -1
2579 ; CHECK-NEXT:    ret i1 [[OV]]
2581   %t = add nuw i8 %a, 42
2582   %ov = icmp ult i8 %t, 170
2583   ret i1 %ov
2586 define i1 @sgt_offset(i8 %a) {
2587 ; CHECK-LABEL: @sgt_offset(
2588 ; CHECK-NEXT:    [[OV:%.*]] = icmp ult i8 [[A:%.*]], -122
2589 ; CHECK-NEXT:    ret i1 [[OV]]
2591   %t = add i8 %a, -6
2592   %ov = icmp sgt i8 %t, -7
2593   ret i1 %ov
2596 define i1 @sgt_offset_use(i32 %a) {
2597 ; CHECK-LABEL: @sgt_offset_use(
2598 ; CHECK-NEXT:    [[T:%.*]] = add i32 [[A:%.*]], 42
2599 ; CHECK-NEXT:    call void @use(i32 [[T]])
2600 ; CHECK-NEXT:    [[OV:%.*]] = icmp ult i32 [[A]], 2147483606
2601 ; CHECK-NEXT:    ret i1 [[OV]]
2603   %t = add i32 %a, 42
2604   call void @use(i32 %t)
2605   %ov = icmp sgt i32 %t, 41
2606   ret i1 %ov
2609 define <2 x i1> @sgt_offset_splat(<2 x i5> %a) {
2610 ; CHECK-LABEL: @sgt_offset_splat(
2611 ; CHECK-NEXT:    [[OV:%.*]] = icmp ult <2 x i5> [[A:%.*]], splat (i5 7)
2612 ; CHECK-NEXT:    ret <2 x i1> [[OV]]
2614   %t = add <2 x i5> %a, <i5 9, i5 9>
2615   %ov = icmp sgt <2 x i5> %t, <i5 8, i5 8>
2616   ret <2 x i1> %ov
2619 ; negative test - constants must differ by 1
2621 define i1 @sgt_wrong_offset(i8 %a) {
2622 ; CHECK-LABEL: @sgt_wrong_offset(
2623 ; CHECK-NEXT:    [[T:%.*]] = add i8 [[A:%.*]], -7
2624 ; CHECK-NEXT:    [[OV:%.*]] = icmp sgt i8 [[T]], -7
2625 ; CHECK-NEXT:    ret i1 [[OV]]
2627   %t = add i8 %a, -7
2628   %ov = icmp sgt i8 %t, -7
2629   ret i1 %ov
2632 define i1 @sgt_offset_nsw(i8 %a, i8 %c) {
2633 ; CHECK-LABEL: @sgt_offset_nsw(
2634 ; CHECK-NEXT:    [[OV:%.*]] = icmp sgt i8 [[A:%.*]], -1
2635 ; CHECK-NEXT:    ret i1 [[OV]]
2637   %t = add nsw i8 %a, 42
2638   %ov = icmp sgt i8 %t, 41
2639   ret i1 %ov
2642 define i1 @slt_offset(i8 %a) {
2643 ; CHECK-LABEL: @slt_offset(
2644 ; CHECK-NEXT:    [[OV:%.*]] = icmp ugt i8 [[A:%.*]], -123
2645 ; CHECK-NEXT:    ret i1 [[OV]]
2647   %t = add i8 %a, -6
2648   %ov = icmp slt i8 %t, -6
2649   ret i1 %ov
2652 define i1 @slt_offset_use(i32 %a) {
2653 ; CHECK-LABEL: @slt_offset_use(
2654 ; CHECK-NEXT:    [[T:%.*]] = add i32 [[A:%.*]], 42
2655 ; CHECK-NEXT:    call void @use(i32 [[T]])
2656 ; CHECK-NEXT:    [[OV:%.*]] = icmp ugt i32 [[A]], 2147483605
2657 ; CHECK-NEXT:    ret i1 [[OV]]
2659   %t = add i32 %a, 42
2660   call void @use(i32 %t)
2661   %ov = icmp slt i32 %t, 42
2662   ret i1 %ov
2665 define <2 x i1> @slt_offset_splat(<2 x i5> %a) {
2666 ; CHECK-LABEL: @slt_offset_splat(
2667 ; CHECK-NEXT:    [[OV:%.*]] = icmp ugt <2 x i5> [[A:%.*]], splat (i5 6)
2668 ; CHECK-NEXT:    ret <2 x i1> [[OV]]
2670   %t = add <2 x i5> %a, <i5 9, i5 9>
2671   %ov = icmp slt <2 x i5> %t, <i5 9, i5 9>
2672   ret <2 x i1> %ov
2675 ; negative test - constants must be equal
2677 define i1 @slt_wrong_offset(i8 %a) {
2678 ; CHECK-LABEL: @slt_wrong_offset(
2679 ; CHECK-NEXT:    [[T:%.*]] = add i8 [[A:%.*]], -6
2680 ; CHECK-NEXT:    [[OV:%.*]] = icmp slt i8 [[T]], -7
2681 ; CHECK-NEXT:    ret i1 [[OV]]
2683   %t = add i8 %a, -6
2684   %ov = icmp slt i8 %t, -7
2685   ret i1 %ov
2688 define i1 @slt_offset_nsw(i8 %a, i8 %c) {
2689 ; CHECK-LABEL: @slt_offset_nsw(
2690 ; CHECK-NEXT:    [[OV:%.*]] = icmp slt i8 [[A:%.*]], 0
2691 ; CHECK-NEXT:    ret i1 [[OV]]
2693   %t = add nsw i8 %a, 42
2694   %ov = icmp slt i8 %t, 42
2695   ret i1 %ov
2698 ; In the following 4 tests, we could push the inc/dec
2699 ; through the min/max, but we should not break up the
2700 ; min/max idiom by using different icmp and select
2701 ; operands.
2703 define i32 @increment_max(i32 %x) {
2704 ; CHECK-LABEL: @increment_max(
2705 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 -1)
2706 ; CHECK-NEXT:    [[S:%.*]] = add nsw i32 [[TMP1]], 1
2707 ; CHECK-NEXT:    ret i32 [[S]]
2709   %a = add nsw i32 %x, 1
2710   %c = icmp sgt i32 %a, 0
2711   %s = select i1 %c, i32 %a, i32 0
2712   ret i32 %s
2715 define i32 @decrement_max(i32 %x) {
2716 ; CHECK-LABEL: @decrement_max(
2717 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 1)
2718 ; CHECK-NEXT:    [[S:%.*]] = add nsw i32 [[TMP1]], -1
2719 ; CHECK-NEXT:    ret i32 [[S]]
2721   %a = add nsw i32 %x, -1
2722   %c = icmp sgt i32 %a, 0
2723   %s = select i1 %c, i32 %a, i32 0
2724   ret i32 %s
2727 define i32 @increment_min(i32 %x) {
2728 ; CHECK-LABEL: @increment_min(
2729 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 -1)
2730 ; CHECK-NEXT:    [[S:%.*]] = add nsw i32 [[TMP1]], 1
2731 ; CHECK-NEXT:    ret i32 [[S]]
2733   %a = add nsw i32 %x, 1
2734   %c = icmp slt i32 %a, 0
2735   %s = select i1 %c, i32 %a, i32 0
2736   ret i32 %s
2739 define i32 @decrement_min(i32 %x) {
2740 ; CHECK-LABEL: @decrement_min(
2741 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 1)
2742 ; CHECK-NEXT:    [[S:%.*]] = add nsw i32 [[TMP1]], -1
2743 ; CHECK-NEXT:    ret i32 [[S]]
2745   %a = add nsw i32 %x, -1
2746   %c = icmp slt i32 %a, 0
2747   %s = select i1 %c, i32 %a, i32 0
2748   ret i32 %s
2751 define i1 @icmp_add_add_C(i32 %a, i32 %b) {
2752 ; CHECK-LABEL: @icmp_add_add_C(
2753 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[B:%.*]]
2754 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], [[TMP1]]
2755 ; CHECK-NEXT:    ret i1 [[CMP]]
2757   %add1 = add i32 %a, %b
2758   %add2 = add i32 %add1, -1
2759   %cmp = icmp ult i32 %add2, %a
2760   ret i1 %cmp
2763 define i1 @icmp_add_add_C_pred(i32 %a, i32 %b) {
2764 ; CHECK-LABEL: @icmp_add_add_C_pred(
2765 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[B:%.*]]
2766 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[A:%.*]], [[TMP1]]
2767 ; CHECK-NEXT:    ret i1 [[CMP]]
2769   %add1 = add i32 %a, %b
2770   %add2 = add i32 %add1, -1
2771   %cmp = icmp uge i32 %add2, %a
2772   ret i1 %cmp
2775 define i1 @icmp_add_add_C_wrong_pred(i32 %a, i32 %b) {
2776 ; CHECK-LABEL: @icmp_add_add_C_wrong_pred(
2777 ; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
2778 ; CHECK-NEXT:    [[ADD2:%.*]] = add i32 [[ADD1]], -1
2779 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[ADD2]], [[A]]
2780 ; CHECK-NEXT:    ret i1 [[CMP]]
2782   %add1 = add i32 %a, %b
2783   %add2 = add i32 %add1, -1
2784   %cmp = icmp ule i32 %add2, %a
2785   ret i1 %cmp
2788 define i1 @icmp_add_add_C_wrong_operand(i32 %a, i32 %b, i32 %c) {
2789 ; CHECK-LABEL: @icmp_add_add_C_wrong_operand(
2790 ; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
2791 ; CHECK-NEXT:    [[ADD2:%.*]] = add i32 [[ADD1]], -1
2792 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD2]], [[C:%.*]]
2793 ; CHECK-NEXT:    ret i1 [[CMP]]
2795   %add1 = add i32 %a, %b
2796   %add2 = add i32 %add1, -1
2797   %cmp = icmp ult i32 %add2, %c
2798   ret i1 %cmp
2801 define i1 @icmp_add_add_C_different_const(i32 %a, i32 %b) {
2802 ; CHECK-LABEL: @icmp_add_add_C_different_const(
2803 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 -43, [[B:%.*]]
2804 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[TMP1]], [[A:%.*]]
2805 ; CHECK-NEXT:    ret i1 [[CMP]]
2807   %add1 = add i32 %a, %b
2808   %add2 = add i32 %add1, 42
2809   %cmp = icmp ult i32 %add2, %a
2810   ret i1 %cmp
2813 define <2 x i1> @icmp_add_add_C_vector(<2 x i8> %a, <2 x i8> %b) {
2814 ; CHECK-LABEL: @icmp_add_add_C_vector(
2815 ; CHECK-NEXT:    [[TMP1:%.*]] = sub <2 x i8> <i8 -11, i8 -21>, [[B:%.*]]
2816 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i8> [[TMP1]], [[A:%.*]]
2817 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2819   %add1 = add <2 x i8> %a, %b
2820   %add2 = add <2 x i8> %add1, <i8 10, i8 20>
2821   %cmp = icmp ult <2 x i8> %add2, %a
2822   ret <2 x i1> %cmp
2825 define <2 x i1> @icmp_add_add_C_vector_undef(<2 x i8> %a, <2 x i8> %b) {
2826 ; CHECK-LABEL: @icmp_add_add_C_vector_undef(
2827 ; CHECK-NEXT:    [[TMP1:%.*]] = sub <2 x i8> <i8 -11, i8 undef>, [[B:%.*]]
2828 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i8> [[TMP1]], [[A:%.*]]
2829 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
2831   %add1 = add <2 x i8> %a, %b
2832   %add2 = add <2 x i8> %add1, <i8 10, i8 undef>
2833   %cmp = icmp ult <2 x i8> %add2, %a
2834   ret <2 x i1> %cmp
2837 define i1 @icmp_add_add_C_comm1(i32 %a, i32 %b) {
2838 ; CHECK-LABEL: @icmp_add_add_C_comm1(
2839 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[B:%.*]]
2840 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], [[TMP1]]
2841 ; CHECK-NEXT:    ret i1 [[CMP]]
2843   %add1 = add i32 %b, %a
2844   %add2 = add i32 %add1, -1
2845   %cmp = icmp ult i32 %add2, %a
2846   ret i1 %cmp
2849 define i1 @icmp_add_add_C_comm2(i32 %X, i32 %b) {
2850 ; CHECK-LABEL: @icmp_add_add_C_comm2(
2851 ; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[X:%.*]]
2852 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[B:%.*]]
2853 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A]], [[TMP1]]
2854 ; CHECK-NEXT:    ret i1 [[CMP]]
2856   %a = udiv i32 42, %X ; thwart complexity-based canonicalization
2857   %add1 = add i32 %a, %b
2858   %add2 = add i32 %add1, -1
2859   %cmp = icmp ugt i32 %a, %add2
2860   ret i1 %cmp
2863 define i1 @icmp_add_add_C_comm2_pred(i32 %X, i32 %b) {
2864 ; CHECK-LABEL: @icmp_add_add_C_comm2_pred(
2865 ; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[X:%.*]]
2866 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[B:%.*]]
2867 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[A]], [[TMP1]]
2868 ; CHECK-NEXT:    ret i1 [[CMP]]
2870   %a = udiv i32 42, %X ; thwart complexity-based canonicalization
2871   %add1 = add i32 %a, %b
2872   %add2 = add i32 %add1, -1
2873   %cmp = icmp ule i32 %a, %add2
2874   ret i1 %cmp
2877 define i1 @icmp_add_add_C_comm2_wrong_pred(i32 %X, i32 %b) {
2878 ; CHECK-LABEL: @icmp_add_add_C_comm2_wrong_pred(
2879 ; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[X:%.*]]
2880 ; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[A]], [[B:%.*]]
2881 ; CHECK-NEXT:    [[ADD2:%.*]] = add i32 [[ADD1]], -1
2882 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A]], [[ADD2]]
2883 ; CHECK-NEXT:    ret i1 [[CMP]]
2885   %a = udiv i32 42, %X ; thwart complexity-based canonicalization
2886   %add1 = add i32 %a, %b
2887   %add2 = add i32 %add1, -1
2888   %cmp = icmp ult i32 %a, %add2
2889   ret i1 %cmp
2892 define i1 @icmp_add_add_C_comm3(i32 %X, i32 %b) {
2893 ; CHECK-LABEL: @icmp_add_add_C_comm3(
2894 ; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[X:%.*]]
2895 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[B:%.*]]
2896 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A]], [[TMP1]]
2897 ; CHECK-NEXT:    ret i1 [[CMP]]
2899   %a = udiv i32 42, %X ; thwart complexity-based canonicalization
2900   %add1 = add i32 %b, %a
2901   %add2 = add i32 %add1, -1
2902   %cmp = icmp ugt i32 %a, %add2
2903   ret i1 %cmp
2906 define i1 @icmp_add_add_C_extra_use1(i32 %a, i32 %b) {
2907 ; CHECK-LABEL: @icmp_add_add_C_extra_use1(
2908 ; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
2909 ; CHECK-NEXT:    [[ADD2:%.*]] = add i32 [[ADD1]], -1
2910 ; CHECK-NEXT:    call void @use(i32 [[ADD2]])
2911 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD2]], [[A]]
2912 ; CHECK-NEXT:    ret i1 [[CMP]]
2914   %add1 = add i32 %a, %b
2915   %add2 = add i32 %add1, -1
2916   call void @use(i32 %add2)
2917   %cmp = icmp ult i32 %add2, %a
2918   ret i1 %cmp
2921 define i1 @icmp_add_add_C_extra_use2(i32 %a, i32 %b) {
2922 ; CHECK-LABEL: @icmp_add_add_C_extra_use2(
2923 ; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
2924 ; CHECK-NEXT:    call void @use(i32 [[ADD1]])
2925 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[B]]
2926 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[A]], [[TMP1]]
2927 ; CHECK-NEXT:    ret i1 [[CMP]]
2929   %add1 = add i32 %a, %b
2930   call void @use(i32 %add1)
2931   %add2 = add i32 %add1, -1
2932   %cmp = icmp ult i32 %add2, %a
2933   ret i1 %cmp
2936 ; PR57635 - fold ULT->ULE pre-decrement of a non-zero inputs
2938 define i1 @icmp_dec_assume_nonzero(i8 %x) {
2939 ; CHECK-LABEL: @icmp_dec_assume_nonzero(
2940 ; CHECK-NEXT:    [[Z:%.*]] = icmp ne i8 [[X:%.*]], 0
2941 ; CHECK-NEXT:    call void @llvm.assume(i1 [[Z]])
2942 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[X]], 8
2943 ; CHECK-NEXT:    ret i1 [[C]]
2945   %z = icmp ne i8 %x, 0
2946   call void @llvm.assume(i1 %z)
2947   %i = add i8 %x, -1
2948   %c = icmp ult i8 %i, 7
2949   ret i1 %c
2952 define i1 @icmp_dec_sub_assume_nonzero(i8 %x) {
2953 ; CHECK-LABEL: @icmp_dec_sub_assume_nonzero(
2954 ; CHECK-NEXT:    [[Z:%.*]] = icmp ne i8 [[X:%.*]], 0
2955 ; CHECK-NEXT:    call void @llvm.assume(i1 [[Z]])
2956 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[X]], 12
2957 ; CHECK-NEXT:    ret i1 [[C]]
2959   %z = icmp ne i8 %x, 0
2960   call void @llvm.assume(i1 %z)
2961   %i = sub i8 %x, 1
2962   %c = icmp ult i8 %i, 11
2963   ret i1 %c
2966 define i1 @icmp_dec_nonzero(i16 %x) {
2967 ; CHECK-LABEL: @icmp_dec_nonzero(
2968 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i16 [[X:%.*]], 8
2969 ; CHECK-NEXT:    ret i1 [[C]]
2971   %o = or i16 %x, 4
2972   %i = add i16 %o, -1
2973   %c = icmp ult i16 %i, 7
2974   ret i1 %c
2977 define <2 x i1> @icmp_dec_nonzero_vec(<2 x i32> %x) {
2978 ; CHECK-LABEL: @icmp_dec_nonzero_vec(
2979 ; CHECK-NEXT:    [[O:%.*]] = or <2 x i32> [[X:%.*]], splat (i32 8)
2980 ; CHECK-NEXT:    [[I:%.*]] = add nsw <2 x i32> [[O]], splat (i32 -1)
2981 ; CHECK-NEXT:    [[C:%.*]] = icmp ult <2 x i32> [[I]], <i32 15, i32 17>
2982 ; CHECK-NEXT:    ret <2 x i1> [[C]]
2984   %o = or <2 x i32> %x, <i32 8, i32 8>
2985   %i = add <2 x i32> %o, <i32 -1, i32 -1>
2986   %c = icmp ult <2 x i32> %i, <i32 15, i32 17>
2987   ret <2 x i1> %c
2990 ; Negative test
2991 define i1 @icmp_dec_notnonzero(i8 %x) {
2992 ; CHECK-LABEL: @icmp_dec_notnonzero(
2993 ; CHECK-NEXT:    [[I:%.*]] = add i8 [[X:%.*]], -1
2994 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[I]], 11
2995 ; CHECK-NEXT:    ret i1 [[C]]
2997   %i = add i8 %x, -1
2998   %c = icmp ult i8 %i, 11
2999   ret i1 %c
3002 define i1 @icmp_addnuw_nonzero(i8 %x, i8 %y) {
3003 ; CHECK-LABEL: @icmp_addnuw_nonzero(
3004 ; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
3005 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[TMP1]], 0
3006 ; CHECK-NEXT:    ret i1 [[C]]
3008   %i = add nuw i8 %x, %y
3009   %c = icmp eq i8 %i, 0
3010   ret i1 %c
3013 define i1 @icmp_addnuw_nonzero_fail_multiuse(i32 %x, i32 %y) {
3014 ; CHECK-LABEL: @icmp_addnuw_nonzero_fail_multiuse(
3015 ; CHECK-NEXT:    [[I:%.*]] = add nuw i32 [[X:%.*]], [[Y:%.*]]
3016 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[I]], 0
3017 ; CHECK-NEXT:    call void @use(i32 [[I]])
3018 ; CHECK-NEXT:    ret i1 [[C]]
3020   %i = add nuw i32 %x, %y
3021   %c = icmp eq i32 %i, 0
3022   call void @use(i32 %i)
3023   ret i1 %c
3026 define i1 @ult_add_C2_pow2_C_neg(i8 %x) {
3027 ; CHECK-LABEL: @ult_add_C2_pow2_C_neg(
3028 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -32
3029 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[TMP1]], -64
3030 ; CHECK-NEXT:    ret i1 [[C]]
3032   %i = add i8 %x, 32
3033   %c = icmp ult i8 %i, -32
3034   ret i1 %c
3037 define i1 @ult_add_nsw_C2_pow2_C_neg(i8 %x) {
3038 ; CHECK-LABEL: @ult_add_nsw_C2_pow2_C_neg(
3039 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -32
3040 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[TMP1]], -64
3041 ; CHECK-NEXT:    ret i1 [[C]]
3043   %i = add nsw i8 %x, 32
3044   %c = icmp ult i8 %i, -32
3045   ret i1 %c
3048 define i1 @ult_add_nuw_nsw_C2_pow2_C_neg(i8 %x) {
3049 ; CHECK-LABEL: @ult_add_nuw_nsw_C2_pow2_C_neg(
3050 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[X:%.*]], -64
3051 ; CHECK-NEXT:    ret i1 [[C]]
3053   %i = add nuw nsw i8 %x, 32
3054   %c = icmp ult i8 %i, -32
3055   ret i1 %c
3058 define i1 @ult_add_C2_neg_C_pow2(i8 %x) {
3059 ; CHECK-LABEL: @ult_add_C2_neg_C_pow2(
3060 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -32
3061 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[TMP1]], 32
3062 ; CHECK-NEXT:    ret i1 [[C]]
3064   %i = add i8 %x, -32
3065   %c = icmp ult i8 %i, 32
3066   ret i1 %c
3069 define <2 x i1> @ult_add_C2_pow2_C_neg_vec(<2 x i8> %x) {
3070 ; CHECK-LABEL: @ult_add_C2_pow2_C_neg_vec(
3071 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 -32)
3072 ; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i8> [[TMP1]], splat (i8 -64)
3073 ; CHECK-NEXT:    ret <2 x i1> [[C]]
3075   %i = add <2 x i8> %x, <i8 32, i8 32>
3076   %c = icmp ult <2 x i8> %i, <i8 -32, i8 -32>
3077   ret <2 x i1> %c
3080 define i1 @ult_add_C2_pow2_C_neg_multiuse(i8 %x) {
3081 ; CHECK-LABEL: @ult_add_C2_pow2_C_neg_multiuse(
3082 ; CHECK-NEXT:    [[I:%.*]] = add i8 [[X:%.*]], 32
3083 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[I]], -32
3084 ; CHECK-NEXT:    call void @use(i8 [[I]])
3085 ; CHECK-NEXT:    ret i1 [[C]]
3087   %i = add i8 %x, 32
3088   %c = icmp ult i8 %i, -32
3089   call void @use(i8 %i)
3090   ret i1 %c
3093 define i1 @uge_add_C2_pow2_C_neg(i8 %x) {
3094 ; CHECK-LABEL: @uge_add_C2_pow2_C_neg(
3095 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -32
3096 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[TMP1]], -64
3097 ; CHECK-NEXT:    ret i1 [[C]]
3099   %i = add i8 %x, 32
3100   %c = icmp uge i8 %i, -32
3101   ret i1 %c
3104 declare void @llvm.assume(i1)
3106 ; Change an unsigned predicate to signed in icmp (add x, C1), C2
3107 define i1 @icmp_add_constant_with_constant_ult_to_slt(i32 range(i32 -4, 10) %x) {
3108 ; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt(
3109 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 8
3110 ; CHECK-NEXT:    ret i1 [[CMP]]
3112   %add = add nsw i32 %x, 5
3113   %cmp = icmp ult i32 %add, 13
3114   ret i1 %cmp
3117 define i1 @icmp_add_constant_with_constant_ugt_to_sgt(i32 range(i32 -4, 10) %x) {
3118 ; CHECK-LABEL: @icmp_add_constant_with_constant_ugt_to_sgt(
3119 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 2
3120 ; CHECK-NEXT:    ret i1 [[CMP]]
3122   %add = add nsw i32 %x, 10
3123   %cmp = icmp ugt i32 %add, 12
3124   ret i1 %cmp
3127 ; Negative test: x + C1 may be negative
3128 define i1 @icmp_add_constant_with_constant_ult_to_slt_neg1(i32 range(i32 -5, 10) %x) {
3129 ; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt_neg1(
3130 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 4
3131 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD]], 20
3132 ; CHECK-NEXT:    ret i1 [[CMP]]
3134   %add = add nsw i32 %x, 4
3135   %cmp = icmp ult i32 %add, 20
3136   ret i1 %cmp
3139 ; Negative test: missing nsw flag
3140 define i1 @icmp_add_constant_with_constant_ult_to_slt_neg2(i8 range(i8 -4, 120) %x) {
3141 ; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt_neg2(
3142 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X:%.*]], 15
3143 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[ADD]], 20
3144 ; CHECK-NEXT:    ret i1 [[CMP]]
3146   %add = add i8 %x, 15
3147   %cmp = icmp ult i8 %add, 20
3148   ret i1 %cmp
3151 ; Negative test: C2 is negative
3152 define i1 @icmp_add_constant_with_constant_ult_to_slt_neg3(i32 range(i32 -4, 10) %x) {
3153 ; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt_neg3(
3154 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 4
3155 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD]], -6
3156 ; CHECK-NEXT:    ret i1 [[CMP]]
3158   %add = add nsw i32 %x, 4
3159   %cmp = icmp ult i32 %add, -6
3160   ret i1 %cmp
3163 ; Negative test: C2 - C1 is negative
3164 define i1 @icmp_add_constant_with_constant_ult_to_slt_neg4(i32 range(i32 -4, 10) %x) {
3165 ; CHECK-LABEL: @icmp_add_constant_with_constant_ult_to_slt_neg4(
3166 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X:%.*]], 5
3167 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD]], 2
3168 ; CHECK-NEXT:    ret i1 [[CMP]]
3170   %add = add nsw i32 %x, 5
3171   %cmp = icmp ult i32 %add, 2
3172   ret i1 %cmp
3175 ; Same as before, but infer the range of ucmp
3176 define i1 @icmp_of_ucmp_plus_const_with_const(i32 %x, i32 %y) {
3177 ; CHECK-LABEL: @icmp_of_ucmp_plus_const_with_const(
3178 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 [[X:%.*]], [[Y:%.*]]
3179 ; CHECK-NEXT:    ret i1 [[CMP2]]
3181   %cmp1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
3182   %add = add i8 %cmp1, 1
3183   %cmp2 = icmp ult i8 %add, 2
3184   ret i1 %cmp2
3187 define i1 @zext_range_check_ult(i8 %x) {
3188 ; CHECK-LABEL: @zext_range_check_ult(
3189 ; CHECK-NEXT:  entry:
3190 ; CHECK-NEXT:    [[TMP0:%.*]] = add i8 [[X:%.*]], -4
3191 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[TMP0]], 3
3192 ; CHECK-NEXT:    ret i1 [[CMP]]
3194 entry:
3195   %conv = zext i8 %x to i32
3196   %add = add i32 %conv, -4
3197   %cmp = icmp ult i32 %add, 3
3198   ret i1 %cmp
3201 ; TODO: should be canonicalized to (x - 4) u> 2
3202 define i1 @zext_range_check_ugt(i8 %x) {
3203 ; CHECK-LABEL: @zext_range_check_ugt(
3204 ; CHECK-NEXT:  entry:
3205 ; CHECK-NEXT:    [[CONV:%.*]] = zext i8 [[X:%.*]] to i32
3206 ; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i32 [[CONV]], -7
3207 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[TMP0]], -3
3208 ; CHECK-NEXT:    ret i1 [[CMP]]
3210 entry:
3211   %conv = zext i8 %x to i32
3212   %add = add i32 %conv, -4
3213   %cmp = icmp ugt i32 %add, 2
3214   ret i1 %cmp
3217 ; TODO: should be canonicalized to (x - 4) u> 2
3218 define i1 @zext_range_check_ult_alter(i8 %x) {
3219 ; CHECK-LABEL: @zext_range_check_ult_alter(
3220 ; CHECK-NEXT:  entry:
3221 ; CHECK-NEXT:    [[CONV:%.*]] = zext i8 [[X:%.*]] to i32
3222 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[CONV]], -7
3223 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD]], -3
3224 ; CHECK-NEXT:    ret i1 [[CMP]]
3226 entry:
3227   %conv = zext i8 %x to i32
3228   %add = add i32 %conv, -7
3229   %cmp = icmp ult i32 %add, -3
3230   ret i1 %cmp
3233 define i1 @zext_range_check_mergable(i8 %x) {
3234 ; CHECK-LABEL: @zext_range_check_mergable(
3235 ; CHECK-NEXT:    [[COND:%.*]] = icmp slt i8 [[X:%.*]], 7
3236 ; CHECK-NEXT:    ret i1 [[COND]]
3238   %conv = zext i8 %x to i32
3239   %add = add nsw i32 %conv, -4
3240   %cmp1 = icmp ult i32 %add, 3
3241   %cmp2 = icmp slt i8 %x, 4
3242   %cond = select i1 %cmp2, i1 true, i1 %cmp1
3243   ret i1 %cond
3246 ; Negative tests
3248 define i1 @sext_range_check_ult(i8 %x) {
3249 ; CHECK-LABEL: @sext_range_check_ult(
3250 ; CHECK-NEXT:  entry:
3251 ; CHECK-NEXT:    [[CONV:%.*]] = sext i8 [[X:%.*]] to i32
3252 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[CONV]], -4
3253 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD]], 3
3254 ; CHECK-NEXT:    ret i1 [[CMP]]
3256 entry:
3257   %conv = sext i8 %x to i32
3258   %add = add i32 %conv, -4
3259   %cmp = icmp ult i32 %add, 3
3260   ret i1 %cmp
3263 define i1 @zext_range_check_ult_illegal_type(i7 %x) {
3264 ; CHECK-LABEL: @zext_range_check_ult_illegal_type(
3265 ; CHECK-NEXT:  entry:
3266 ; CHECK-NEXT:    [[CONV:%.*]] = zext i7 [[X:%.*]] to i32
3267 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[CONV]], -4
3268 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD]], 3
3269 ; CHECK-NEXT:    ret i1 [[CMP]]
3271 entry:
3272   %conv = zext i7 %x to i32
3273   %add = add i32 %conv, -4
3274   %cmp = icmp ult i32 %add, 3
3275   ret i1 %cmp
3278 define i1 @zext_range_check_ult_range_check_failure(i8 %x) {
3279 ; CHECK-LABEL: @zext_range_check_ult_range_check_failure(
3280 ; CHECK-NEXT:  entry:
3281 ; CHECK-NEXT:    [[CONV:%.*]] = zext i8 [[X:%.*]] to i32
3282 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[CONV]], -4
3283 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD]], 253
3284 ; CHECK-NEXT:    ret i1 [[CMP]]
3286 entry:
3287   %conv = zext i8 %x to i32
3288   %add = add i32 %conv, -4
3289   %cmp = icmp ult i32 %add, 253
3290   ret i1 %cmp