1 ; RUN: opt < %s -instcombine -S | FileCheck %s
3 target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
5 define i32 @test1(i32 %X) {
6 entry:
7 icmp slt i32 %X, 0 ; <i1>:0 [#uses=1]
8 zext i1 %0 to i32 ; <i32>:1 [#uses=1]
9 ret i32 %1
10 ; CHECK-LABEL: @test1(
11 ; CHECK: lshr i32 %X, 31
12 ; CHECK-NEXT: ret i32
13 }
15 define i32 @test2(i32 %X) {
16 entry:
17 icmp ult i32 %X, -2147483648 ; <i1>:0 [#uses=1]
18 zext i1 %0 to i32 ; <i32>:1 [#uses=1]
19 ret i32 %1
20 ; CHECK-LABEL: @test2(
21 ; CHECK: lshr i32 %X, 31
22 ; CHECK-NEXT: xor i32
23 ; CHECK-NEXT: ret i32
24 }
26 define i32 @test3(i32 %X) {
27 entry:
28 icmp slt i32 %X, 0 ; <i1>:0 [#uses=1]
29 sext i1 %0 to i32 ; <i32>:1 [#uses=1]
30 ret i32 %1
31 ; CHECK-LABEL: @test3(
32 ; CHECK: ashr i32 %X, 31
33 ; CHECK-NEXT: ret i32
34 }
36 define i32 @test4(i32 %X) {
37 entry:
38 icmp ult i32 %X, -2147483648 ; <i1>:0 [#uses=1]
39 sext i1 %0 to i32 ; <i32>:1 [#uses=1]
40 ret i32 %1
41 ; CHECK-LABEL: @test4(
42 ; CHECK: ashr i32 %X, 31
43 ; CHECK-NEXT: xor i32
44 ; CHECK-NEXT: ret i32
45 }
47 ; PR4837
48 define <2 x i1> @test5(<2 x i64> %x) {
49 entry:
50 %V = icmp eq <2 x i64> %x, undef
51 ret <2 x i1> %V
52 ; CHECK-LABEL: @test5(
53 ; CHECK: ret <2 x i1> <i1 true, i1 true>
54 }
56 define i32 @test6(i32 %a, i32 %b) {
57 %c = icmp sle i32 %a, -1
58 %d = zext i1 %c to i32
59 %e = sub i32 0, %d
60 %f = and i32 %e, %b
61 ret i32 %f
62 ; CHECK-LABEL: @test6(
63 ; CHECK-NEXT: ashr i32 %a, 31
64 ; CHECK-NEXT: %f = and i32 %e, %b
65 ; CHECK-NEXT: ret i32 %f
66 }
69 define i1 @test7(i32 %x) {
70 entry:
71 %a = add i32 %x, -1
72 %b = icmp ult i32 %a, %x
73 ret i1 %b
74 ; CHECK-LABEL: @test7(
75 ; CHECK: %b = icmp ne i32 %x, 0
76 ; CHECK: ret i1 %b
77 }
79 define i1 @test8(i32 %x){
80 entry:
81 %a = add i32 %x, -1
82 %b = icmp eq i32 %a, %x
83 ret i1 %b
84 ; CHECK-LABEL: @test8(
85 ; CHECK: ret i1 false
86 }
88 define i1 @test9(i32 %x) {
89 entry:
90 %a = add i32 %x, -2
91 %b = icmp ugt i32 %x, %a
92 ret i1 %b
93 ; CHECK-LABEL: @test9(
94 ; CHECK: icmp ugt i32 %x, 1
95 ; CHECK: ret i1 %b
96 }
98 define i1 @test10(i32 %x){
99 entry:
100 %a = add i32 %x, -1
101 %b = icmp slt i32 %a, %x
102 ret i1 %b
103 ; CHECK-LABEL: @test10(
104 ; CHECK: %b = icmp ne i32 %x, -2147483648
105 ; CHECK: ret i1 %b
106 }
108 define i1 @test11(i32 %x) {
109 %a = add nsw i32 %x, 8
110 %b = icmp slt i32 %x, %a
111 ret i1 %b
112 ; CHECK-LABEL: @test11(
113 ; CHECK: ret i1 true
114 }
116 ; PR6195
117 define i1 @test12(i1 %A) {
118 %S = select i1 %A, i64 -4294967295, i64 8589934591
119 %B = icmp ne i64 bitcast (<2 x i32> <i32 1, i32 -1> to i64), %S
120 ret i1 %B
121 ; CHECK-LABEL: @test12(
122 ; CHECK-NEXT: = xor i1 %A, true
123 ; CHECK-NEXT: ret i1
124 }
126 ; PR6481
127 define i1 @test13(i8 %X) nounwind readnone {
128 entry:
129 %cmp = icmp slt i8 undef, %X
130 ret i1 %cmp
131 ; CHECK-LABEL: @test13(
132 ; CHECK: ret i1 false
133 }
135 define i1 @test14(i8 %X) nounwind readnone {
136 entry:
137 %cmp = icmp slt i8 undef, -128
138 ret i1 %cmp
139 ; CHECK-LABEL: @test14(
140 ; CHECK: ret i1 false
141 }
143 define i1 @test15() nounwind readnone {
144 entry:
145 %cmp = icmp eq i8 undef, -128
146 ret i1 %cmp
147 ; CHECK-LABEL: @test15(
148 ; CHECK: ret i1 undef
149 }
151 define i1 @test16() nounwind readnone {
152 entry:
153 %cmp = icmp ne i8 undef, -128
154 ret i1 %cmp
155 ; CHECK-LABEL: @test16(
156 ; CHECK: ret i1 undef
157 }
159 define i1 @test17(i32 %x) nounwind {
160 %shl = shl i32 1, %x
161 %and = and i32 %shl, 8
162 %cmp = icmp eq i32 %and, 0
163 ret i1 %cmp
164 ; CHECK-LABEL: @test17(
165 ; CHECK-NEXT: %cmp = icmp ne i32 %x, 3
166 }
168 define i1 @test17a(i32 %x) nounwind {
169 %shl = shl i32 1, %x
170 %and = and i32 %shl, 7
171 %cmp = icmp eq i32 %and, 0
172 ret i1 %cmp
173 ; CHECK-LABEL: @test17a(
174 ; CHECK-NEXT: %cmp = icmp ugt i32 %x, 2
175 }
177 define i1 @test18(i32 %x) nounwind {
178 %sh = lshr i32 8, %x
179 %and = and i32 %sh, 1
180 %cmp = icmp eq i32 %and, 0
181 ret i1 %cmp
182 ; CHECK-LABEL: @test18(
183 ; CHECK-NEXT: %cmp = icmp ne i32 %x, 3
184 }
186 define i1 @test19(i32 %x) nounwind {
187 %shl = shl i32 1, %x
188 %and = and i32 %shl, 8
189 %cmp = icmp eq i32 %and, 8
190 ret i1 %cmp
191 ; CHECK-LABEL: @test19(
192 ; CHECK-NEXT: %cmp = icmp eq i32 %x, 3
193 }
195 define i1 @test20(i32 %x) nounwind {
196 %shl = shl i32 1, %x
197 %and = and i32 %shl, 8
198 %cmp = icmp ne i32 %and, 0
199 ret i1 %cmp
200 ; CHECK-LABEL: @test20(
201 ; CHECK-NEXT: %cmp = icmp eq i32 %x, 3
202 }
204 define i1 @test20a(i32 %x) nounwind {
205 %shl = shl i32 1, %x
206 %and = and i32 %shl, 7
207 %cmp = icmp ne i32 %and, 0
208 ret i1 %cmp
209 ; CHECK-LABEL: @test20a(
210 ; CHECK-NEXT: %cmp = icmp ult i32 %x, 3
211 }
213 define i1 @test21(i8 %x, i8 %y) {
214 ; CHECK-LABEL: @test21(
215 ; CHECK-NOT: or i8
216 ; CHECK: icmp ugt
217 %A = or i8 %x, 1
218 %B = icmp ugt i8 %A, 3
219 ret i1 %B
220 }
222 define i1 @test22(i8 %x, i8 %y) {
223 ; CHECK-LABEL: @test22(
224 ; CHECK-NOT: or i8
225 ; CHECK: icmp ult
226 %A = or i8 %x, 1
227 %B = icmp ult i8 %A, 4
228 ret i1 %B
229 }
231 ; PR2740
232 ; CHECK-LABEL: @test23(
233 ; CHECK: icmp sgt i32 %x, 1328634634
234 define i1 @test23(i32 %x) nounwind {
235 %i3 = sdiv i32 %x, -1328634635
236 %i4 = icmp eq i32 %i3, -1
237 ret i1 %i4
238 }
240 @X = global [1000 x i32] zeroinitializer
242 ; PR8882
243 ; CHECK-LABEL: @test24(
244 ; CHECK: %cmp = icmp eq i64 %i, 1000
245 ; CHECK: ret i1 %cmp
246 define i1 @test24(i64 %i) {
247 %p1 = getelementptr inbounds i32* getelementptr inbounds ([1000 x i32]* @X, i64 0, i64 0), i64 %i
248 %cmp = icmp eq i32* %p1, getelementptr inbounds ([1000 x i32]* @X, i64 1, i64 0)
249 ret i1 %cmp
250 }
252 @X_as1 = addrspace(1) global [1000 x i32] zeroinitializer
254 ; CHECK: @test24_as1
255 ; CHECK: trunc i64 %i to i16
256 ; CHECK: %cmp = icmp eq i16 %1, 1000
257 ; CHECK: ret i1 %cmp
258 define i1 @test24_as1(i64 %i) {
259 %p1 = getelementptr inbounds i32 addrspace(1)* getelementptr inbounds ([1000 x i32] addrspace(1)* @X_as1, i64 0, i64 0), i64 %i
260 %cmp = icmp eq i32 addrspace(1)* %p1, getelementptr inbounds ([1000 x i32] addrspace(1)* @X_as1, i64 1, i64 0)
261 ret i1 %cmp
262 }
264 ; CHECK-LABEL: @test25(
265 ; X + Z > Y + Z -> X > Y if there is no overflow.
266 ; CHECK: %c = icmp sgt i32 %x, %y
267 ; CHECK: ret i1 %c
268 define i1 @test25(i32 %x, i32 %y, i32 %z) {
269 %lhs = add nsw i32 %x, %z
270 %rhs = add nsw i32 %y, %z
271 %c = icmp sgt i32 %lhs, %rhs
272 ret i1 %c
273 }
275 ; CHECK-LABEL: @test26(
276 ; X + Z > Y + Z -> X > Y if there is no overflow.
277 ; CHECK: %c = icmp ugt i32 %x, %y
278 ; CHECK: ret i1 %c
279 define i1 @test26(i32 %x, i32 %y, i32 %z) {
280 %lhs = add nuw i32 %x, %z
281 %rhs = add nuw i32 %y, %z
282 %c = icmp ugt i32 %lhs, %rhs
283 ret i1 %c
284 }
286 ; CHECK-LABEL: @test27(
287 ; X - Z > Y - Z -> X > Y if there is no overflow.
288 ; CHECK: %c = icmp sgt i32 %x, %y
289 ; CHECK: ret i1 %c
290 define i1 @test27(i32 %x, i32 %y, i32 %z) {
291 %lhs = sub nsw i32 %x, %z
292 %rhs = sub nsw i32 %y, %z
293 %c = icmp sgt i32 %lhs, %rhs
294 ret i1 %c
295 }
297 ; CHECK-LABEL: @test28(
298 ; X - Z > Y - Z -> X > Y if there is no overflow.
299 ; CHECK: %c = icmp ugt i32 %x, %y
300 ; CHECK: ret i1 %c
301 define i1 @test28(i32 %x, i32 %y, i32 %z) {
302 %lhs = sub nuw i32 %x, %z
303 %rhs = sub nuw i32 %y, %z
304 %c = icmp ugt i32 %lhs, %rhs
305 ret i1 %c
306 }
308 ; CHECK-LABEL: @test29(
309 ; X + Y > X -> Y > 0 if there is no overflow.
310 ; CHECK: %c = icmp sgt i32 %y, 0
311 ; CHECK: ret i1 %c
312 define i1 @test29(i32 %x, i32 %y) {
313 %lhs = add nsw i32 %x, %y
314 %c = icmp sgt i32 %lhs, %x
315 ret i1 %c
316 }
318 ; CHECK-LABEL: @test30(
319 ; X + Y > X -> Y > 0 if there is no overflow.
320 ; CHECK: %c = icmp ne i32 %y, 0
321 ; CHECK: ret i1 %c
322 define i1 @test30(i32 %x, i32 %y) {
323 %lhs = add nuw i32 %x, %y
324 %c = icmp ugt i32 %lhs, %x
325 ret i1 %c
326 }
328 ; CHECK-LABEL: @test31(
329 ; X > X + Y -> 0 > Y if there is no overflow.
330 ; CHECK: %c = icmp slt i32 %y, 0
331 ; CHECK: ret i1 %c
332 define i1 @test31(i32 %x, i32 %y) {
333 %rhs = add nsw i32 %x, %y
334 %c = icmp sgt i32 %x, %rhs
335 ret i1 %c
336 }
338 ; CHECK-LABEL: @test32(
339 ; X > X + Y -> 0 > Y if there is no overflow.
340 ; CHECK: ret i1 false
341 define i1 @test32(i32 %x, i32 %y) {
342 %rhs = add nuw i32 %x, %y
343 %c = icmp ugt i32 %x, %rhs
344 ret i1 %c
345 }
347 ; CHECK-LABEL: @test33(
348 ; X - Y > X -> 0 > Y if there is no overflow.
349 ; CHECK: %c = icmp slt i32 %y, 0
350 ; CHECK: ret i1 %c
351 define i1 @test33(i32 %x, i32 %y) {
352 %lhs = sub nsw i32 %x, %y
353 %c = icmp sgt i32 %lhs, %x
354 ret i1 %c
355 }
357 ; CHECK-LABEL: @test34(
358 ; X - Y > X -> 0 > Y if there is no overflow.
359 ; CHECK: ret i1 false
360 define i1 @test34(i32 %x, i32 %y) {
361 %lhs = sub nuw i32 %x, %y
362 %c = icmp ugt i32 %lhs, %x
363 ret i1 %c
364 }
366 ; CHECK-LABEL: @test35(
367 ; X > X - Y -> Y > 0 if there is no overflow.
368 ; CHECK: %c = icmp sgt i32 %y, 0
369 ; CHECK: ret i1 %c
370 define i1 @test35(i32 %x, i32 %y) {
371 %rhs = sub nsw i32 %x, %y
372 %c = icmp sgt i32 %x, %rhs
373 ret i1 %c
374 }
376 ; CHECK-LABEL: @test36(
377 ; X > X - Y -> Y > 0 if there is no overflow.
378 ; CHECK: %c = icmp ne i32 %y, 0
379 ; CHECK: ret i1 %c
380 define i1 @test36(i32 %x, i32 %y) {
381 %rhs = sub nuw i32 %x, %y
382 %c = icmp ugt i32 %x, %rhs
383 ret i1 %c
384 }
386 ; CHECK-LABEL: @test37(
387 ; X - Y > X - Z -> Z > Y if there is no overflow.
388 ; CHECK: %c = icmp sgt i32 %z, %y
389 ; CHECK: ret i1 %c
390 define i1 @test37(i32 %x, i32 %y, i32 %z) {
391 %lhs = sub nsw i32 %x, %y
392 %rhs = sub nsw i32 %x, %z
393 %c = icmp sgt i32 %lhs, %rhs
394 ret i1 %c
395 }
397 ; CHECK-LABEL: @test38(
398 ; X - Y > X - Z -> Z > Y if there is no overflow.
399 ; CHECK: %c = icmp ugt i32 %z, %y
400 ; CHECK: ret i1 %c
401 define i1 @test38(i32 %x, i32 %y, i32 %z) {
402 %lhs = sub nuw i32 %x, %y
403 %rhs = sub nuw i32 %x, %z
404 %c = icmp ugt i32 %lhs, %rhs
405 ret i1 %c
406 }
408 ; PR9343 #1
409 ; CHECK-LABEL: @test39(
410 ; CHECK: %B = icmp eq i32 %X, 0
411 define i1 @test39(i32 %X, i32 %Y) {
412 %A = ashr exact i32 %X, %Y
413 %B = icmp eq i32 %A, 0
414 ret i1 %B
415 }
417 ; CHECK-LABEL: @test40(
418 ; CHECK: %B = icmp ne i32 %X, 0
419 define i1 @test40(i32 %X, i32 %Y) {
420 %A = lshr exact i32 %X, %Y
421 %B = icmp ne i32 %A, 0
422 ret i1 %B
423 }
425 ; PR9343 #3
426 ; CHECK-LABEL: @test41(
427 ; CHECK: ret i1 true
428 define i1 @test41(i32 %X, i32 %Y) {
429 %A = urem i32 %X, %Y
430 %B = icmp ugt i32 %Y, %A
431 ret i1 %B
432 }
434 ; CHECK-LABEL: @test42(
435 ; CHECK: %B = icmp sgt i32 %Y, -1
436 define i1 @test42(i32 %X, i32 %Y) {
437 %A = srem i32 %X, %Y
438 %B = icmp slt i32 %A, %Y
439 ret i1 %B
440 }
442 ; CHECK-LABEL: @test43(
443 ; CHECK: %B = icmp slt i32 %Y, 0
444 define i1 @test43(i32 %X, i32 %Y) {
445 %A = srem i32 %X, %Y
446 %B = icmp slt i32 %Y, %A
447 ret i1 %B
448 }
450 ; CHECK-LABEL: @test44(
451 ; CHECK: %B = icmp sgt i32 %Y, -1
452 define i1 @test44(i32 %X, i32 %Y) {
453 %A = srem i32 %X, %Y
454 %B = icmp slt i32 %A, %Y
455 ret i1 %B
456 }
458 ; CHECK-LABEL: @test45(
459 ; CHECK: %B = icmp slt i32 %Y, 0
460 define i1 @test45(i32 %X, i32 %Y) {
461 %A = srem i32 %X, %Y
462 %B = icmp slt i32 %Y, %A
463 ret i1 %B
464 }
466 ; PR9343 #4
467 ; CHECK-LABEL: @test46(
468 ; CHECK: %C = icmp ult i32 %X, %Y
469 define i1 @test46(i32 %X, i32 %Y, i32 %Z) {
470 %A = ashr exact i32 %X, %Z
471 %B = ashr exact i32 %Y, %Z
472 %C = icmp ult i32 %A, %B
473 ret i1 %C
474 }
476 ; PR9343 #5
477 ; CHECK-LABEL: @test47(
478 ; CHECK: %C = icmp ugt i32 %X, %Y
479 define i1 @test47(i32 %X, i32 %Y, i32 %Z) {
480 %A = ashr exact i32 %X, %Z
481 %B = ashr exact i32 %Y, %Z
482 %C = icmp ugt i32 %A, %B
483 ret i1 %C
484 }
486 ; PR9343 #8
487 ; CHECK-LABEL: @test48(
488 ; CHECK: %C = icmp eq i32 %X, %Y
489 define i1 @test48(i32 %X, i32 %Y, i32 %Z) {
490 %A = sdiv exact i32 %X, %Z
491 %B = sdiv exact i32 %Y, %Z
492 %C = icmp eq i32 %A, %B
493 ret i1 %C
494 }
496 ; PR8469
497 ; CHECK-LABEL: @test49(
498 ; CHECK: ret <2 x i1> <i1 true, i1 true>
499 define <2 x i1> @test49(<2 x i32> %tmp3) {
500 entry:
501 %tmp11 = and <2 x i32> %tmp3, <i32 3, i32 3>
502 %cmp = icmp ult <2 x i32> %tmp11, <i32 4, i32 4>
503 ret <2 x i1> %cmp
504 }
506 ; PR9343 #7
507 ; CHECK-LABEL: @test50(
508 ; CHECK: ret i1 true
509 define i1 @test50(i16 %X, i32 %Y) {
510 %A = zext i16 %X to i32
511 %B = srem i32 %A, %Y
512 %C = icmp sgt i32 %B, -1
513 ret i1 %C
514 }
516 ; CHECK-LABEL: @test51(
517 ; CHECK: ret i1 %C
518 define i1 @test51(i32 %X, i32 %Y) {
519 %A = and i32 %X, 2147483648
520 %B = srem i32 %A, %Y
521 %C = icmp sgt i32 %B, -1
522 ret i1 %C
523 }
525 ; CHECK-LABEL: @test52(
526 ; CHECK-NEXT: and i32 %x1, 16711935
527 ; CHECK-NEXT: icmp eq i32 {{.*}}, 4980863
528 ; CHECK-NEXT: ret i1
529 define i1 @test52(i32 %x1) nounwind {
530 %conv = and i32 %x1, 255
531 %cmp = icmp eq i32 %conv, 127
532 %tmp2 = lshr i32 %x1, 16
533 %tmp3 = trunc i32 %tmp2 to i8
534 %cmp15 = icmp eq i8 %tmp3, 76
536 %A = and i1 %cmp, %cmp15
537 ret i1 %A
538 }
540 ; PR9838
541 ; CHECK-LABEL: @test53(
542 ; CHECK-NEXT: sdiv exact
543 ; CHECK-NEXT: sdiv
544 ; CHECK-NEXT: icmp
545 define i1 @test53(i32 %a, i32 %b) nounwind {
546 %x = sdiv exact i32 %a, 30
547 %y = sdiv i32 %b, 30
548 %z = icmp eq i32 %x, %y
549 ret i1 %z
550 }
552 ; CHECK-LABEL: @test54(
553 ; CHECK-NEXT: %and = and i8 %a, -64
554 ; CHECK-NEXT: icmp eq i8 %and, -128
555 define i1 @test54(i8 %a) nounwind {
556 %ext = zext i8 %a to i32
557 %and = and i32 %ext, 192
558 %ret = icmp eq i32 %and, 128
559 ret i1 %ret
560 }
562 ; CHECK-LABEL: @test55(
563 ; CHECK-NEXT: icmp eq i32 %a, -123
564 define i1 @test55(i32 %a) {
565 %sub = sub i32 0, %a
566 %cmp = icmp eq i32 %sub, 123
567 ret i1 %cmp
568 }
570 ; CHECK-LABEL: @test56(
571 ; CHECK-NEXT: icmp eq i32 %a, -113
572 define i1 @test56(i32 %a) {
573 %sub = sub i32 10, %a
574 %cmp = icmp eq i32 %sub, 123
575 ret i1 %cmp
576 }
578 ; PR10267 Don't make icmps more expensive when no other inst is subsumed.
579 declare void @foo(i32)
580 ; CHECK-LABEL: @test57(
581 ; CHECK: %and = and i32 %a, -2
582 ; CHECK: %cmp = icmp ne i32 %and, 0
583 define i1 @test57(i32 %a) {
584 %and = and i32 %a, -2
585 %cmp = icmp ne i32 %and, 0
586 call void @foo(i32 %and)
587 ret i1 %cmp
588 }
590 ; rdar://problem/10482509
591 ; CHECK-LABEL: @cmpabs1(
592 ; CHECK-NEXT: icmp ne
593 define zeroext i1 @cmpabs1(i64 %val) {
594 %sub = sub nsw i64 0, %val
595 %cmp = icmp slt i64 %val, 0
596 %sub.val = select i1 %cmp, i64 %sub, i64 %val
597 %tobool = icmp ne i64 %sub.val, 0
598 ret i1 %tobool
599 }
601 ; CHECK-LABEL: @cmpabs2(
602 ; CHECK-NEXT: icmp ne
603 define zeroext i1 @cmpabs2(i64 %val) {
604 %sub = sub nsw i64 0, %val
605 %cmp = icmp slt i64 %val, 0
606 %sub.val = select i1 %cmp, i64 %val, i64 %sub
607 %tobool = icmp ne i64 %sub.val, 0
608 ret i1 %tobool
609 }
611 ; CHECK-LABEL: @test58(
612 ; CHECK-NEXT: call i32 @test58_d(i64 36029346783166592)
613 define void @test58() nounwind {
614 %cast = bitcast <1 x i64> <i64 36029346783166592> to i64
615 %call = call i32 @test58_d( i64 %cast) nounwind
616 ret void
617 }
618 declare i32 @test58_d(i64)
620 define i1 @test59(i8* %foo) {
621 %bit = bitcast i8* %foo to i32*
622 %gep1 = getelementptr inbounds i32* %bit, i64 2
623 %gep2 = getelementptr inbounds i8* %foo, i64 10
624 %cast1 = bitcast i32* %gep1 to i8*
625 %cmp = icmp ult i8* %cast1, %gep2
626 %use = ptrtoint i8* %cast1 to i64
627 %call = call i32 @test58_d(i64 %use) nounwind
628 ret i1 %cmp
629 ; CHECK-LABEL: @test59(
630 ; CHECK: ret i1 true
631 }
633 define i1 @test59_as1(i8 addrspace(1)* %foo) {
634 %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)*
635 %gep1 = getelementptr inbounds i32 addrspace(1)* %bit, i64 2
636 %gep2 = getelementptr inbounds i8 addrspace(1)* %foo, i64 10
637 %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)*
638 %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
639 %use = ptrtoint i8 addrspace(1)* %cast1 to i64
640 %call = call i32 @test58_d(i64 %use) nounwind
641 ret i1 %cmp
642 ; CHECK: @test59_as1
643 ; CHECK: %[[GEP:.+]] = getelementptr inbounds i8 addrspace(1)* %foo, i16 8
644 ; CHECK: ptrtoint i8 addrspace(1)* %[[GEP]] to i16
645 ; CHECK: ret i1 true
646 }
648 define i1 @test60(i8* %foo, i64 %i, i64 %j) {
649 %bit = bitcast i8* %foo to i32*
650 %gep1 = getelementptr inbounds i32* %bit, i64 %i
651 %gep2 = getelementptr inbounds i8* %foo, i64 %j
652 %cast1 = bitcast i32* %gep1 to i8*
653 %cmp = icmp ult i8* %cast1, %gep2
654 ret i1 %cmp
655 ; CHECK-LABEL: @test60(
656 ; CHECK-NEXT: %gep1.idx = shl nuw i64 %i, 2
657 ; CHECK-NEXT: icmp slt i64 %gep1.idx, %j
658 ; CHECK-NEXT: ret i1
659 }
661 define i1 @test60_as1(i8 addrspace(1)* %foo, i64 %i, i64 %j) {
662 %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)*
663 %gep1 = getelementptr inbounds i32 addrspace(1)* %bit, i64 %i
664 %gep2 = getelementptr inbounds i8 addrspace(1)* %foo, i64 %j
665 %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)*
666 %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
667 ret i1 %cmp
668 ; CHECK: @test60_as1
669 ; CHECK: trunc i64 %i to i16
670 ; CHECK: trunc i64 %j to i16
671 ; CHECK: %gep1.idx = shl nuw i16 %{{.+}}, 2
672 ; CHECK-NEXT: icmp sgt i16 %{{.+}}, %gep1.idx
673 ; CHECK-NEXT: ret i1
674 }
676 ; Same as test60, but look through an addrspacecast instead of a
677 ; bitcast. This uses the same sized addrspace.
678 define i1 @test60_addrspacecast(i8* %foo, i64 %i, i64 %j) {
679 %bit = addrspacecast i8* %foo to i32 addrspace(3)*
680 %gep1 = getelementptr inbounds i32 addrspace(3)* %bit, i64 %i
681 %gep2 = getelementptr inbounds i8* %foo, i64 %j
682 %cast1 = addrspacecast i32 addrspace(3)* %gep1 to i8*
683 %cmp = icmp ult i8* %cast1, %gep2
684 ret i1 %cmp
685 ; CHECK-LABEL: @test60_addrspacecast(
686 ; CHECK-NEXT: %gep1.idx = shl nuw i64 %i, 2
687 ; CHECK-NEXT: icmp slt i64 %gep1.idx, %j
688 ; CHECK-NEXT: ret i1
689 }
691 define i1 @test60_addrspacecast_smaller(i8* %foo, i16 %i, i64 %j) {
692 %bit = addrspacecast i8* %foo to i32 addrspace(1)*
693 %gep1 = getelementptr inbounds i32 addrspace(1)* %bit, i16 %i
694 %gep2 = getelementptr inbounds i8* %foo, i64 %j
695 %cast1 = addrspacecast i32 addrspace(1)* %gep1 to i8*
696 %cmp = icmp ult i8* %cast1, %gep2
697 ret i1 %cmp
698 ; CHECK-LABEL: @test60_addrspacecast_smaller(
699 ; CHECK-NEXT: %gep1.idx = shl nuw i16 %i, 2
700 ; CHECK-NEXT: trunc i64 %j to i16
701 ; CHECK-NEXT: icmp sgt i16 %1, %gep1.idx
702 ; CHECK-NEXT: ret i1
703 }
705 define i1 @test60_addrspacecast_larger(i8 addrspace(1)* %foo, i32 %i, i16 %j) {
706 %bit = addrspacecast i8 addrspace(1)* %foo to i32 addrspace(2)*
707 %gep1 = getelementptr inbounds i32 addrspace(2)* %bit, i32 %i
708 %gep2 = getelementptr inbounds i8 addrspace(1)* %foo, i16 %j
709 %cast1 = addrspacecast i32 addrspace(2)* %gep1 to i8 addrspace(1)*
710 %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
711 ret i1 %cmp
712 ; CHECK-LABEL: @test60_addrspacecast_larger(
713 ; CHECK-NEXT: %gep1.idx = shl nuw i32 %i, 2
714 ; CHECK-NEXT: trunc i32 %gep1.idx to i16
715 ; CHECK-NEXT: icmp slt i16 %1, %j
716 ; CHECK-NEXT: ret i1
717 }
719 define i1 @test61(i8* %foo, i64 %i, i64 %j) {
720 %bit = bitcast i8* %foo to i32*
721 %gep1 = getelementptr i32* %bit, i64 %i
722 %gep2 = getelementptr i8* %foo, i64 %j
723 %cast1 = bitcast i32* %gep1 to i8*
724 %cmp = icmp ult i8* %cast1, %gep2
725 ret i1 %cmp
726 ; Don't transform non-inbounds GEPs.
727 ; CHECK-LABEL: @test61(
728 ; CHECK: icmp ult i8* %cast1, %gep2
729 ; CHECK-NEXT: ret i1
730 }
732 define i1 @test61_as1(i8 addrspace(1)* %foo, i16 %i, i16 %j) {
733 %bit = bitcast i8 addrspace(1)* %foo to i32 addrspace(1)*
734 %gep1 = getelementptr i32 addrspace(1)* %bit, i16 %i
735 %gep2 = getelementptr i8 addrspace(1)* %foo, i16 %j
736 %cast1 = bitcast i32 addrspace(1)* %gep1 to i8 addrspace(1)*
737 %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2
738 ret i1 %cmp
739 ; Don't transform non-inbounds GEPs.
740 ; CHECK: @test61_as1
741 ; CHECK: icmp ult i8 addrspace(1)* %cast1, %gep2
742 ; CHECK-NEXT: ret i1
743 }
745 define i1 @test62(i8* %a) {
746 %arrayidx1 = getelementptr inbounds i8* %a, i64 1
747 %arrayidx2 = getelementptr inbounds i8* %a, i64 10
748 %cmp = icmp slt i8* %arrayidx1, %arrayidx2
749 ret i1 %cmp
750 ; CHECK-LABEL: @test62(
751 ; CHECK-NEXT: ret i1 true
752 }
754 define i1 @test62_as1(i8 addrspace(1)* %a) {
755 ; CHECK-LABEL: @test62_as1(
756 ; CHECK-NEXT: ret i1 true
757 %arrayidx1 = getelementptr inbounds i8 addrspace(1)* %a, i64 1
758 %arrayidx2 = getelementptr inbounds i8 addrspace(1)* %a, i64 10
759 %cmp = icmp slt i8 addrspace(1)* %arrayidx1, %arrayidx2
760 ret i1 %cmp
761 }
763 define i1 @test63(i8 %a, i32 %b) nounwind {
764 %z = zext i8 %a to i32
765 %t = and i32 %b, 255
766 %c = icmp eq i32 %z, %t
767 ret i1 %c
768 ; CHECK-LABEL: @test63(
769 ; CHECK-NEXT: %1 = trunc i32 %b to i8
770 ; CHECK-NEXT: %c = icmp eq i8 %1, %a
771 ; CHECK-NEXT: ret i1 %c
772 }
774 define i1 @test64(i8 %a, i32 %b) nounwind {
775 %t = and i32 %b, 255
776 %z = zext i8 %a to i32
777 %c = icmp eq i32 %t, %z
778 ret i1 %c
779 ; CHECK-LABEL: @test64(
780 ; CHECK-NEXT: %1 = trunc i32 %b to i8
781 ; CHECK-NEXT: %c = icmp eq i8 %1, %a
782 ; CHECK-NEXT: ret i1 %c
783 }
785 define i1 @test65(i64 %A, i64 %B) {
786 %s1 = add i64 %A, %B
787 %s2 = add i64 %A, %B
788 %cmp = icmp eq i64 %s1, %s2
789 ; CHECK-LABEL: @test65(
790 ; CHECK-NEXT: ret i1 true
791 ret i1 %cmp
792 }
794 define i1 @test66(i64 %A, i64 %B) {
795 %s1 = add i64 %A, %B
796 %s2 = add i64 %B, %A
797 %cmp = icmp eq i64 %s1, %s2
798 ; CHECK-LABEL: @test66(
799 ; CHECK-NEXT: ret i1 true
800 ret i1 %cmp
801 }
803 ; CHECK-LABEL: @test67(
804 ; CHECK: %and = and i32 %x, 96
805 ; CHECK: %cmp = icmp ne i32 %and, 0
806 define i1 @test67(i32 %x) nounwind uwtable {
807 %and = and i32 %x, 127
808 %cmp = icmp sgt i32 %and, 31
809 ret i1 %cmp
810 }
812 ; CHECK-LABEL: @test68(
813 ; CHECK: %cmp = icmp ugt i32 %and, 30
814 define i1 @test68(i32 %x) nounwind uwtable {
815 %and = and i32 %x, 127
816 %cmp = icmp sgt i32 %and, 30
817 ret i1 %cmp
818 }
820 ; PR14708
821 ; CHECK-LABEL: @test69(
822 ; CHECK: %1 = and i32 %c, -33
823 ; CHECK: %2 = icmp eq i32 %1, 65
824 ; CHECK: ret i1 %2
825 define i1 @test69(i32 %c) nounwind uwtable {
826 %1 = icmp eq i32 %c, 97
827 %2 = icmp eq i32 %c, 65
828 %3 = or i1 %1, %2
829 ret i1 %3
830 }
832 ; PR15940
833 ; CHECK-LABEL: @test70(
834 ; CHECK-NEXT: %A = srem i32 5, %X
835 ; CHECK-NEXT: %C = icmp ne i32 %A, 2
836 ; CHECK-NEXT: ret i1 %C
837 define i1 @test70(i32 %X) {
838 %A = srem i32 5, %X
839 %B = add i32 %A, 2
840 %C = icmp ne i32 %B, 4
841 ret i1 %C
842 }
844 ; CHECK-LABEL: @icmp_sext16trunc(
845 ; CHECK-NEXT: %1 = trunc i32 %x to i16
846 ; CHECK-NEXT: %cmp = icmp slt i16 %1, 36
847 define i1 @icmp_sext16trunc(i32 %x) {
848 %trunc = trunc i32 %x to i16
849 %sext = sext i16 %trunc to i32
850 %cmp = icmp slt i32 %sext, 36
851 ret i1 %cmp
852 }
854 ; CHECK-LABEL: @icmp_sext8trunc(
855 ; CHECK-NEXT: %1 = trunc i32 %x to i8
856 ; CHECK-NEXT: %cmp = icmp slt i8 %1, 36
857 define i1 @icmp_sext8trunc(i32 %x) {
858 %trunc = trunc i32 %x to i8
859 %sext = sext i8 %trunc to i32
860 %cmp = icmp slt i32 %sext, 36
861 ret i1 %cmp
862 }
864 ; CHECK-LABEL: @icmp_shl16(
865 ; CHECK-NEXT: %1 = trunc i32 %x to i16
866 ; CHECK-NEXT: %cmp = icmp slt i16 %1, 36
867 define i1 @icmp_shl16(i32 %x) {
868 %shl = shl i32 %x, 16
869 %cmp = icmp slt i32 %shl, 2359296
870 ret i1 %cmp
871 }
873 ; CHECK-LABEL: @icmp_shl24(
874 ; CHECK-NEXT: %1 = trunc i32 %x to i8
875 ; CHECK-NEXT: %cmp = icmp slt i8 %1, 36
876 define i1 @icmp_shl24(i32 %x) {
877 %shl = shl i32 %x, 24
878 %cmp = icmp slt i32 %shl, 603979776
879 ret i1 %cmp
880 }
882 ; If the (shl x, C) preserved the sign and this is a sign test,
883 ; compare the LHS operand instead
884 ; CHECK-LABEL: @icmp_shl_nsw_sgt(
885 ; CHECK-NEXT: icmp sgt i32 %x, 0
886 define i1 @icmp_shl_nsw_sgt(i32 %x) {
887 %shl = shl nsw i32 %x, 21
888 %cmp = icmp sgt i32 %shl, 0
889 ret i1 %cmp
890 }
892 ; CHECK-LABEL: @icmp_shl_nsw_sge0(
893 ; CHECK-NEXT: icmp sgt i32 %x, -1
894 define i1 @icmp_shl_nsw_sge0(i32 %x) {
895 %shl = shl nsw i32 %x, 21
896 %cmp = icmp sge i32 %shl, 0
897 ret i1 %cmp
898 }
900 ; CHECK-LABEL: @icmp_shl_nsw_sge1(
901 ; CHECK-NEXT: icmp sgt i32 %x, 0
902 define i1 @icmp_shl_nsw_sge1(i32 %x) {
903 %shl = shl nsw i32 %x, 21
904 %cmp = icmp sge i32 %shl, 1
905 ret i1 %cmp
906 }
908 ; Checks for icmp (eq|ne) (shl x, C), 0
909 ; CHECK-LABEL: @icmp_shl_nsw_eq(
910 ; CHECK-NEXT: icmp eq i32 %x, 0
911 define i1 @icmp_shl_nsw_eq(i32 %x) {
912 %mul = shl nsw i32 %x, 5
913 %cmp = icmp eq i32 %mul, 0
914 ret i1 %cmp
915 }
917 ; CHECK-LABEL: @icmp_shl_eq(
918 ; CHECK-NOT: icmp eq i32 %mul, 0
919 define i1 @icmp_shl_eq(i32 %x) {
920 %mul = shl i32 %x, 5
921 %cmp = icmp eq i32 %mul, 0
922 ret i1 %cmp
923 }
925 ; CHECK-LABEL: @icmp_shl_nsw_ne(
926 ; CHECK-NEXT: icmp ne i32 %x, 0
927 define i1 @icmp_shl_nsw_ne(i32 %x) {
928 %mul = shl nsw i32 %x, 7
929 %cmp = icmp ne i32 %mul, 0
930 ret i1 %cmp
931 }
933 ; CHECK-LABEL: @icmp_shl_ne(
934 ; CHECK-NOT: icmp ne i32 %x, 0
935 define i1 @icmp_shl_ne(i32 %x) {
936 %mul = shl i32 %x, 7
937 %cmp = icmp ne i32 %mul, 0
938 ret i1 %cmp
939 }
941 ; If the (mul x, C) preserved the sign and this is sign test,
942 ; compare the LHS operand instead
943 ; CHECK-LABEL: @icmp_mul_nsw(
944 ; CHECK-NEXT: icmp sgt i32 %x, 0
945 define i1 @icmp_mul_nsw(i32 %x) {
946 %mul = mul nsw i32 %x, 12
947 %cmp = icmp sgt i32 %mul, 0
948 ret i1 %cmp
949 }
951 ; CHECK-LABEL: @icmp_mul_nsw1(
952 ; CHECK-NEXT: icmp slt i32 %x, 0
953 define i1 @icmp_mul_nsw1(i32 %x) {
954 %mul = mul nsw i32 %x, 12
955 %cmp = icmp sle i32 %mul, -1
956 ret i1 %cmp
957 }
959 ; CHECK-LABEL: @icmp_mul_nsw_neg(
960 ; CHECK-NEXT: icmp slt i32 %x, 1
961 define i1 @icmp_mul_nsw_neg(i32 %x) {
962 %mul = mul nsw i32 %x, -12
963 %cmp = icmp sge i32 %mul, 0
964 ret i1 %cmp
965 }
967 ; CHECK-LABEL: @icmp_mul_nsw_neg1(
968 ; CHECK-NEXT: icmp slt i32 %x, 0
969 define i1 @icmp_mul_nsw_neg1(i32 %x) {
970 %mul = mul nsw i32 %x, -12
971 %cmp = icmp sge i32 %mul, 1
972 ret i1 %cmp
973 }
975 ; CHECK-LABEL: @icmp_mul_nsw_0(
976 ; CHECK-NOT: icmp sgt i32 %x, 0
977 define i1 @icmp_mul_nsw_0(i32 %x) {
978 %mul = mul nsw i32 %x, 0
979 %cmp = icmp sgt i32 %mul, 0
980 ret i1 %cmp
981 }
983 ; CHECK-LABEL: @icmp_mul(
984 ; CHECK-NEXT: %mul = mul i32 %x, -12
985 define i1 @icmp_mul(i32 %x) {
986 %mul = mul i32 %x, -12
987 %cmp = icmp sge i32 %mul, 0
988 ret i1 %cmp
989 }
991 ; Checks for icmp (eq|ne) (mul x, C), 0
992 ; CHECK-LABEL: @icmp_mul_neq0(
993 ; CHECK-NEXT: icmp ne i32 %x, 0
994 define i1 @icmp_mul_neq0(i32 %x) {
995 %mul = mul nsw i32 %x, -12
996 %cmp = icmp ne i32 %mul, 0
997 ret i1 %cmp
998 }
1000 ; CHECK-LABEL: @icmp_mul_eq0(
1001 ; CHECK-NEXT: icmp eq i32 %x, 0
1002 define i1 @icmp_mul_eq0(i32 %x) {
1003 %mul = mul nsw i32 %x, 12
1004 %cmp = icmp eq i32 %mul, 0
1005 ret i1 %cmp
1006 }
1008 ; CHECK-LABEL: @icmp_mul0_eq0(
1009 ; CHECK-NEXT: ret i1 true
1010 define i1 @icmp_mul0_eq0(i32 %x) {
1011 %mul = mul i32 %x, 0
1012 %cmp = icmp eq i32 %mul, 0
1013 ret i1 %cmp
1014 }
1016 ; CHECK-LABEL: @icmp_mul0_ne0(
1017 ; CHECK-NEXT: ret i1 false
1018 define i1 @icmp_mul0_ne0(i32 %x) {
1019 %mul = mul i32 %x, 0
1020 %cmp = icmp ne i32 %mul, 0
1021 ret i1 %cmp
1022 }
1024 ; CHECK-LABEL: @icmp_sub1_sge(
1025 ; CHECK-NEXT: icmp sgt i32 %x, %y
1026 define i1 @icmp_sub1_sge(i32 %x, i32 %y) {
1027 %sub = add nsw i32 %x, -1
1028 %cmp = icmp sge i32 %sub, %y
1029 ret i1 %cmp
1030 }
1032 ; CHECK-LABEL: @icmp_add1_sgt(
1033 ; CHECK-NEXT: icmp sge i32 %x, %y
1034 define i1 @icmp_add1_sgt(i32 %x, i32 %y) {
1035 %add = add nsw i32 %x, 1
1036 %cmp = icmp sgt i32 %add, %y
1037 ret i1 %cmp
1038 }
1040 ; CHECK-LABEL: @icmp_sub1_slt(
1041 ; CHECK-NEXT: icmp sle i32 %x, %y
1042 define i1 @icmp_sub1_slt(i32 %x, i32 %y) {
1043 %sub = add nsw i32 %x, -1
1044 %cmp = icmp slt i32 %sub, %y
1045 ret i1 %cmp
1046 }
1048 ; CHECK-LABEL: @icmp_add1_sle(
1049 ; CHECK-NEXT: icmp slt i32 %x, %y
1050 define i1 @icmp_add1_sle(i32 %x, i32 %y) {
1051 %add = add nsw i32 %x, 1
1052 %cmp = icmp sle i32 %add, %y
1053 ret i1 %cmp
1054 }
1056 ; CHECK-LABEL: @icmp_add20_sge_add57(
1057 ; CHECK-NEXT: [[ADD:%[a-z0-9]+]] = add nsw i32 %y, 37
1058 ; CHECK-NEXT: icmp sle i32 [[ADD]], %x
1059 define i1 @icmp_add20_sge_add57(i32 %x, i32 %y) {
1060 %1 = add nsw i32 %x, 20
1061 %2 = add nsw i32 %y, 57
1062 %cmp = icmp sge i32 %1, %2
1063 ret i1 %cmp
1064 }
1066 ; CHECK-LABEL: @icmp_sub57_sge_sub20(
1067 ; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = add nsw i32 %x, -37
1068 ; CHECK-NEXT: icmp sge i32 [[SUB]], %y
1069 define i1 @icmp_sub57_sge_sub20(i32 %x, i32 %y) {
1070 %1 = add nsw i32 %x, -57
1071 %2 = add nsw i32 %y, -20
1072 %cmp = icmp sge i32 %1, %2
1073 ret i1 %cmp
1074 }
1076 ; CHECK-LABEL: @icmp_and_shl_neg_ne_0(
1077 ; CHECK-NEXT: [[SHL:%[a-z0-9]+]] = shl i32 1, %B
1078 ; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 [[SHL]], %A
1079 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp eq i32 [[AND]], 0
1080 ; CHECK-NEXT: ret i1 [[CMP]]
1081 define i1 @icmp_and_shl_neg_ne_0(i32 %A, i32 %B) {
1082 %neg = xor i32 %A, -1
1083 %shl = shl i32 1, %B
1084 %and = and i32 %shl, %neg
1085 %cmp = icmp ne i32 %and, 0
1086 ret i1 %cmp
1087 }
1089 ; CHECK-LABEL: @icmp_and_shl_neg_eq_0(
1090 ; CHECK-NEXT: [[SHL:%[a-z0-9]+]] = shl i32 1, %B
1091 ; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 [[SHL]], %A
1092 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i32 [[AND]], 0
1093 ; CHECK-NEXT: ret i1 [[CMP]]
1094 define i1 @icmp_and_shl_neg_eq_0(i32 %A, i32 %B) {
1095 %neg = xor i32 %A, -1
1096 %shl = shl i32 1, %B
1097 %and = and i32 %shl, %neg
1098 %cmp = icmp eq i32 %and, 0
1099 ret i1 %cmp
1100 }
1102 ; CHECK-LABEL: @icmp_add_and_shr_ne_0(
1103 ; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %X, 240
1104 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i32 [[AND]], 224
1105 ; CHECK-NEXT: ret i1 [[CMP]]
1106 define i1 @icmp_add_and_shr_ne_0(i32 %X) {
1107 %shr = lshr i32 %X, 4
1108 %and = and i32 %shr, 15
1109 %add = add i32 %and, -14
1110 %tobool = icmp ne i32 %add, 0
1111 ret i1 %tobool
1112 }
1114 ; PR16244
1115 ; CHECK-LABEL: define i1 @test71(
1116 ; CHECK-NEXT: ret i1 false
1117 define i1 @test71(i8* %x) {
1118 %a = getelementptr i8* %x, i64 8
1119 %b = getelementptr inbounds i8* %x, i64 8
1120 %c = icmp ugt i8* %a, %b
1121 ret i1 %c
1122 }
1124 define i1 @test71_as1(i8 addrspace(1)* %x) {
1125 ; CHECK-LABEL: @test71_as1(
1126 ; CHECK-NEXT: ret i1 false
1127 %a = getelementptr i8 addrspace(1)* %x, i64 8
1128 %b = getelementptr inbounds i8 addrspace(1)* %x, i64 8
1129 %c = icmp ugt i8 addrspace(1)* %a, %b
1130 ret i1 %c
1131 }
1133 ; CHECK-LABEL: @icmp_shl_1_V_ult_32(
1134 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ult i32 %V, 5
1135 ; CHECK-NEXT: ret i1 [[CMP]]
1136 define i1 @icmp_shl_1_V_ult_32(i32 %V) {
1137 %shl = shl i32 1, %V
1138 %cmp = icmp ult i32 %shl, 32
1139 ret i1 %cmp
1140 }
1142 ; CHECK-LABEL: @icmp_shl_1_V_eq_32(
1143 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp eq i32 %V, 5
1144 ; CHECK-NEXT: ret i1 [[CMP]]
1145 define i1 @icmp_shl_1_V_eq_32(i32 %V) {
1146 %shl = shl i32 1, %V
1147 %cmp = icmp eq i32 %shl, 32
1148 ret i1 %cmp
1149 }
1151 ; CHECK-LABEL: @icmp_shl_1_V_ult_30(
1152 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ult i32 %V, 5
1153 ; CHECK-NEXT: ret i1 [[CMP]]
1154 define i1 @icmp_shl_1_V_ult_30(i32 %V) {
1155 %shl = shl i32 1, %V
1156 %cmp = icmp ult i32 %shl, 30
1157 ret i1 %cmp
1158 }
1160 ; CHECK-LABEL: @icmp_shl_1_V_ugt_30(
1161 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ugt i32 %V, 4
1162 ; CHECK-NEXT: ret i1 [[CMP]]
1163 define i1 @icmp_shl_1_V_ugt_30(i32 %V) {
1164 %shl = shl i32 1, %V
1165 %cmp = icmp ugt i32 %shl, 30
1166 ret i1 %cmp
1167 }
1169 ; CHECK-LABEL: @icmp_shl_1_V_ule_30(
1170 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ult i32 %V, 5
1171 ; CHECK-NEXT: ret i1 [[CMP]]
1172 define i1 @icmp_shl_1_V_ule_30(i32 %V) {
1173 %shl = shl i32 1, %V
1174 %cmp = icmp ule i32 %shl, 30
1175 ret i1 %cmp
1176 }
1178 ; CHECK-LABEL: @icmp_shl_1_V_uge_30(
1179 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ugt i32 %V, 4
1180 ; CHECK-NEXT: ret i1 [[CMP]]
1181 define i1 @icmp_shl_1_V_uge_30(i32 %V) {
1182 %shl = shl i32 1, %V
1183 %cmp = icmp uge i32 %shl, 30
1184 ret i1 %cmp
1185 }
1187 ; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648(
1188 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp eq i32 %V, 31
1189 ; CHECK-NEXT: ret i1 [[CMP]]
1190 define i1 @icmp_shl_1_V_uge_2147483648(i32 %V) {
1191 %shl = shl i32 1, %V
1192 %cmp = icmp uge i32 %shl, 2147483648
1193 ret i1 %cmp
1194 }
1196 ; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648(
1197 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i32 %V, 31
1198 ; CHECK-NEXT: ret i1 [[CMP]]
1199 define i1 @icmp_shl_1_V_ult_2147483648(i32 %V) {
1200 %shl = shl i32 1, %V
1201 %cmp = icmp ult i32 %shl, 2147483648
1202 ret i1 %cmp
1203 }
1205 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B(
1206 ; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = add i64 %b, -1
1207 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp uge i64 [[SUB]], %a
1208 ; CHECK-NEXT: ret i1 [[CMP]]
1209 define i1 @or_icmp_eq_B_0_icmp_ult_A_B(i64 %a, i64 %b) {
1210 %1 = icmp eq i64 %b, 0
1211 %2 = icmp ult i64 %a, %b
1212 %3 = or i1 %1, %2
1213 ret i1 %3
1214 }
1216 ; CHECK-LABEL: @icmp_add_ult_2(
1217 ; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %X, -2
1218 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp eq i32 [[AND]], 14
1219 ; CHECK-NEXT: ret i1 [[CMP]]
1220 define i1 @icmp_add_ult_2(i32 %X) {
1221 %add = add i32 %X, -14
1222 %cmp = icmp ult i32 %add, 2
1223 ret i1 %cmp
1224 }
1226 ; CHECK: @icmp_add_X_-14_ult_2
1227 ; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %X, -2
1228 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp eq i32 [[AND]], 14
1229 ; CHECK-NEXT: ret i1 [[CMP]]
1230 define i1 @icmp_add_X_-14_ult_2(i32 %X) {
1231 %add = add i32 %X, -14
1232 %cmp = icmp ult i32 %add, 2
1233 ret i1 %cmp
1234 }
1236 ; CHECK-LABEL: @icmp_sub_3_X_ult_2(
1237 ; CHECK-NEXT: [[OR:%[a-z0-9]+]] = or i32 %X, 1
1238 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp eq i32 [[OR]], 3
1239 ; CHECK-NEXT: ret i1 [[CMP]]
1240 define i1 @icmp_sub_3_X_ult_2(i32 %X) {
1241 %add = sub i32 3, %X
1242 %cmp = icmp ult i32 %add, 2
1243 ret i1 %cmp
1244 }
1246 ; CHECK: @icmp_add_X_-14_uge_2
1247 ; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %X, -2
1248 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i32 [[AND]], 14
1249 ; CHECK-NEXT: ret i1 [[CMP]]
1250 define i1 @icmp_add_X_-14_uge_2(i32 %X) {
1251 %add = add i32 %X, -14
1252 %cmp = icmp uge i32 %add, 2
1253 ret i1 %cmp
1254 }
1256 ; CHECK-LABEL: @icmp_sub_3_X_uge_2(
1257 ; CHECK-NEXT: [[OR:%[a-z0-9]+]] = or i32 %X, 1
1258 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i32 [[OR]], 3
1259 ; CHECK-NEXT: ret i1 [[CMP]]
1260 define i1 @icmp_sub_3_X_uge_2(i32 %X) {
1261 %add = sub i32 3, %X
1262 %cmp = icmp uge i32 %add, 2
1263 ret i1 %cmp
1264 }
1266 ; CHECK: @icmp_and_X_-16_eq-16
1267 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ugt i32 %X, -17
1268 ; CHECK-NEXT: ret i1 [[CMP]]
1269 define i1 @icmp_and_X_-16_eq-16(i32 %X) {
1270 %and = and i32 %X, -16
1271 %cmp = icmp eq i32 %and, -16
1272 ret i1 %cmp
1273 }
1275 ; CHECK: @icmp_and_X_-16_ne-16
1276 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ult i32 %X, -16
1277 ; CHECK-NEXT: ret i1 [[CMP]]
1278 define i1 @icmp_and_X_-16_ne-16(i32 %X) {
1279 %and = and i32 %X, -16
1280 %cmp = icmp ne i32 %and, -16
1281 ret i1 %cmp
1282 }
1284 ; CHECK: @icmp_sub_-1_X_ult_4
1285 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ugt i32 %X, -5
1286 ; CHECK-NEXT: ret i1 [[CMP]]
1287 define i1 @icmp_sub_-1_X_ult_4(i32 %X) {
1288 %sub = sub i32 -1, %X
1289 %cmp = icmp ult i32 %sub, 4
1290 ret i1 %cmp
1291 }
1293 ; CHECK: @icmp_sub_-1_X_uge_4
1294 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ult i32 %X, -4
1295 ; CHECK-NEXT: ret i1 [[CMP]]
1296 define i1 @icmp_sub_-1_X_uge_4(i32 %X) {
1297 %sub = sub i32 -1, %X
1298 %cmp = icmp uge i32 %sub, 4
1299 ret i1 %cmp
1300 }
1302 ; CHECK-LABEL: @icmp_swap_operands_for_cse
1303 ; CHECK: [[CMP:%[a-z0-9]+]] = icmp ult i32 %X, %Y
1304 ; CHECK-NEXT: br i1 [[CMP]], label %true, label %false
1305 ; CHECK: ret i1
1306 define i1 @icmp_swap_operands_for_cse(i32 %X, i32 %Y) {
1307 entry:
1308 %sub = sub i32 %X, %Y
1309 %cmp = icmp ugt i32 %Y, %X
1310 br i1 %cmp, label %true, label %false
1311 true:
1312 %restrue = trunc i32 %sub to i1
1313 br label %end
1314 false:
1315 %shift = lshr i32 %sub, 4
1316 %resfalse = trunc i32 %shift to i1
1317 br label %end
1318 end:
1319 %res = phi i1 [%restrue, %true], [%resfalse, %false]
1320 ret i1 %res
1321 }
1323 ; CHECK-LABEL: @icmp_swap_operands_for_cse2
1324 ; CHECK: [[CMP:%[a-z0-9]+]] = icmp ult i32 %X, %Y
1325 ; CHECK-NEXT: br i1 [[CMP]], label %true, label %false
1326 ; CHECK: ret i1
1327 define i1 @icmp_swap_operands_for_cse2(i32 %X, i32 %Y) {
1328 entry:
1329 %cmp = icmp ugt i32 %Y, %X
1330 br i1 %cmp, label %true, label %false
1331 true:
1332 %sub = sub i32 %X, %Y
1333 %sub1 = sub i32 %X, %Y
1334 %add = add i32 %sub, %sub1
1335 %restrue = trunc i32 %add to i1
1336 br label %end
1337 false:
1338 %sub2 = sub i32 %Y, %X
1339 %resfalse = trunc i32 %sub2 to i1
1340 br label %end
1341 end:
1342 %res = phi i1 [%restrue, %true], [%resfalse, %false]
1343 ret i1 %res
1344 }
1346 ; CHECK-LABEL: @icmp_do_not_swap_operands_for_cse
1347 ; CHECK: [[CMP:%[a-z0-9]+]] = icmp ugt i32 %Y, %X
1348 ; CHECK-NEXT: br i1 [[CMP]], label %true, label %false
1349 ; CHECK: ret i1
1350 define i1 @icmp_do_not_swap_operands_for_cse(i32 %X, i32 %Y) {
1351 entry:
1352 %cmp = icmp ugt i32 %Y, %X
1353 br i1 %cmp, label %true, label %false
1354 true:
1355 %sub = sub i32 %X, %Y
1356 %restrue = trunc i32 %sub to i1
1357 br label %end
1358 false:
1359 %sub2 = sub i32 %Y, %X
1360 %resfalse = trunc i32 %sub2 to i1
1361 br label %end
1362 end:
1363 %res = phi i1 [%restrue, %true], [%resfalse, %false]
1364 ret i1 %res
1365 }
1367 ; CHECK-LABEL: @icmp_lshr_lshr_eq
1368 ; CHECK: %z.unshifted = xor i32 %a, %b
1369 ; CHECK: %z = icmp ult i32 %z.unshifted, 1073741824
1370 define i1 @icmp_lshr_lshr_eq(i32 %a, i32 %b) nounwind {
1371 %x = lshr i32 %a, 30
1372 %y = lshr i32 %b, 30
1373 %z = icmp eq i32 %x, %y
1374 ret i1 %z
1375 }
1377 ; CHECK-LABEL: @icmp_ashr_ashr_ne
1378 ; CHECK: %z.unshifted = xor i32 %a, %b
1379 ; CHECK: %z = icmp ugt i32 %z.unshifted, 255
1380 define i1 @icmp_ashr_ashr_ne(i32 %a, i32 %b) nounwind {
1381 %x = ashr i32 %a, 8
1382 %y = ashr i32 %b, 8
1383 %z = icmp ne i32 %x, %y
1384 ret i1 %z
1385 }
1387 ; CHECK-LABEL: @icmp_neg_cst_slt
1388 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %a, 10
1389 ; CHECK-NEXT: ret i1 [[CMP]]
1390 define i1 @icmp_neg_cst_slt(i32 %a) {
1391 %1 = sub nsw i32 0, %a
1392 %2 = icmp slt i32 %1, -10
1393 ret i1 %2
1394 }
1396 ; CHECK-LABEL: @icmp_and_or_lshr
1397 ; CHECK-NEXT: [[SHL:%[a-z0-9]+]] = shl nuw i32 1, %y
1398 ; CHECK-NEXT: [[OR:%[a-z0-9]+]] = or i32 [[SHL]], 1
1399 ; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 [[OR]], %x
1400 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i32 [[AND]], 0
1401 ; CHECK-NEXT: ret i1 [[CMP]]
1402 define i1 @icmp_and_or_lshr(i32 %x, i32 %y) {
1403 %shf = lshr i32 %x, %y
1404 %or = or i32 %shf, %x
1405 %and = and i32 %or, 1
1406 %ret = icmp ne i32 %and, 0
1407 ret i1 %ret
1408 }
1410 ; CHECK-LABEL: @icmp_and_or_lshr_cst
1411 ; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, 3
1412 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i32 [[AND]], 0
1413 ; CHECK-NEXT: ret i1 [[CMP]]
1414 define i1 @icmp_and_or_lshr_cst(i32 %x) {
1415 %shf = lshr i32 %x, 1
1416 %or = or i32 %shf, %x
1417 %and = and i32 %or, 1
1418 %ret = icmp ne i32 %and, 0
1419 ret i1 %ret
1420 }
1422 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2
1423 ; CHECK-NEXT: %cmp = icmp ugt i32 %a, 29
1424 ; CHECK-NEXT: ret i1 %cmp
1425 define i1 @shl_ap1_zero_ap2_non_zero_2(i32 %a) {
1426 %shl = shl i32 4, %a
1427 %cmp = icmp eq i32 %shl, 0
1428 ret i1 %cmp
1429 }
1431 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_4
1432 ; CHECK-NEXT: %cmp = icmp ugt i32 %a, 30
1433 ; CHECK-NEXT: ret i1 %cmp
1434 define i1 @shl_ap1_zero_ap2_non_zero_4(i32 %a) {
1435 %shl = shl i32 -2, %a
1436 %cmp = icmp eq i32 %shl, 0
1437 ret i1 %cmp
1438 }
1440 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_positive
1441 ; CHECK-NEXT: %cmp = icmp eq i32 %a, 0
1442 ; CHECK-NEXT: ret i1 %cmp
1443 define i1 @shl_ap1_non_zero_ap2_non_zero_both_positive(i32 %a) {
1444 %shl = shl i32 50, %a
1445 %cmp = icmp eq i32 %shl, 50
1446 ret i1 %cmp
1447 }
1449 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_negative
1450 ; CHECK-NEXT: %cmp = icmp eq i32 %a, 0
1451 ; CHECK-NEXT: ret i1 %cmp
1452 define i1 @shl_ap1_non_zero_ap2_non_zero_both_negative(i32 %a) {
1453 %shl = shl i32 -50, %a
1454 %cmp = icmp eq i32 %shl, -50
1455 ret i1 %cmp
1456 }
1458 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_1
1459 ; CHECK-NEXT: ret i1 false
1460 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_1(i32 %a) {
1461 %shl = shl i32 50, %a
1462 %cmp = icmp eq i32 %shl, 25
1463 ret i1 %cmp
1464 }
1466 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_2
1467 ; CHECK-NEXT: %cmp = icmp eq i32 %a, 1
1468 ; CHECK-NEXT: ret i1 %cmp
1469 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_2(i32 %a) {
1470 %shl = shl i32 25, %a
1471 %cmp = icmp eq i32 %shl, 50
1472 ret i1 %cmp
1473 }
1475 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_3
1476 ; CHECK-NEXT: ret i1 false
1477 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_3(i32 %a) {
1478 %shl = shl i32 26, %a
1479 %cmp = icmp eq i32 %shl, 50
1480 ret i1 %cmp
1481 }
1483 ; CHECK-LABEL: @icmp_sgt_zero_add_nsw
1484 ; CHECK-NEXT: icmp sgt i32 %a, -1
1485 define i1 @icmp_sgt_zero_add_nsw(i32 %a) {
1486 %add = add nsw i32 %a, 1
1487 %cmp = icmp sgt i32 %add, 0
1488 ret i1 %cmp
1489 }
1491 ; CHECK-LABEL: @icmp_sge_zero_add_nsw
1492 ; CHECK-NEXT: icmp sgt i32 %a, -2
1493 define i1 @icmp_sge_zero_add_nsw(i32 %a) {
1494 %add = add nsw i32 %a, 1
1495 %cmp = icmp sge i32 %add, 0
1496 ret i1 %cmp
1497 }
1499 ; CHECK-LABEL: @icmp_slt_zero_add_nsw
1500 ; CHECK-NEXT: icmp slt i32 %a, -1
1501 define i1 @icmp_slt_zero_add_nsw(i32 %a) {
1502 %add = add nsw i32 %a, 1
1503 %cmp = icmp slt i32 %add, 0
1504 ret i1 %cmp
1505 }
1507 ; CHECK-LABEL: @icmp_sle_zero_add_nsw
1508 ; CHECK-NEXT: icmp slt i32 %a, 0
1509 define i1 @icmp_sle_zero_add_nsw(i32 %a) {
1510 %add = add nsw i32 %a, 1
1511 %cmp = icmp sle i32 %add, 0
1512 ret i1 %cmp
1513 }
1515 ; CHECK-LABEL: @icmp_cmpxchg_strong
1516 ; CHECK-NEXT: %[[xchg:.*]] = cmpxchg i32* %sc, i32 %old_val, i32 %new_val seq_cst seq_cst
1517 ; CHECK-NEXT: %[[icmp:.*]] = extractvalue { i32, i1 } %[[xchg]], 1
1518 ; CHECK-NEXT: ret i1 %[[icmp]]
1519 define zeroext i1 @icmp_cmpxchg_strong(i32* %sc, i32 %old_val, i32 %new_val) {
1520 %xchg = cmpxchg i32* %sc, i32 %old_val, i32 %new_val seq_cst seq_cst
1521 %xtrc = extractvalue { i32, i1 } %xchg, 0
1522 %icmp = icmp eq i32 %xtrc, %old_val
1523 ret i1 %icmp
1524 }
1526 ; CHECK-LABEL: @f1
1527 ; CHECK-NEXT: %[[cmp:.*]] = icmp sge i64 %a, %b
1528 ; CHECK-NEXT: ret i1 %[[cmp]]
1529 define i1 @f1(i64 %a, i64 %b) {
1530 %t = sub nsw i64 %a, %b
1531 %v = icmp sge i64 %t, 0
1532 ret i1 %v
1533 }
1535 ; CHECK-LABEL: @f2
1536 ; CHECK-NEXT: %[[cmp:.*]] = icmp sgt i64 %a, %b
1537 ; CHECK-NEXT: ret i1 %[[cmp]]
1538 define i1 @f2(i64 %a, i64 %b) {
1539 %t = sub nsw i64 %a, %b
1540 %v = icmp sgt i64 %t, 0
1541 ret i1 %v
1542 }
1544 ; CHECK-LABEL: @f3
1545 ; CHECK-NEXT: %[[cmp:.*]] = icmp slt i64 %a, %b
1546 ; CHECK-NEXT: ret i1 %[[cmp]]
1547 define i1 @f3(i64 %a, i64 %b) {
1548 %t = sub nsw i64 %a, %b
1549 %v = icmp slt i64 %t, 0
1550 ret i1 %v
1551 }
1553 ; CHECK-LABEL: @f4
1554 ; CHECK-NEXT: %[[cmp:.*]] = icmp sle i64 %a, %b
1555 ; CHECK-NEXT: ret i1 %[[cmp]]
1556 define i1 @f4(i64 %a, i64 %b) {
1557 %t = sub nsw i64 %a, %b
1558 %v = icmp sle i64 %t, 0
1559 ret i1 %v
1560 }
1562 ; CHECK-LABEL: @f5
1563 ; CHECK: %[[cmp:.*]] = icmp slt i32 %[[sub:.*]], 0
1564 ; CHECK: %[[neg:.*]] = sub nsw i32 0, %[[sub]]
1565 ; CHECK: %[[sel:.*]] = select i1 %[[cmp]], i32 %[[neg]], i32 %[[sub]]
1566 ; CHECK: ret i32 %[[sel]]
1567 define i32 @f5(i8 %a, i8 %b) {
1568 %conv = zext i8 %a to i32
1569 %conv3 = zext i8 %b to i32
1570 %sub = sub nsw i32 %conv, %conv3
1571 %cmp4 = icmp slt i32 %sub, 0
1572 %sub7 = sub nsw i32 0, %sub
1573 %sub7.sub = select i1 %cmp4, i32 %sub7, i32 %sub
1574 ret i32 %sub7.sub
1575 }