1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
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(
12 ; CHECK-NEXT: [[TMP0:%.*]] = or i16 [[ARG1:%.*]], [[ARG:%.*]]
13 ; CHECK-NEXT: [[I4:%.*]] = icmp eq i16 [[TMP0]], 0
14 ; CHECK-NEXT: ret i1 [[I4]]
17 %i = zext i16 %arg to i32
18 %i2 = zext i16 %arg1 to i32
20 %i4 = icmp eq i32 %i3, 0
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(
28 ; CHECK-NEXT: [[TMP0:%.*]] = or i8 [[ARG1:%.*]], [[ARG:%.*]]
29 ; CHECK-NEXT: [[I4:%.*]] = icmp eq i8 [[TMP0]], 0
30 ; CHECK-NEXT: ret i1 [[I4]]
33 %i = zext i8 %arg to i32
34 %i2 = zext i8 %arg1 to i32
36 %i4 = icmp eq i32 %i3, 0
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(
44 ; CHECK-NEXT: ret i1 false
47 %i = zext i1 %arg to i32
48 %i2 = zext i1 %arg1 to i32
50 %i4 = icmp eq i32 %i3, -2
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(
57 ; CHECK-NEXT: ret i1 false
60 %i = zext i1 %arg to i32
61 %i2 = zext i1 %arg1 to i32
63 %i4 = icmp eq i32 %i3, -1
67 define i1 @cvt_icmp_0_zext_plus_zext_eq(i1 %arg, i1 %arg1) {
68 ; CHECK-LABEL: @cvt_icmp_0_zext_plus_zext_eq(
70 ; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]]
71 ; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true
72 ; CHECK-NEXT: ret i1 [[I4]]
75 %i = zext i1 %arg to i32
76 %i2 = zext i1 %arg1 to i32
78 %i4 = icmp eq i32 %i3, 0
82 define i1 @cvt_icmp_1_zext_plus_zext_eq(i1 %arg, i1 %arg1) {
83 ; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_eq(
85 ; CHECK-NEXT: [[I4:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]]
86 ; CHECK-NEXT: ret i1 [[I4]]
89 %i = zext i1 %arg to i32
90 %i2 = zext i1 %arg1 to i32
92 %i4 = icmp eq i32 %i3, 1
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(
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>
110 define i1 @cvt_icmp_2_zext_plus_zext_eq(i1 %arg, i1 %arg1) {
111 ; CHECK-LABEL: @cvt_icmp_2_zext_plus_zext_eq(
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
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(
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
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(
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
152 define i1 @cvt_icmp_0_sext_plus_sext_eq(i1 %arg, i1 %arg1) {
153 ; CHECK-LABEL: @cvt_icmp_0_sext_plus_sext_eq(
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
167 define i1 @cvt_icmp_1_sext_plus_sext_eq(i1 %arg, i1 %arg1) {
168 ; CHECK-LABEL: @cvt_icmp_1_sext_plus_sext_eq(
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
180 define i1 @cvt_icmp_2_sext_plus_sext_eq(i1 %arg, i1 %arg1) {
181 ; CHECK-LABEL: @cvt_icmp_2_sext_plus_sext_eq(
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
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(
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
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(
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
221 define i1 @cvt_icmp_0_sext_plus_zext_eq(i1 %arg, i1 %arg1) {
222 ; CHECK-LABEL: @cvt_icmp_0_sext_plus_zext_eq(
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
236 define i1 @cvt_icmp_1_sext_plus_zext_eq(i1 %arg, i1 %arg1) {
237 ; CHECK-LABEL: @cvt_icmp_1_sext_plus_zext_eq(
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
251 define i1 @cvt_icmp_2_sext_plus_zext_eq(i1 %arg, i1 %arg1) {
252 ; CHECK-LABEL: @cvt_icmp_2_sext_plus_zext_eq(
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
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(
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
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(
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
290 define i1 @cvt_icmp_0_zext_plus_zext_ne(i1 %arg, i1 %arg1) {
291 ; CHECK-LABEL: @cvt_icmp_0_zext_plus_zext_ne(
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
304 define i1 @cvt_icmp_1_zext_plus_zext_ne(i1 %arg, i1 %arg1) {
305 ; CHECK-LABEL: @cvt_icmp_1_zext_plus_zext_ne(
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
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(
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
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(
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
359 define i1 @cvt_icmp_2_zext_plus_zext_ne(i1 %arg, i1 %arg1) {
360 ; CHECK-LABEL: @cvt_icmp_2_zext_plus_zext_ne(
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
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(
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
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(
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
404 define i1 @cvt_icmp_0_sext_plus_sext_ne(i1 %arg, i1 %arg1) {
405 ; CHECK-LABEL: @cvt_icmp_0_sext_plus_sext_ne(
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
418 define i1 @cvt_icmp_1_sext_plus_sext_ne(i1 %arg, i1 %arg1) {
419 ; CHECK-LABEL: @cvt_icmp_1_sext_plus_sext_ne(
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
431 define i1 @cvt_icmp_2_sext_plus_sext_ne(i1 %arg, i1 %arg1) {
432 ; CHECK-LABEL: @cvt_icmp_2_sext_plus_sext_ne(
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
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(
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
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(
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
472 define i1 @cvt_icmp_0_sext_plus_zext_ne(i1 %arg, i1 %arg1) {
473 ; CHECK-LABEL: @cvt_icmp_0_sext_plus_zext_ne(
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
486 define i1 @cvt_icmp_1_sext_plus_zext_ne(i1 %arg, i1 %arg1) {
487 ; CHECK-LABEL: @cvt_icmp_1_sext_plus_zext_ne(
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
501 define i1 @cvt_icmp_2_sext_plus_zext_ne(i1 %arg, i1 %arg1) {
502 ; CHECK-LABEL: @cvt_icmp_2_sext_plus_zext_ne(
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
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(
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>
527 ; test if zext i1 X + sext i1 Y converted to sext i1 X + zext i1 Y
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(
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
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(
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>
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(
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
571 define i1 @cvt_icmp_0_zext_plus_sext_eq(i1 %arg, i1 %arg1) {
572 ; CHECK-LABEL: @cvt_icmp_0_zext_plus_sext_eq(
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
586 define i1 @cvt_icmp_1_zext_plus_sext_eq(i1 %arg, i1 %arg1) {
587 ; CHECK-LABEL: @cvt_icmp_1_zext_plus_sext_eq(
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
601 define i1 @cvt_icmp_2_zext_plus_sext_eq(i1 %arg, i1 %arg1) {
602 ; CHECK-LABEL: @cvt_icmp_2_zext_plus_sext_eq(
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
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(
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
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(
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
642 define i1 @cvt_icmp_0_zext_plus_sext_ne(i1 %arg, i1 %arg1) {
643 ; CHECK-LABEL: @cvt_icmp_0_zext_plus_sext_ne(
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
656 define i1 @cvt_icmp_1_zext_plus_sext_ne(i1 %arg, i1 %arg1) {
657 ; CHECK-LABEL: @cvt_icmp_1_zext_plus_sext_ne(
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
671 define i1 @cvt_icmp_2_zext_plus_sext_ne(i1 %arg, i1 %arg1) {
672 ; CHECK-LABEL: @cvt_icmp_2_zext_plus_sext_ne(
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
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(
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
703 define i1 @test_cvt_icmp2(i1 %arg, i1 %arg1, ptr %p) {
704 ; CHECK-LABEL: @test_cvt_icmp2(
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
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(
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
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(
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
747 define i1 @test_zext_zext_cvt_0_ult_icmp(i1 %arg, i1 %arg1) {
748 ; CHECK-LABEL: @test_zext_zext_cvt_0_ult_icmp(
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
760 define i1 @test_zext_zext_cvt_2_ult_icmp(i1 %arg, i1 %arg1) {
761 ; CHECK-LABEL: @test_zext_zext_cvt_2_ult_icmp(
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
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(
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
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(
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
805 define i1 @test_sext_sext_cvt_0_ult_icmp(i1 %arg, i1 %arg1) {
806 ; CHECK-LABEL: @test_sext_sext_cvt_0_ult_icmp(
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
818 define i1 @test_sext_sext_cvt_1_ult_icmp(i1 %arg, i1 %arg1) {
819 ; CHECK-LABEL: @test_sext_sext_cvt_1_ult_icmp(
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
833 define i1 @test_sext_sext_cvt_2_ult_icmp(i1 %arg, i1 %arg1) {
834 ; CHECK-LABEL: @test_sext_sext_cvt_2_ult_icmp(
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
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(
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
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(
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
878 define i1 @test_sext_zext_cvt_0_ult_icmp(i1 %arg, i1 %arg1) {
879 ; CHECK-LABEL: @test_sext_zext_cvt_0_ult_icmp(
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
891 define i1 @test_sext_zext_cvt_2_ult_icmp(i1 %arg, i1 %arg1) {
892 ; CHECK-LABEL: @test_sext_zext_cvt_2_ult_icmp(
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
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(
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
921 define i1 @test_zext_sext_cvt_0_ult_icmp(i1 %arg, i1 %arg1) {
922 ; CHECK-LABEL: @test_zext_sext_cvt_0_ult_icmp(
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
934 define i1 @test_zext_sext_cvt_1_ult_icmp(i1 %arg, i1 %arg1) {
935 ; CHECK-LABEL: @test_zext_sext_cvt_1_ult_icmp(
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
950 define i1 @test_cvt_icmp4(i1 %arg, i1 %arg1) {
951 ; CHECK-LABEL: @test_cvt_icmp4(
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
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(
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
977 define i1 @test_zext_zext_cvt_1_ugt_icmp(i1 %arg, i1 %arg1) {
978 ; CHECK-LABEL: @test_zext_zext_cvt_1_ugt_icmp(
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
991 define i1 @test_zext_zext_cvt_2_ugt_icmp(i1 %arg, i1 %arg1) {
992 ; CHECK-LABEL: @test_zext_zext_cvt_2_ugt_icmp(
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
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(
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
1018 define i1 @test_sext_sext_cvt_0_ugt_icmp(i1 %arg, i1 %arg1) {
1019 ; CHECK-LABEL: @test_sext_sext_cvt_0_ugt_icmp(
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
1032 define i1 @test_sext_sext_cvt_2_ugt_icmp(i1 %arg, i1 %arg1) {
1033 ; CHECK-LABEL: @test_sext_sext_cvt_2_ugt_icmp(
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
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(
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
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(
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
1074 define i1 @test_zext_sext_cvt_0_ugt_icmp(i1 %arg, i1 %arg1) {
1075 ; CHECK-LABEL: @test_zext_sext_cvt_0_ugt_icmp(
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
1088 define i1 @test_zext_sext_cvt_1_ugt_icmp(i1 %arg, i1 %arg1) {
1089 ; CHECK-LABEL: @test_zext_sext_cvt_1_ugt_icmp(
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
1103 define i1 @test_zext_sext_cvt_2_ugt_icmp(i1 %arg, i1 %arg1) {
1104 ; CHECK-LABEL: @test_zext_sext_cvt_2_ugt_icmp(
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
1118 define i1 @test_cvt_icmp5(i1 %arg, i1 %arg1) {
1119 ; CHECK-LABEL: @test_cvt_icmp5(
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
1132 define i1 @test_cvt_icmp6(i1 %arg, i1 %arg1) {
1133 ; CHECK-LABEL: @test_cvt_icmp6(
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
1148 define i1 @test_cvt_icmp7(i1 %arg, i1 %arg1) {
1149 ; CHECK-LABEL: @test_cvt_icmp7(
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
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(
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
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(
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
1188 define i1 @test_zext_zext_cvt_2_sgt_icmp(i1 %arg, i1 %arg1) {
1189 ; CHECK-LABEL: @test_zext_zext_cvt_2_sgt_icmp(
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
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(
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
1216 define i1 @test_sext_sext_cvt_0_sgt_icmp(i1 %arg, i1 %arg1) {
1217 ; CHECK-LABEL: @test_sext_sext_cvt_0_sgt_icmp(
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
1229 define i1 @test_sext_sext_cvt_2_sgt_icmp(i1 %arg, i1 %arg1) {
1230 ; CHECK-LABEL: @test_sext_sext_cvt_2_sgt_icmp(
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
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(
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
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(
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
1270 define i1 @test_zext_sext_cvt_0_sgt_icmp(i1 %arg, i1 %arg1) {
1271 ; CHECK-LABEL: @test_zext_sext_cvt_0_sgt_icmp(
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
1285 define i1 @test_zext_sext_cvt_1_sgt_icmp(i1 %arg, i1 %arg1) {
1286 ; CHECK-LABEL: @test_zext_sext_cvt_1_sgt_icmp(
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
1298 define i1 @test_zext_sext_cvt_2_sgt_icmp(i1 %arg, i1 %arg1) {
1299 ; CHECK-LABEL: @test_zext_sext_cvt_2_sgt_icmp(
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
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(
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
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(
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
1338 define i1 @test_zext_zext_cvt_2_slt_icmp(i1 %arg, i1 %arg1) {
1339 ; CHECK-LABEL: @test_zext_zext_cvt_2_slt_icmp(
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
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(
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
1366 define i1 @test_sext_sext_cvt_0_slt_icmp(i1 %arg, i1 %arg1) {
1367 ; CHECK-LABEL: @test_sext_sext_cvt_0_slt_icmp(
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
1380 define i1 @test_sext_sext_cvt_2_slt_icmp(i1 %arg, i1 %arg1) {
1381 ; CHECK-LABEL: @test_sext_sext_cvt_2_slt_icmp(
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
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(
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
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(
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
1419 define i1 @test_zext_sext_cvt_0_slt_icmp(i1 %arg, i1 %arg1) {
1420 ; CHECK-LABEL: @test_zext_sext_cvt_0_slt_icmp(
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
1434 define i1 @test_zext_sext_cvt_1_slt_icmp(i1 %arg, i1 %arg1) {
1435 ; CHECK-LABEL: @test_zext_sext_cvt_1_slt_icmp(
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
1449 define i1 @test_zext_sext_cvt_2_slt_icmp(i1 %arg, i1 %arg1) {
1450 ; CHECK-LABEL: @test_zext_sext_cvt_2_slt_icmp(
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
1462 define i1 @test_cvt_icmp8(i1 %arg, i1 %arg1) {
1463 ; CHECK-LABEL: @test_cvt_icmp8(
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
1476 define i1 @test_cvt_icmp9(i1 %arg, i1 %arg1) {
1477 ; CHECK-LABEL: @test_cvt_icmp9(
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
1491 define i1 @test_cvt_icmp10(i1 %arg, i1 %arg1) {
1492 ; CHECK-LABEL: @test_cvt_icmp10(
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
1506 define i1 @test_cvt_icmp11(i1 %arg, i1 %arg1) {
1507 ; CHECK-LABEL: @test_cvt_icmp11(
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
1520 define i1 @test_cvt_icmp12(i1 %arg, i1 %arg1) {
1521 ; CHECK-LABEL: @test_cvt_icmp12(
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
1534 define i1 @test_cvt_icmp13(i1 %arg, i1 %arg1) {
1535 ; CHECK-LABEL: @test_cvt_icmp13(
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
1549 define i1 @test_cvt_icmp14(i1 %arg, i1 %arg1) {
1550 ; CHECK-LABEL: @test_cvt_icmp14(
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
1564 define i1 @test_cvt_icmp15(i1 %arg, i1 %arg1) {
1565 ; CHECK-LABEL: @test_cvt_icmp15(
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
1577 define i1 @test_cvt_icmp16(i1 %arg, i1 %arg1) {
1578 ; CHECK-LABEL: @test_cvt_icmp16(
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
1590 define i1 @test_cvt_icmp17(i1 %arg, i1 %arg1) {
1591 ; CHECK-LABEL: @test_cvt_icmp17(
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
1603 define i1 @test_cvt_icmp18(i1 %arg, i1 %arg1) {
1604 ; CHECK-LABEL: @test_cvt_icmp18(
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
1616 define i1 @test_cvt_icmp19(i1 %arg, i1 %arg1) {
1617 ; CHECK-LABEL: @test_cvt_icmp19(
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
1631 define i1 @test_cvt_icmp20(i1 %arg, i1 %arg1) {
1632 ; CHECK-LABEL: @test_cvt_icmp20(
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
1645 define i1 @test_cvt_icmp21(i1 %arg, i1 %arg1) {
1646 ; CHECK-LABEL: @test_cvt_icmp21(
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
1660 define i1 @test_cvt_icmp22(i1 %arg, i1 %arg1) {
1661 ; CHECK-LABEL: @test_cvt_icmp22(
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
1675 define i1 @test_cvt_icmp23(i1 %arg, i1 %arg1) {
1676 ; CHECK-LABEL: @test_cvt_icmp23(
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
1688 define i1 @test_cvt_icmp24(i1 %arg, i1 %arg1) {
1689 ; CHECK-LABEL: @test_cvt_icmp24(
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
1703 define i1 @test_cvt_icmp25(i1 %arg, i1 %arg1) {
1704 ; CHECK-LABEL: @test_cvt_icmp25(
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
1718 define i1 @test_cvt_icmp26(i1 %arg, i1 %arg1) {
1719 ; CHECK-LABEL: @test_cvt_icmp26(
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
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]]
1737 %c = icmp ult i32 %b, 4
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>
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]]
1757 %c = icmp ugt i32 %b, -5
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>
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]]
1777 %c = icmp slt i32 %b, 2147483652
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>
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
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>
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
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>
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
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>
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
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
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
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>
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
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>
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
2112 %c = icmp ugt i8 %x, %a
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
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
2143 store i8 %a, ptr %p3
2144 %c = icmp ugt i8 %x, %a
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
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
2174 %c = icmp ult i8 %a, %x
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]]
2187 %c = icmp ult i8 %a, %x
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
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
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
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
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
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
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
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
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
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
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)
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)
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>
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>
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>
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>
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]]
2398 %tobool = icmp eq i8 %t2, %t1
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
2410 %tobool = icmp eq i8 %t2, %t1
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
2422 %tobool = icmp eq i8 %t2, %t1
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
2434 %tobool = icmp eq i8 %t2, %t1
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
2446 %tobool = icmp eq i8 %t2, %t1
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
2458 %tobool = icmp eq i8 %t2, %t1
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
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]]
2480 %ov = icmp ugt i8 %t, 251
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]]
2492 call void @use(i32 %t)
2493 %ov = icmp ugt i32 %t, 2147483689
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>
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]]
2516 %ov = icmp ugt i8 %t, 251
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
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]]
2536 %ov = icmp ult i8 %t, 122
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]]
2548 call void @use(i32 %t)
2549 %ov = icmp ult i32 %t, 2147483690
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>
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]]
2572 %ov = icmp ult i8 %t, 123
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
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]]
2592 %ov = icmp sgt i8 %t, -7
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]]
2604 call void @use(i32 %t)
2605 %ov = icmp sgt i32 %t, 41
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>
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]]
2628 %ov = icmp sgt i8 %t, -7
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
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]]
2648 %ov = icmp slt i8 %t, -6
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]]
2660 call void @use(i32 %t)
2661 %ov = icmp slt i32 %t, 42
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>
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]]
2684 %ov = icmp slt i8 %t, -7
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
2948 %c = icmp ult i8 %i, 7
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)
2962 %c = icmp ult i8 %i, 11
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]]
2973 %c = icmp ult i16 %i, 7
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>
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]]
2998 %c = icmp ult i8 %i, 11
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
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)
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]]
3033 %c = icmp ult i8 %i, -32
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
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
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]]
3065 %c = icmp ult i8 %i, 32
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>
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]]
3088 %c = icmp ult i8 %i, -32
3089 call void @use(i8 %i)
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]]
3100 %c = icmp uge i8 %i, -32
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
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
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
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
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
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
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
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]]
3195 %conv = zext i8 %x to i32
3196 %add = add i32 %conv, -4
3197 %cmp = icmp ult i32 %add, 3
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]]
3211 %conv = zext i8 %x to i32
3212 %add = add i32 %conv, -4
3213 %cmp = icmp ugt i32 %add, 2
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]]
3227 %conv = zext i8 %x to i32
3228 %add = add i32 %conv, -7
3229 %cmp = icmp ult i32 %add, -3
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
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]]
3257 %conv = sext i8 %x to i32
3258 %add = add i32 %conv, -4
3259 %cmp = icmp ult i32 %add, 3
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]]
3272 %conv = zext i7 %x to i32
3273 %add = add i32 %conv, -4
3274 %cmp = icmp ult i32 %add, 3
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]]
3287 %conv = zext i8 %x to i32
3288 %add = add i32 %conv, -4
3289 %cmp = icmp ult i32 %add, 253