1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 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"
6 declare i8 @llvm.abs.i8(i8, i1)
8 define i32 @test1(i32 %X) {
10 ; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr i32 [[X:%.*]], 31
11 ; CHECK-NEXT: ret i32 [[X_LOBIT]]
13 %a = icmp slt i32 %X, 0
14 %b = zext i1 %a to i32
18 define <2 x i32> @test1vec(<2 x i32> %X) {
19 ; CHECK-LABEL: @test1vec(
20 ; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 31, i32 31>
21 ; CHECK-NEXT: ret <2 x i32> [[X_LOBIT]]
23 %a = icmp slt <2 x i32> %X, zeroinitializer
24 %b = zext <2 x i1> %a to <2 x i32>
28 define i32 @test2(i32 %X) {
29 ; CHECK-LABEL: @test2(
30 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], -1
31 ; CHECK-NEXT: [[X_LOBIT_NOT:%.*]] = lshr i32 [[TMP1]], 31
32 ; CHECK-NEXT: ret i32 [[X_LOBIT_NOT]]
34 %a = icmp ult i32 %X, -2147483648
35 %b = zext i1 %a to i32
39 define <2 x i32> @test2vec(<2 x i32> %X) {
40 ; CHECK-LABEL: @test2vec(
41 ; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], <i32 -1, i32 -1>
42 ; CHECK-NEXT: [[X_LOBIT_NOT:%.*]] = lshr <2 x i32> [[TMP1]], <i32 31, i32 31>
43 ; CHECK-NEXT: ret <2 x i32> [[X_LOBIT_NOT]]
45 %a = icmp ult <2 x i32> %X, <i32 -2147483648, i32 -2147483648>
46 %b = zext <2 x i1> %a to <2 x i32>
50 define i32 @test3(i32 %X) {
51 ; CHECK-LABEL: @test3(
52 ; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31
53 ; CHECK-NEXT: ret i32 [[X_LOBIT]]
55 %a = icmp slt i32 %X, 0
56 %b = sext i1 %a to i32
60 define i32 @test4(i32 %X) {
61 ; CHECK-LABEL: @test4(
62 ; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr i32 [[X:%.*]], 31
63 ; CHECK-NEXT: [[X_LOBIT_NOT:%.*]] = xor i32 [[X_LOBIT]], -1
64 ; CHECK-NEXT: ret i32 [[X_LOBIT_NOT]]
66 %a = icmp ult i32 %X, -2147483648
67 %b = sext i1 %a to i32
72 define <2 x i1> @test5_eq(<2 x i64> %x) {
73 ; CHECK-LABEL: @test5_eq(
74 ; CHECK-NEXT: ret <2 x i1> undef
76 %V = icmp eq <2 x i64> %x, undef
79 define <2 x i1> @test5_ne(<2 x i64> %x) {
80 ; CHECK-LABEL: @test5_ne(
81 ; CHECK-NEXT: ret <2 x i1> undef
83 %V = icmp ne <2 x i64> %x, undef
86 define <2 x i1> @test5_ugt(<2 x i64> %x) {
87 ; CHECK-LABEL: @test5_ugt(
88 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
90 %V = icmp ugt <2 x i64> %x, undef
93 define <2 x i1> @test5_zero() {
94 ; CHECK-LABEL: @test5_zero(
95 ; CHECK-NEXT: ret <2 x i1> undef
97 %V = icmp eq <2 x i64> zeroinitializer, undef
101 define i32 @test6(i32 %a, i32 %b) {
102 ; CHECK-LABEL: @test6(
103 ; CHECK-NEXT: [[ISNEG:%.*]] = icmp slt i32 [[A:%.*]], 0
104 ; CHECK-NEXT: [[F:%.*]] = select i1 [[ISNEG]], i32 [[B:%.*]], i32 0
105 ; CHECK-NEXT: ret i32 [[F]]
107 %c = icmp sle i32 %a, -1
108 %d = zext i1 %c to i32
115 define i1 @test7(i32 %x) {
116 ; CHECK-LABEL: @test7(
117 ; CHECK-NEXT: [[B:%.*]] = icmp ne i32 [[X:%.*]], 0
118 ; CHECK-NEXT: ret i1 [[B]]
121 %b = icmp ult i32 %a, %x
125 define <2 x i1> @test7_vec(<2 x i32> %x) {
126 ; CHECK-LABEL: @test7_vec(
127 ; CHECK-NEXT: [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
128 ; CHECK-NEXT: ret <2 x i1> [[B]]
130 %a = add <2 x i32> %x, <i32 -1, i32 -1>
131 %b = icmp ult <2 x i32> %a, %x
135 define i1 @test8(i32 %x) {
136 ; CHECK-LABEL: @test8(
137 ; CHECK-NEXT: ret i1 false
140 %b = icmp eq i32 %a, %x
144 define <2 x i1> @test8_vec(<2 x i32> %x) {
145 ; CHECK-LABEL: @test8_vec(
146 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
148 %a = add <2 x i32> %x, <i32 -1, i32 -1>
149 %b = icmp eq <2 x i32> %a, %x
153 define i1 @test9(i32 %x) {
154 ; CHECK-LABEL: @test9(
155 ; CHECK-NEXT: [[B:%.*]] = icmp ugt i32 [[X:%.*]], 1
156 ; CHECK-NEXT: ret i1 [[B]]
159 %b = icmp ugt i32 %x, %a
163 define <2 x i1> @test9_vec(<2 x i32> %x) {
164 ; CHECK-LABEL: @test9_vec(
165 ; CHECK-NEXT: [[B:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 1, i32 1>
166 ; CHECK-NEXT: ret <2 x i1> [[B]]
168 %a = add <2 x i32> %x, <i32 -2, i32 -2>
169 %b = icmp ugt <2 x i32> %x, %a
173 define i1 @test9b(i32 %x) {
174 ; CHECK-LABEL: @test9b(
175 ; CHECK-NEXT: [[B:%.*]] = icmp ult i32 [[X:%.*]], 2
176 ; CHECK-NEXT: ret i1 [[B]]
179 %b = icmp ugt i32 %a, %x
183 define <2 x i1> @test9b_vec(<2 x i32> %x) {
184 ; CHECK-LABEL: @test9b_vec(
185 ; CHECK-NEXT: [[B:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 2, i32 2>
186 ; CHECK-NEXT: ret <2 x i1> [[B]]
188 %a = add <2 x i32> %x, <i32 -2, i32 -2>
189 %b = icmp ugt <2 x i32> %a, %x
193 define i1 @test10(i32 %x) {
194 ; CHECK-LABEL: @test10(
195 ; CHECK-NEXT: [[B:%.*]] = icmp ne i32 [[X:%.*]], -2147483648
196 ; CHECK-NEXT: ret i1 [[B]]
199 %b = icmp slt i32 %a, %x
203 define <2 x i1> @test10_vec(<2 x i32> %x) {
204 ; CHECK-LABEL: @test10_vec(
205 ; CHECK-NEXT: [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 -2147483648, i32 -2147483648>
206 ; CHECK-NEXT: ret <2 x i1> [[B]]
208 %a = add <2 x i32> %x, <i32 -1, i32 -1>
209 %b = icmp slt <2 x i32> %a, %x
213 define i1 @test10b(i32 %x) {
214 ; CHECK-LABEL: @test10b(
215 ; CHECK-NEXT: [[B:%.*]] = icmp eq i32 [[X:%.*]], -2147483648
216 ; CHECK-NEXT: ret i1 [[B]]
219 %b = icmp sgt i32 %a, %x
223 define <2 x i1> @test10b_vec(<2 x i32> %x) {
224 ; CHECK-LABEL: @test10b_vec(
225 ; CHECK-NEXT: [[B:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 -2147483648, i32 -2147483648>
226 ; CHECK-NEXT: ret <2 x i1> [[B]]
228 %a = add <2 x i32> %x, <i32 -1, i32 -1>
229 %b = icmp sgt <2 x i32> %a, %x
233 define i1 @test11(i32 %x) {
234 ; CHECK-LABEL: @test11(
235 ; CHECK-NEXT: ret i1 true
237 %a = add nsw i32 %x, 8
238 %b = icmp slt i32 %x, %a
242 define <2 x i1> @test11_vec(<2 x i32> %x) {
243 ; CHECK-LABEL: @test11_vec(
244 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
246 %a = add nsw <2 x i32> %x, <i32 8, i32 8>
247 %b = icmp slt <2 x i32> %x, %a
252 define i1 @test12(i1 %A) {
253 ; CHECK-LABEL: @test12(
254 ; CHECK-NEXT: [[NOT_A:%.*]] = xor i1 [[A:%.*]], true
255 ; CHECK-NEXT: ret i1 [[NOT_A]]
257 %S = select i1 %A, i64 -4294967295, i64 8589934591
258 %B = icmp ne i64 bitcast (<2 x i32> <i32 1, i32 -1> to i64), %S
263 define i1 @test13(i8 %X) {
264 ; CHECK-LABEL: @test13(
265 ; CHECK-NEXT: ret i1 false
267 %cmp = icmp slt i8 undef, %X
271 define i1 @test14(i8 %X) {
272 ; CHECK-LABEL: @test14(
273 ; CHECK-NEXT: ret i1 false
275 %cmp = icmp slt i8 undef, -128
279 define i1 @test15() {
280 ; CHECK-LABEL: @test15(
281 ; CHECK-NEXT: ret i1 undef
283 %cmp = icmp eq i8 undef, -128
287 define i1 @test16() {
288 ; CHECK-LABEL: @test16(
289 ; CHECK-NEXT: ret i1 undef
291 %cmp = icmp ne i8 undef, -128
295 define i1 @test17(i32 %x) {
296 ; CHECK-LABEL: @test17(
297 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 3
298 ; CHECK-NEXT: ret i1 [[CMP]]
301 %and = and i32 %shl, 8
302 %cmp = icmp eq i32 %and, 0
306 define <2 x i1> @test17vec(<2 x i32> %x) {
307 ; CHECK-LABEL: @test17vec(
308 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 3, i32 3>
309 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
311 %shl = shl <2 x i32> <i32 1, i32 1>, %x
312 %and = and <2 x i32> %shl, <i32 8, i32 8>
313 %cmp = icmp eq <2 x i32> %and, zeroinitializer
317 define i1 @test17a(i32 %x) {
318 ; CHECK-LABEL: @test17a(
319 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], 2
320 ; CHECK-NEXT: ret i1 [[CMP]]
323 %and = and i32 %shl, 7
324 %cmp = icmp eq i32 %and, 0
328 define <2 x i1> @test17a_vec(<2 x i32> %x) {
329 ; CHECK-LABEL: @test17a_vec(
330 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 2, i32 2>
331 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
333 %shl = shl <2 x i32> <i32 1, i32 1>, %x
334 %and = and <2 x i32> %shl, <i32 7, i32 7>
335 %cmp = icmp eq <2 x i32> %and, zeroinitializer
339 define i1 @test18_eq(i32 %x) {
340 ; CHECK-LABEL: @test18_eq(
341 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 3
342 ; CHECK-NEXT: ret i1 [[CMP]]
345 %and = and i32 %sh, 1
346 %cmp = icmp eq i32 %and, 0
350 define <2 x i1> @test18_eq_vec(<2 x i32> %x) {
351 ; CHECK-LABEL: @test18_eq_vec(
352 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 3, i32 3>
353 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
355 %sh = lshr <2 x i32> <i32 8, i32 8>, %x
356 %and = and <2 x i32> %sh, <i32 1, i32 1>
357 %cmp = icmp eq <2 x i32> %and, zeroinitializer
361 define i1 @test18_ne(i32 %x) {
362 ; CHECK-LABEL: @test18_ne(
363 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3
364 ; CHECK-NEXT: ret i1 [[CMP]]
367 %and = and i32 %sh, 1
368 %cmp = icmp ne i32 %and, 0
372 define <2 x i1> @test18_ne_vec(<2 x i32> %x) {
373 ; CHECK-LABEL: @test18_ne_vec(
374 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 3, i32 3>
375 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
377 %sh = lshr <2 x i32> <i32 8, i32 8>, %x
378 %and = and <2 x i32> %sh, <i32 1, i32 1>
379 %cmp = icmp ne <2 x i32> %and, zeroinitializer
383 define i1 @test19(i32 %x) {
384 ; CHECK-LABEL: @test19(
385 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3
386 ; CHECK-NEXT: ret i1 [[CMP]]
389 %and = and i32 %shl, 8
390 %cmp = icmp eq i32 %and, 8
394 define <2 x i1> @test19vec(<2 x i32> %x) {
395 ; CHECK-LABEL: @test19vec(
396 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 3, i32 3>
397 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
399 %shl = shl <2 x i32> <i32 1, i32 1>, %x
400 %and = and <2 x i32> %shl, <i32 8, i32 8>
401 %cmp = icmp eq <2 x i32> %and, <i32 8, i32 8>
405 define <2 x i1> @cmp_and_signbit_vec(<2 x i3> %x) {
406 ; CHECK-LABEL: @cmp_and_signbit_vec(
407 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i3> [[X:%.*]], zeroinitializer
408 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
410 %and = and <2 x i3> %x, <i3 4, i3 4>
411 %cmp = icmp ne <2 x i3> %and, zeroinitializer
415 define i1 @test20(i32 %x) {
416 ; CHECK-LABEL: @test20(
417 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3
418 ; CHECK-NEXT: ret i1 [[CMP]]
421 %and = and i32 %shl, 8
422 %cmp = icmp ne i32 %and, 0
426 define <2 x i1> @test20vec(<2 x i32> %x) {
427 ; CHECK-LABEL: @test20vec(
428 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 3, i32 3>
429 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
431 %shl = shl <2 x i32> <i32 1, i32 1>, %x
432 %and = and <2 x i32> %shl, <i32 8, i32 8>
433 %cmp = icmp ne <2 x i32> %and, zeroinitializer
437 define i1 @test20a(i32 %x) {
438 ; CHECK-LABEL: @test20a(
439 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 3
440 ; CHECK-NEXT: ret i1 [[CMP]]
443 %and = and i32 %shl, 7
444 %cmp = icmp ne i32 %and, 0
448 define <2 x i1> @test20a_vec(<2 x i32> %x) {
449 ; CHECK-LABEL: @test20a_vec(
450 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 3, i32 3>
451 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
453 %shl = shl <2 x i32> <i32 1, i32 1>, %x
454 %and = and <2 x i32> %shl, <i32 7, i32 7>
455 %cmp = icmp ne <2 x i32> %and, zeroinitializer
459 define i1 @test21(i8 %x, i8 %y) {
460 ; CHECK-LABEL: @test21(
461 ; CHECK-NEXT: [[B:%.*]] = icmp ugt i8 [[X:%.*]], 3
462 ; CHECK-NEXT: ret i1 [[B]]
465 %B = icmp ugt i8 %A, 3
469 define i1 @test22(i8 %x, i8 %y) {
470 ; CHECK-LABEL: @test22(
471 ; CHECK-NEXT: [[B:%.*]] = icmp ult i8 [[X:%.*]], 4
472 ; CHECK-NEXT: ret i1 [[B]]
475 %B = icmp ult i8 %A, 4
480 define i1 @test23(i32 %x) {
481 ; CHECK-LABEL: @test23(
482 ; CHECK-NEXT: [[I4:%.*]] = icmp sgt i32 [[X:%.*]], 1328634634
483 ; CHECK-NEXT: ret i1 [[I4]]
485 %i3 = sdiv i32 %x, -1328634635
486 %i4 = icmp eq i32 %i3, -1
490 define <2 x i1> @test23vec(<2 x i32> %x) {
491 ; CHECK-LABEL: @test23vec(
492 ; CHECK-NEXT: [[I4:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 1328634634, i32 1328634634>
493 ; CHECK-NEXT: ret <2 x i1> [[I4]]
495 %i3 = sdiv <2 x i32> %x, <i32 -1328634635, i32 -1328634635>
496 %i4 = icmp eq <2 x i32> %i3, <i32 -1, i32 -1>
500 ; Note: offs can be negative, LLVM used to make an incorrect assumption that
501 ; unsigned overflow does not happen during offset computation
502 define i1 @test24_neg_offs(i32* %p, i64 %offs) {
503 ; CHECK-LABEL: @test24_neg_offs(
504 ; CHECK-NEXT: [[P1_IDX_NEG:%.*]] = mul i64 [[OFFS:%.*]], -4
505 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[P1_IDX_NEG]], 8
506 ; CHECK-NEXT: ret i1 [[CMP]]
508 %p1 = getelementptr inbounds i32, i32* %p, i64 %offs
509 %conv1 = ptrtoint i32* %p to i64
510 %conv2 = ptrtoint i32* %p1 to i64
511 %delta = sub i64 %conv1, %conv2
512 %cmp = icmp eq i64 %delta, 8
516 ; X - Z > Y - Z -> X > Y if there is no overflow.
517 define i1 @test27(i32 %x, i32 %y, i32 %z) {
518 ; CHECK-LABEL: @test27(
519 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
520 ; CHECK-NEXT: ret i1 [[C]]
522 %lhs = sub nsw i32 %x, %z
523 %rhs = sub nsw i32 %y, %z
524 %c = icmp sgt i32 %lhs, %rhs
528 define i1 @test27_extra_uses(i32 %x, i32 %y, i32 %z) {
529 ; CHECK-LABEL: @test27_extra_uses(
530 ; CHECK-NEXT: [[LHS:%.*]] = sub nsw i32 [[X:%.*]], [[Z:%.*]]
531 ; CHECK-NEXT: call void @foo(i32 [[LHS]])
532 ; CHECK-NEXT: [[RHS:%.*]] = sub nsw i32 [[Y:%.*]], [[Z]]
533 ; CHECK-NEXT: call void @foo(i32 [[RHS]])
534 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X]], [[Y]]
535 ; CHECK-NEXT: ret i1 [[C]]
537 %lhs = sub nsw i32 %x, %z
538 call void @foo(i32 %lhs)
539 %rhs = sub nsw i32 %y, %z
540 call void @foo(i32 %rhs)
541 %c = icmp sgt i32 %lhs, %rhs
545 ; X - Z > Y - Z -> X > Y if there is no overflow.
546 define i1 @test28(i32 %x, i32 %y, i32 %z) {
547 ; CHECK-LABEL: @test28(
548 ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
549 ; CHECK-NEXT: ret i1 [[C]]
551 %lhs = sub nuw i32 %x, %z
552 %rhs = sub nuw i32 %y, %z
553 %c = icmp ugt i32 %lhs, %rhs
557 define i1 @test28_extra_uses(i32 %x, i32 %y, i32 %z) {
558 ; CHECK-LABEL: @test28_extra_uses(
559 ; CHECK-NEXT: [[LHS:%.*]] = sub nuw i32 [[X:%.*]], [[Z:%.*]]
560 ; CHECK-NEXT: call void @foo(i32 [[LHS]])
561 ; CHECK-NEXT: [[RHS:%.*]] = sub nuw i32 [[Y:%.*]], [[Z]]
562 ; CHECK-NEXT: call void @foo(i32 [[RHS]])
563 ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X]], [[Y]]
564 ; CHECK-NEXT: ret i1 [[C]]
566 %lhs = sub nuw i32 %x, %z
567 call void @foo(i32 %lhs)
568 %rhs = sub nuw i32 %y, %z
569 call void @foo(i32 %rhs)
570 %c = icmp ugt i32 %lhs, %rhs
574 ; PR36969 - https://bugs.llvm.org/show_bug.cgi?id=36969
576 define i1 @ugt_sub(i32 %xsrc, i32 %y) {
577 ; CHECK-LABEL: @ugt_sub(
578 ; CHECK-NEXT: [[X:%.*]] = udiv i32 [[XSRC:%.*]], 42
579 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X]], [[Y:%.*]]
580 ; CHECK-NEXT: ret i1 [[CMP]]
582 %x = udiv i32 %xsrc, 42 ; thwart complexity-based canonicalization
583 %sub = sub i32 %x, %y
584 %cmp = icmp ugt i32 %sub, %x
588 ; Swap operands and predicate. Try a vector type to verify that works too.
590 define <2 x i1> @ult_sub(<2 x i8> %xsrc, <2 x i8> %y) {
591 ; CHECK-LABEL: @ult_sub(
592 ; CHECK-NEXT: [[X:%.*]] = udiv <2 x i8> [[XSRC:%.*]], <i8 42, i8 -42>
593 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i8> [[X]], [[Y:%.*]]
594 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
596 %x = udiv <2 x i8> %xsrc, <i8 42, i8 -42> ; thwart complexity-based canonicalization
597 %sub = sub <2 x i8> %x, %y
598 %cmp = icmp ult <2 x i8> %x, %sub
602 ; X - Y > X -> 0 > Y if there is no overflow.
603 define i1 @test33(i32 %x, i32 %y) {
604 ; CHECK-LABEL: @test33(
605 ; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[Y:%.*]], 0
606 ; CHECK-NEXT: ret i1 [[C]]
608 %lhs = sub nsw i32 %x, %y
609 %c = icmp sgt i32 %lhs, %x
613 ; X - Y > X -> 0 > Y if there is no overflow.
614 define i1 @test34(i32 %x, i32 %y) {
615 ; CHECK-LABEL: @test34(
616 ; CHECK-NEXT: ret i1 false
618 %lhs = sub nuw i32 %x, %y
619 %c = icmp ugt i32 %lhs, %x
623 ; X > X - Y -> Y > 0 if there is no overflow.
624 define i1 @test35(i32 %x, i32 %y) {
625 ; CHECK-LABEL: @test35(
626 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Y:%.*]], 0
627 ; CHECK-NEXT: ret i1 [[C]]
629 %rhs = sub nsw i32 %x, %y
630 %c = icmp sgt i32 %x, %rhs
634 ; X > X - Y -> Y > 0 if there is no overflow.
635 define i1 @test36(i32 %x, i32 %y) {
636 ; CHECK-LABEL: @test36(
637 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[Y:%.*]], 0
638 ; CHECK-NEXT: ret i1 [[C]]
640 %rhs = sub nuw i32 %x, %y
641 %c = icmp ugt i32 %x, %rhs
645 ; X - Y > X - Z -> Z > Y if there is no overflow.
646 define i1 @test37(i32 %x, i32 %y, i32 %z) {
647 ; CHECK-LABEL: @test37(
648 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Z:%.*]], [[Y:%.*]]
649 ; CHECK-NEXT: ret i1 [[C]]
651 %lhs = sub nsw i32 %x, %y
652 %rhs = sub nsw i32 %x, %z
653 %c = icmp sgt i32 %lhs, %rhs
657 define i1 @test37_extra_uses(i32 %x, i32 %y, i32 %z) {
658 ; CHECK-LABEL: @test37_extra_uses(
659 ; CHECK-NEXT: [[LHS:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
660 ; CHECK-NEXT: call void @foo(i32 [[LHS]])
661 ; CHECK-NEXT: [[RHS:%.*]] = sub nsw i32 [[X]], [[Z:%.*]]
662 ; CHECK-NEXT: call void @foo(i32 [[RHS]])
663 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[Z]], [[Y]]
664 ; CHECK-NEXT: ret i1 [[C]]
666 %lhs = sub nsw i32 %x, %y
667 call void @foo(i32 %lhs)
668 %rhs = sub nsw i32 %x, %z
669 call void @foo(i32 %rhs)
670 %c = icmp sgt i32 %lhs, %rhs
674 ; TODO: Min/max pattern should not prevent the fold.
676 define i32 @neg_max_s32(i32 %x, i32 %y) {
677 ; CHECK-LABEL: @neg_max_s32(
678 ; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
679 ; CHECK-NEXT: [[S_NEG:%.*]] = select i1 [[C]], i32 [[Y]], i32 [[X]]
680 ; CHECK-NEXT: ret i32 [[S_NEG]]
682 %nx = sub nsw i32 0, %x
683 %ny = sub nsw i32 0, %y
684 %c = icmp slt i32 %nx, %ny
685 %s = select i1 %c, i32 %ny, i32 %nx
686 %r = sub nsw i32 0, %s
690 define <4 x i32> @neg_max_v4s32(<4 x i32> %x, <4 x i32> %y) {
691 ; CHECK-LABEL: @neg_max_v4s32(
692 ; CHECK-NEXT: [[C:%.*]] = icmp sgt <4 x i32> [[Y:%.*]], [[X:%.*]]
693 ; CHECK-NEXT: [[S_NEG:%.*]] = select <4 x i1> [[C]], <4 x i32> [[X]], <4 x i32> [[Y]]
694 ; CHECK-NEXT: ret <4 x i32> [[S_NEG]]
696 %nx = sub nsw <4 x i32> zeroinitializer, %x
697 %ny = sub nsw <4 x i32> zeroinitializer, %y
698 %c = icmp sgt <4 x i32> %nx, %ny
699 %s = select <4 x i1> %c, <4 x i32> %nx, <4 x i32> %ny
700 %r = sub <4 x i32> zeroinitializer, %s
704 ; X - Y > X - Z -> Z > Y if there is no overflow.
705 define i1 @test38(i32 %x, i32 %y, i32 %z) {
706 ; CHECK-LABEL: @test38(
707 ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[Z:%.*]], [[Y:%.*]]
708 ; CHECK-NEXT: ret i1 [[C]]
710 %lhs = sub nuw i32 %x, %y
711 %rhs = sub nuw i32 %x, %z
712 %c = icmp ugt i32 %lhs, %rhs
716 define i1 @test38_extra_uses(i32 %x, i32 %y, i32 %z) {
717 ; CHECK-LABEL: @test38_extra_uses(
718 ; CHECK-NEXT: [[LHS:%.*]] = sub nuw i32 [[X:%.*]], [[Y:%.*]]
719 ; CHECK-NEXT: call void @foo(i32 [[LHS]])
720 ; CHECK-NEXT: [[RHS:%.*]] = sub nuw i32 [[X]], [[Z:%.*]]
721 ; CHECK-NEXT: call void @foo(i32 [[RHS]])
722 ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[Z]], [[Y]]
723 ; CHECK-NEXT: ret i1 [[C]]
725 %lhs = sub nuw i32 %x, %y
726 call void @foo(i32 %lhs)
727 %rhs = sub nuw i32 %x, %z
728 call void @foo(i32 %rhs)
729 %c = icmp ugt i32 %lhs, %rhs
733 define i1 @shr_exact(i132 %x) {
734 ; CHECK-LABEL: @shr_exact(
735 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i132 [[X:%.*]], 32
736 ; CHECK-NEXT: ret i1 [[CMP]]
738 %sh = ashr exact i132 %x, 4
739 %cmp = icmp eq i132 %sh, 2
743 define <2 x i1> @shr_exact_vec(<2 x i132> %x) {
744 ; CHECK-LABEL: @shr_exact_vec(
745 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i132> [[X:%.*]], <i132 32, i132 32>
746 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
748 %sh = lshr exact <2 x i132> %x, <i132 4, i132 4>
749 %cmp = icmp ne <2 x i132> %sh, <i132 2, i132 2>
754 define i1 @test41(i32 %X, i32 %Y) {
755 ; CHECK-LABEL: @test41(
756 ; CHECK-NEXT: ret i1 true
759 %B = icmp ugt i32 %Y, %A
763 define i1 @test42(i32 %X, i32 %Y) {
764 ; CHECK-LABEL: @test42(
765 ; CHECK-NEXT: [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1
766 ; CHECK-NEXT: ret i1 [[B]]
769 %B = icmp slt i32 %A, %Y
773 define i1 @test43(i32 %X, i32 %Y) {
774 ; CHECK-LABEL: @test43(
775 ; CHECK-NEXT: [[B:%.*]] = icmp slt i32 [[Y:%.*]], 0
776 ; CHECK-NEXT: ret i1 [[B]]
779 %B = icmp slt i32 %Y, %A
783 define i1 @test44(i32 %X, i32 %Y) {
784 ; CHECK-LABEL: @test44(
785 ; CHECK-NEXT: [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1
786 ; CHECK-NEXT: ret i1 [[B]]
789 %B = icmp slt i32 %A, %Y
793 define i1 @test45(i32 %X, i32 %Y) {
794 ; CHECK-LABEL: @test45(
795 ; CHECK-NEXT: [[B:%.*]] = icmp slt i32 [[Y:%.*]], 0
796 ; CHECK-NEXT: ret i1 [[B]]
799 %B = icmp slt i32 %Y, %A
804 define i1 @test46(i32 %X, i32 %Y, i32 %Z) {
805 ; CHECK-LABEL: @test46(
806 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
807 ; CHECK-NEXT: ret i1 [[C]]
809 %A = ashr exact i32 %X, %Z
810 %B = ashr exact i32 %Y, %Z
811 %C = icmp ult i32 %A, %B
816 define i1 @test47(i32 %X, i32 %Y, i32 %Z) {
817 ; CHECK-LABEL: @test47(
818 ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
819 ; CHECK-NEXT: ret i1 [[C]]
821 %A = ashr exact i32 %X, %Z
822 %B = ashr exact i32 %Y, %Z
823 %C = icmp ugt i32 %A, %B
828 define i1 @test48(i32 %X, i32 %Y, i32 %Z) {
829 ; CHECK-LABEL: @test48(
830 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
831 ; CHECK-NEXT: ret i1 [[C]]
833 %A = sdiv exact i32 %X, %Z
834 %B = sdiv exact i32 %Y, %Z
835 %C = icmp eq i32 %A, %B
839 ; The above transform only works for equality predicates.
841 define i1 @PR32949(i32 %X, i32 %Y, i32 %Z) {
842 ; CHECK-LABEL: @PR32949(
843 ; CHECK-NEXT: [[A:%.*]] = sdiv exact i32 [[X:%.*]], [[Z:%.*]]
844 ; CHECK-NEXT: [[B:%.*]] = sdiv exact i32 [[Y:%.*]], [[Z]]
845 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[A]], [[B]]
846 ; CHECK-NEXT: ret i1 [[C]]
848 %A = sdiv exact i32 %X, %Z
849 %B = sdiv exact i32 %Y, %Z
850 %C = icmp sgt i32 %A, %B
855 define <2 x i1> @test49(<2 x i32> %i3) {
856 ; CHECK-LABEL: @test49(
858 ; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
861 %i11 = and <2 x i32> %i3, <i32 3, i32 3>
862 %cmp = icmp ult <2 x i32> %i11, <i32 4, i32 4>
867 define i1 @test50(i16 %X, i32 %Y) {
868 ; CHECK-LABEL: @test50(
869 ; CHECK-NEXT: ret i1 true
871 %A = zext i16 %X to i32
873 %C = icmp sgt i32 %B, -1
877 define i1 @test51(i32 %X, i32 %Y) {
878 ; CHECK-LABEL: @test51(
879 ; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], -2147483648
880 ; CHECK-NEXT: [[B:%.*]] = srem i32 [[A]], [[Y:%.*]]
881 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[B]], -1
882 ; CHECK-NEXT: ret i1 [[C]]
884 %A = and i32 %X, 2147483648
886 %C = icmp sgt i32 %B, -1
890 define i1 @test52(i32 %x1) {
891 ; CHECK-LABEL: @test52(
892 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X1:%.*]], 16711935
893 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 4980863
894 ; CHECK-NEXT: ret i1 [[TMP2]]
896 %conv = and i32 %x1, 255
897 %cmp = icmp eq i32 %conv, 127
898 %i2 = lshr i32 %x1, 16
899 %i3 = trunc i32 %i2 to i8
900 %cmp15 = icmp eq i8 %i3, 76
902 %A = and i1 %cmp, %cmp15
906 define i1 @test52_logical(i32 %x1) {
907 ; CHECK-LABEL: @test52_logical(
908 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X1:%.*]], 16711935
909 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 4980863
910 ; CHECK-NEXT: ret i1 [[TMP2]]
912 %conv = and i32 %x1, 255
913 %cmp = icmp eq i32 %conv, 127
914 %i2 = lshr i32 %x1, 16
915 %i3 = trunc i32 %i2 to i8
916 %cmp15 = icmp eq i8 %i3, 76
918 %A = select i1 %cmp, i1 %cmp15, i1 false
922 define i1 @test52b(i128 %x1) {
923 ; CHECK-LABEL: @test52b(
924 ; CHECK-NEXT: [[TMP1:%.*]] = and i128 [[X1:%.*]], 16711935
925 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i128 [[TMP1]], 4980863
926 ; CHECK-NEXT: ret i1 [[TMP2]]
928 %conv = and i128 %x1, 255
929 %cmp = icmp eq i128 %conv, 127
930 %i2 = lshr i128 %x1, 16
931 %i3 = trunc i128 %i2 to i8
932 %cmp15 = icmp eq i8 %i3, 76
934 %A = and i1 %cmp, %cmp15
938 define i1 @test52b_logical(i128 %x1) {
939 ; CHECK-LABEL: @test52b_logical(
940 ; CHECK-NEXT: [[TMP1:%.*]] = and i128 [[X1:%.*]], 16711935
941 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i128 [[TMP1]], 4980863
942 ; CHECK-NEXT: ret i1 [[TMP2]]
944 %conv = and i128 %x1, 255
945 %cmp = icmp eq i128 %conv, 127
946 %i2 = lshr i128 %x1, 16
947 %i3 = trunc i128 %i2 to i8
948 %cmp15 = icmp eq i8 %i3, 76
950 %A = select i1 %cmp, i1 %cmp15, i1 false
955 define i1 @test53(i32 %a, i32 %b) {
956 ; CHECK-LABEL: @test53(
957 ; CHECK-NEXT: [[X:%.*]] = sdiv exact i32 [[A:%.*]], 30
958 ; CHECK-NEXT: [[Y:%.*]] = sdiv i32 [[B:%.*]], 30
959 ; CHECK-NEXT: [[Z:%.*]] = icmp eq i32 [[X]], [[Y]]
960 ; CHECK-NEXT: ret i1 [[Z]]
962 %x = sdiv exact i32 %a, 30
964 %z = icmp eq i32 %x, %y
968 define i1 @test54(i8 %a) {
969 ; CHECK-LABEL: @test54(
970 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[A:%.*]], -64
971 ; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[TMP1]], -128
972 ; CHECK-NEXT: ret i1 [[RET]]
974 %ext = zext i8 %a to i32
975 %and = and i32 %ext, 192
976 %ret = icmp eq i32 %and, 128
980 define i1 @test55(i32 %a) {
981 ; CHECK-LABEL: @test55(
982 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -123
983 ; CHECK-NEXT: ret i1 [[CMP]]
986 %cmp = icmp eq i32 %sub, 123
990 define <2 x i1> @test55vec(<2 x i32> %a) {
991 ; CHECK-LABEL: @test55vec(
992 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 -123, i32 -123>
993 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
995 %sub = sub <2 x i32> zeroinitializer, %a
996 %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123>
1000 define i1 @test56(i32 %a) {
1001 ; CHECK-LABEL: @test56(
1002 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], -113
1003 ; CHECK-NEXT: ret i1 [[CMP]]
1005 %sub = sub i32 10, %a
1006 %cmp = icmp eq i32 %sub, 123
1010 define <2 x i1> @test56vec(<2 x i32> %a) {
1011 ; CHECK-LABEL: @test56vec(
1012 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 -113, i32 -113>
1013 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1015 %sub = sub <2 x i32> <i32 10, i32 10>, %a
1016 %cmp = icmp eq <2 x i32> %sub, <i32 123, i32 123>
1020 ; PR10267 Don't make icmps more expensive when no other inst is subsumed.
1021 declare void @foo(i32)
1022 define i1 @test57(i32 %a) {
1023 ; CHECK-LABEL: @test57(
1024 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], -2
1025 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1026 ; CHECK-NEXT: call void @foo(i32 [[AND]])
1027 ; CHECK-NEXT: ret i1 [[CMP]]
1029 %and = and i32 %a, -2
1030 %cmp = icmp ne i32 %and, 0
1031 call void @foo(i32 %and)
1035 ; rdar://problem/10482509
1036 define zeroext i1 @cmpabs1(i64 %val) {
1037 ; CHECK-LABEL: @cmpabs1(
1038 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0
1039 ; CHECK-NEXT: ret i1 [[TOBOOL]]
1041 %sub = sub nsw i64 0, %val
1042 %cmp = icmp slt i64 %val, 0
1043 %sub.val = select i1 %cmp, i64 %sub, i64 %val
1044 %tobool = icmp ne i64 %sub.val, 0
1048 define zeroext i1 @cmpabs2(i64 %val) {
1049 ; CHECK-LABEL: @cmpabs2(
1050 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[VAL:%.*]], 0
1051 ; CHECK-NEXT: ret i1 [[TOBOOL]]
1053 %sub = sub nsw i64 0, %val
1054 %cmp = icmp slt i64 %val, 0
1055 %sub.val = select i1 %cmp, i64 %val, i64 %sub
1056 %tobool = icmp ne i64 %sub.val, 0
1060 define i1 @abs_intrin_eq_zero(i8 %x) {
1061 ; CHECK-LABEL: @abs_intrin_eq_zero(
1062 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 0
1063 ; CHECK-NEXT: ret i1 [[CMP]]
1065 %abs = call i8 @llvm.abs.i8(i8 %x, i1 false)
1066 %cmp = icmp eq i8 %abs, 0
1070 define i1 @abs_intrin_ne_zero(i8 %x) {
1071 ; CHECK-LABEL: @abs_intrin_ne_zero(
1072 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[X:%.*]], 0
1073 ; CHECK-NEXT: ret i1 [[CMP]]
1075 %abs = call i8 @llvm.abs.i8(i8 %x, i1 false)
1076 %cmp = icmp ne i8 %abs, 0
1080 define void @test58() {
1081 ; CHECK-LABEL: @test58(
1082 ; CHECK-NEXT: [[CALL:%.*]] = call i32 @test58_d(i64 36029346783166592)
1083 ; CHECK-NEXT: ret void
1085 %cast = bitcast <1 x i64> <i64 36029346783166592> to i64
1086 %call = call i32 @test58_d( i64 %cast)
1089 declare i32 @test58_d(i64)
1091 ; Negative test: GEP inbounds may cross sign boundary.
1092 define i1 @test62(i8* %a) {
1093 ; CHECK-LABEL: @test62(
1094 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, i8* [[A:%.*]], i64 1
1095 ; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 10
1096 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8* [[ARRAYIDX1]], [[ARRAYIDX2]]
1097 ; CHECK-NEXT: ret i1 [[CMP]]
1099 %arrayidx1 = getelementptr inbounds i8, i8* %a, i64 1
1100 %arrayidx2 = getelementptr inbounds i8, i8* %a, i64 10
1101 %cmp = icmp slt i8* %arrayidx1, %arrayidx2
1105 define i1 @test62_as1(i8 addrspace(1)* %a) {
1106 ; CHECK-LABEL: @test62_as1(
1107 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[A:%.*]], i16 1
1108 ; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[A]], i16 10
1109 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 addrspace(1)* [[ARRAYIDX1]], [[ARRAYIDX2]]
1110 ; CHECK-NEXT: ret i1 [[CMP]]
1112 %arrayidx1 = getelementptr inbounds i8, i8 addrspace(1)* %a, i64 1
1113 %arrayidx2 = getelementptr inbounds i8, i8 addrspace(1)* %a, i64 10
1114 %cmp = icmp slt i8 addrspace(1)* %arrayidx1, %arrayidx2
1118 define i1 @test63(i8 %a, i32 %b) {
1119 ; CHECK-LABEL: @test63(
1120 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8
1121 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[TMP1]], [[A:%.*]]
1122 ; CHECK-NEXT: ret i1 [[C]]
1124 %z = zext i8 %a to i32
1125 %t = and i32 %b, 255
1126 %c = icmp eq i32 %z, %t
1130 define i1 @test64(i8 %a, i32 %b) {
1131 ; CHECK-LABEL: @test64(
1132 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B:%.*]] to i8
1133 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[TMP1]], [[A:%.*]]
1134 ; CHECK-NEXT: ret i1 [[C]]
1136 %t = and i32 %b, 255
1137 %z = zext i8 %a to i32
1138 %c = icmp eq i32 %t, %z
1142 define i1 @test65(i64 %A, i64 %B) {
1143 ; CHECK-LABEL: @test65(
1144 ; CHECK-NEXT: ret i1 true
1146 %s1 = add i64 %A, %B
1147 %s2 = add i64 %A, %B
1148 %cmp = icmp eq i64 %s1, %s2
1152 define i1 @test66(i64 %A, i64 %B) {
1153 ; CHECK-LABEL: @test66(
1154 ; CHECK-NEXT: ret i1 true
1156 %s1 = add i64 %A, %B
1157 %s2 = add i64 %B, %A
1158 %cmp = icmp eq i64 %s1, %s2
1162 define i1 @test67(i32 %x) {
1163 ; CHECK-LABEL: @test67(
1164 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 96
1165 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0
1166 ; CHECK-NEXT: ret i1 [[CMP]]
1168 %and = and i32 %x, 127
1169 %cmp = icmp sgt i32 %and, 31
1173 define i1 @test67inverse(i32 %x) {
1174 ; CHECK-LABEL: @test67inverse(
1175 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 96
1176 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
1177 ; CHECK-NEXT: ret i1 [[CMP]]
1179 %and = and i32 %x, 127
1180 %cmp = icmp sle i32 %and, 31
1184 ; The test above relies on 3 different folds.
1185 ; This test only checks the last of those (icmp ugt -> icmp ne).
1187 define <2 x i1> @test67vec(<2 x i32> %x) {
1188 ; CHECK-LABEL: @test67vec(
1189 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96>
1190 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer
1191 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1193 %and = and <2 x i32> %x, <i32 96, i32 96>
1194 %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31>
1198 define <2 x i1> @test67vec2(<2 x i32> %x) {
1199 ; CHECK-LABEL: @test67vec2(
1200 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96>
1201 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer
1202 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1204 %and = and <2 x i32> %x, <i32 127, i32 127>
1205 %cmp = icmp ugt <2 x i32> %and, <i32 31, i32 31>
1209 define <2 x i1> @test67vecinverse(<2 x i32> %x) {
1210 ; CHECK-LABEL: @test67vecinverse(
1211 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 96, i32 96>
1212 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], zeroinitializer
1213 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1215 %and = and <2 x i32> %x, <i32 96, i32 96>
1216 %cmp = icmp sle <2 x i32> %and, <i32 31, i32 31>
1220 define i1 @test68(i32 %x) {
1221 ; CHECK-LABEL: @test68(
1222 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 127
1223 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[AND]], 30
1224 ; CHECK-NEXT: ret i1 [[CMP]]
1226 %and = and i32 %x, 127
1227 %cmp = icmp sgt i32 %and, 30
1232 define i1 @test70(i32 %X) {
1233 ; CHECK-LABEL: @test70(
1234 ; CHECK-NEXT: [[A:%.*]] = srem i32 5, [[X:%.*]]
1235 ; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[A]], 2
1236 ; CHECK-NEXT: ret i1 [[C]]
1240 %C = icmp ne i32 %B, 4
1244 define <2 x i1> @test70vec(<2 x i32> %X) {
1245 ; CHECK-LABEL: @test70vec(
1246 ; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 2, i32 2>
1247 ; CHECK-NEXT: ret <2 x i1> [[C]]
1249 %B = add <2 x i32> %X, <i32 2, i32 2>
1250 %C = icmp ne <2 x i32> %B, <i32 4, i32 4>
1254 define i1 @icmp_sext16trunc(i32 %x) {
1255 ; CHECK-LABEL: @icmp_sext16trunc(
1256 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
1257 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36
1258 ; CHECK-NEXT: ret i1 [[CMP]]
1260 %trunc = trunc i32 %x to i16
1261 %sext = sext i16 %trunc to i32
1262 %cmp = icmp slt i32 %sext, 36
1266 define i1 @icmp_sext8trunc(i32 %x) {
1267 ; CHECK-LABEL: @icmp_sext8trunc(
1268 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
1269 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36
1270 ; CHECK-NEXT: ret i1 [[CMP]]
1272 %trunc = trunc i32 %x to i8
1273 %sext = sext i8 %trunc to i32
1274 %cmp = icmp slt i32 %sext, 36
1278 ; Vectors should fold the same way.
1279 define <2 x i1> @icmp_sext8trunc_vec(<2 x i32> %x) {
1280 ; CHECK-LABEL: @icmp_sext8trunc_vec(
1281 ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8>
1282 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[TMP1]], <i8 36, i8 36>
1283 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1285 %trunc = trunc <2 x i32> %x to <2 x i8>
1286 %sext = sext <2 x i8> %trunc to <2 x i32>
1287 %cmp = icmp slt <2 x i32> %sext, <i32 36, i32 36>
1291 define i1 @icmp_shl16(i32 %x) {
1292 ; CHECK-LABEL: @icmp_shl16(
1293 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
1294 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[TMP1]], 36
1295 ; CHECK-NEXT: ret i1 [[CMP]]
1297 %shl = shl i32 %x, 16
1298 %cmp = icmp slt i32 %shl, 2359296
1302 ; D25952: Don't create illegal types like i15 in InstCombine
1304 define i1 @icmp_shl17(i32 %x) {
1305 ; CHECK-LABEL: @icmp_shl17(
1306 ; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], 17
1307 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[SHL]], 2359296
1308 ; CHECK-NEXT: ret i1 [[CMP]]
1310 %shl = shl i32 %x, 17
1311 %cmp = icmp slt i32 %shl, 2359296
1315 define <2 x i1> @icmp_shl16_vec(<2 x i32> %x) {
1316 ; CHECK-LABEL: @icmp_shl16_vec(
1317 ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i16>
1318 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i16> [[TMP1]], <i16 36, i16 36>
1319 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1321 %shl = shl <2 x i32> %x, <i32 16, i32 16>
1322 %cmp = icmp slt <2 x i32> %shl, <i32 2359296, i32 2359296>
1326 define i1 @icmp_shl24(i32 %x) {
1327 ; CHECK-LABEL: @icmp_shl24(
1328 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
1329 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], 36
1330 ; CHECK-NEXT: ret i1 [[CMP]]
1332 %shl = shl i32 %x, 24
1333 %cmp = icmp slt i32 %shl, 603979776
1337 define i1 @icmp_shl_eq(i32 %x) {
1338 ; CHECK-LABEL: @icmp_shl_eq(
1339 ; CHECK-NEXT: [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 134217727
1340 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MUL_MASK]], 0
1341 ; CHECK-NEXT: ret i1 [[CMP]]
1343 %mul = shl i32 %x, 5
1344 %cmp = icmp eq i32 %mul, 0
1348 define <2 x i1> @icmp_shl_eq_vec(<2 x i32> %x) {
1349 ; CHECK-LABEL: @icmp_shl_eq_vec(
1350 ; CHECK-NEXT: [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], <i32 134217727, i32 134217727>
1351 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[MUL_MASK]], zeroinitializer
1352 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1354 %mul = shl <2 x i32> %x, <i32 5, i32 5>
1355 %cmp = icmp eq <2 x i32> %mul, zeroinitializer
1359 define i1 @icmp_shl_nsw_ne(i32 %x) {
1360 ; CHECK-LABEL: @icmp_shl_nsw_ne(
1361 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0
1362 ; CHECK-NEXT: ret i1 [[CMP]]
1364 %mul = shl nsw i32 %x, 7
1365 %cmp = icmp ne i32 %mul, 0
1369 define <2 x i1> @icmp_shl_nsw_ne_vec(<2 x i32> %x) {
1370 ; CHECK-LABEL: @icmp_shl_nsw_ne_vec(
1371 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
1372 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1374 %mul = shl nsw <2 x i32> %x, <i32 7, i32 7>
1375 %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1379 define i1 @icmp_shl_ne(i32 %x) {
1380 ; CHECK-LABEL: @icmp_shl_ne(
1381 ; CHECK-NEXT: [[MUL_MASK:%.*]] = and i32 [[X:%.*]], 33554431
1382 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MUL_MASK]], 0
1383 ; CHECK-NEXT: ret i1 [[CMP]]
1385 %mul = shl i32 %x, 7
1386 %cmp = icmp ne i32 %mul, 0
1390 define <2 x i1> @icmp_shl_ne_vec(<2 x i32> %x) {
1391 ; CHECK-LABEL: @icmp_shl_ne_vec(
1392 ; CHECK-NEXT: [[MUL_MASK:%.*]] = and <2 x i32> [[X:%.*]], <i32 33554431, i32 33554431>
1393 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[MUL_MASK]], zeroinitializer
1394 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1396 %mul = shl <2 x i32> %x, <i32 7, i32 7>
1397 %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1401 define <2 x i1> @icmp_shl_nuw_ne_vec(<2 x i32> %x) {
1402 ; CHECK-LABEL: @icmp_shl_nuw_ne_vec(
1403 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 2, i32 2>
1404 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1406 %shl = shl nuw <2 x i32> %x, <i32 7, i32 7>
1407 %cmp = icmp ne <2 x i32> %shl, <i32 256, i32 256>
1411 ; If the (mul x, C) preserved the sign and this is sign test,
1412 ; compare the LHS operand instead
1413 define i1 @icmp_mul_nsw(i32 %x) {
1414 ; CHECK-LABEL: @icmp_mul_nsw(
1415 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 0
1416 ; CHECK-NEXT: ret i1 [[CMP]]
1418 %mul = mul nsw i32 %x, 12
1419 %cmp = icmp sgt i32 %mul, 0
1423 define i1 @icmp_mul_nsw1(i32 %x) {
1424 ; CHECK-LABEL: @icmp_mul_nsw1(
1425 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
1426 ; CHECK-NEXT: ret i1 [[CMP]]
1428 %mul = mul nsw i32 %x, 12
1429 %cmp = icmp sle i32 %mul, -1
1433 define i1 @icmp_mul_nsw_neg(i32 %x) {
1434 ; CHECK-LABEL: @icmp_mul_nsw_neg(
1435 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
1436 ; CHECK-NEXT: ret i1 [[CMP]]
1438 %mul = mul nsw i32 %x, -12
1439 %cmp = icmp sge i32 %mul, 0
1443 define i1 @icmp_mul_nsw_neg1(i32 %x) {
1444 ; CHECK-LABEL: @icmp_mul_nsw_neg1(
1445 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
1446 ; CHECK-NEXT: ret i1 [[CMP]]
1448 %mul = mul nsw i32 %x, -12
1449 %cmp = icmp sge i32 %mul, 1
1453 define <2 x i1> @icmp_mul_nsw_neg1_vec(<2 x i32> %x) {
1454 ; CHECK-LABEL: @icmp_mul_nsw_neg1_vec(
1455 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer
1456 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1458 %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12>
1459 %cmp = icmp sge <2 x i32> %mul, <i32 1, i32 1>
1463 define i1 @icmp_mul_nsw_0(i32 %x) {
1464 ; CHECK-LABEL: @icmp_mul_nsw_0(
1465 ; CHECK-NEXT: ret i1 false
1467 %mul = mul nsw i32 %x, 0
1468 %cmp = icmp sgt i32 %mul, 0
1472 define i1 @icmp_mul(i32 %x) {
1473 ; CHECK-LABEL: @icmp_mul(
1474 ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[X:%.*]], -12
1475 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[MUL]], -1
1476 ; CHECK-NEXT: ret i1 [[CMP]]
1478 %mul = mul i32 %x, -12
1479 %cmp = icmp sge i32 %mul, 0
1483 ; Checks for icmp (eq|ne) (mul x, C), 0
1484 define i1 @icmp_mul_neq0(i32 %x) {
1485 ; CHECK-LABEL: @icmp_mul_neq0(
1486 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0
1487 ; CHECK-NEXT: ret i1 [[CMP]]
1489 %mul = mul nsw i32 %x, -12
1490 %cmp = icmp ne i32 %mul, 0
1494 define <2 x i1> @icmp_mul_neq0_vec(<2 x i32> %x) {
1495 ; CHECK-LABEL: @icmp_mul_neq0_vec(
1496 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
1497 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1499 %mul = mul nsw <2 x i32> %x, <i32 -12, i32 -12>
1500 %cmp = icmp ne <2 x i32> %mul, zeroinitializer
1504 define i1 @icmp_mul_eq0(i32 %x) {
1505 ; CHECK-LABEL: @icmp_mul_eq0(
1506 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
1507 ; CHECK-NEXT: ret i1 [[CMP]]
1509 %mul = mul nsw i32 %x, 12
1510 %cmp = icmp eq i32 %mul, 0
1514 define i1 @icmp_mul0_eq0(i32 %x) {
1515 ; CHECK-LABEL: @icmp_mul0_eq0(
1516 ; CHECK-NEXT: ret i1 true
1518 %mul = mul i32 %x, 0
1519 %cmp = icmp eq i32 %mul, 0
1523 define i1 @icmp_mul0_ne0(i32 %x) {
1524 ; CHECK-LABEL: @icmp_mul0_ne0(
1525 ; CHECK-NEXT: ret i1 false
1527 %mul = mul i32 %x, 0
1528 %cmp = icmp ne i32 %mul, 0
1532 define i1 @icmp_sub1_sge(i32 %x, i32 %y) {
1533 ; CHECK-LABEL: @icmp_sub1_sge(
1534 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
1535 ; CHECK-NEXT: ret i1 [[CMP]]
1537 %sub = add nsw i32 %x, -1
1538 %cmp = icmp sge i32 %sub, %y
1542 define i1 @icmp_add1_sgt(i32 %x, i32 %y) {
1543 ; CHECK-LABEL: @icmp_add1_sgt(
1544 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[X:%.*]], [[Y:%.*]]
1545 ; CHECK-NEXT: ret i1 [[CMP]]
1547 %add = add nsw i32 %x, 1
1548 %cmp = icmp sgt i32 %add, %y
1552 define i1 @icmp_sub1_slt(i32 %x, i32 %y) {
1553 ; CHECK-LABEL: @icmp_sub1_slt(
1554 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]]
1555 ; CHECK-NEXT: ret i1 [[CMP]]
1557 %sub = add nsw i32 %x, -1
1558 %cmp = icmp slt i32 %sub, %y
1562 define i1 @icmp_add1_sle(i32 %x, i32 %y) {
1563 ; CHECK-LABEL: @icmp_add1_sle(
1564 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
1565 ; CHECK-NEXT: ret i1 [[CMP]]
1567 %add = add nsw i32 %x, 1
1568 %cmp = icmp sle i32 %add, %y
1572 define i1 @icmp_add20_sge_add57(i32 %x, i32 %y) {
1573 ; CHECK-LABEL: @icmp_add20_sge_add57(
1574 ; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[Y:%.*]], 37
1575 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[X:%.*]]
1576 ; CHECK-NEXT: ret i1 [[CMP]]
1578 %1 = add nsw i32 %x, 20
1579 %2 = add nsw i32 %y, 57
1580 %cmp = icmp sge i32 %1, %2
1584 define i1 @icmp_sub57_sge_sub20(i32 %x, i32 %y) {
1585 ; CHECK-LABEL: @icmp_sub57_sge_sub20(
1586 ; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[X:%.*]], -37
1587 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[TMP1]], [[Y:%.*]]
1588 ; CHECK-NEXT: ret i1 [[CMP]]
1590 %1 = add nsw i32 %x, -57
1591 %2 = add nsw i32 %y, -20
1592 %cmp = icmp sge i32 %1, %2
1596 define i1 @icmp_and_shl_neg_ne_0(i32 %A, i32 %B) {
1597 ; CHECK-LABEL: @icmp_and_shl_neg_ne_0(
1598 ; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[B:%.*]]
1599 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
1600 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
1601 ; CHECK-NEXT: ret i1 [[CMP]]
1603 %neg = xor i32 %A, -1
1604 %shl = shl i32 1, %B
1605 %and = and i32 %shl, %neg
1606 %cmp = icmp ne i32 %and, 0
1610 define i1 @icmp_and_shl_neg_eq_0(i32 %A, i32 %B) {
1611 ; CHECK-LABEL: @icmp_and_shl_neg_eq_0(
1612 ; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[B:%.*]]
1613 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SHL]], [[A:%.*]]
1614 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 0
1615 ; CHECK-NEXT: ret i1 [[CMP]]
1617 %neg = xor i32 %A, -1
1618 %shl = shl i32 1, %B
1619 %and = and i32 %shl, %neg
1620 %cmp = icmp eq i32 %and, 0
1624 define i1 @icmp_add_and_shr_ne_0(i32 %X) {
1625 ; CHECK-LABEL: @icmp_add_and_shr_ne_0(
1626 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240
1627 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
1628 ; CHECK-NEXT: ret i1 [[TOBOOL]]
1630 %shr = lshr i32 %X, 4
1631 %and = and i32 %shr, 15
1632 %add = add i32 %and, -14
1633 %tobool = icmp ne i32 %add, 0
1637 define <2 x i1> @icmp_add_and_shr_ne_0_vec(<2 x i32> %X) {
1638 ; CHECK-LABEL: @icmp_add_and_shr_ne_0_vec(
1639 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 240, i32 240>
1640 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 224, i32 224>
1641 ; CHECK-NEXT: ret <2 x i1> [[TOBOOL]]
1643 %shr = lshr <2 x i32> %X, <i32 4, i32 4>
1644 %and = and <2 x i32> %shr, <i32 15, i32 15>
1645 %add = add <2 x i32> %and, <i32 -14, i32 -14>
1646 %tobool = icmp ne <2 x i32> %add, zeroinitializer
1647 ret <2 x i1> %tobool
1650 ; Variation of the above with an extra use of the shift
1651 define i1 @icmp_and_shr_multiuse(i32 %X) {
1652 ; CHECK-LABEL: @icmp_and_shr_multiuse(
1653 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240
1654 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
1655 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 496
1656 ; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
1657 ; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
1658 ; CHECK-NEXT: ret i1 [[AND3]]
1660 %shr = lshr i32 %X, 4
1661 %and = and i32 %shr, 15
1662 %and2 = and i32 %shr, 31 ; second use of the shift
1663 %tobool = icmp ne i32 %and, 14
1664 %tobool2 = icmp ne i32 %and2, 27
1665 %and3 = and i1 %tobool, %tobool2
1669 define i1 @icmp_and_shr_multiuse_logical(i32 %X) {
1670 ; CHECK-LABEL: @icmp_and_shr_multiuse_logical(
1671 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240
1672 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
1673 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 496
1674 ; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
1675 ; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
1676 ; CHECK-NEXT: ret i1 [[AND3]]
1678 %shr = lshr i32 %X, 4
1679 %and = and i32 %shr, 15
1680 %and2 = and i32 %shr, 31 ; second use of the shift
1681 %tobool = icmp ne i32 %and, 14
1682 %tobool2 = icmp ne i32 %and2, 27
1683 %and3 = select i1 %tobool, i1 %tobool2, i1 false
1687 ; Variation of the above with an ashr
1688 define i1 @icmp_and_ashr_multiuse(i32 %X) {
1689 ; CHECK-LABEL: @icmp_and_ashr_multiuse(
1690 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240
1691 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
1692 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 496
1693 ; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
1694 ; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
1695 ; CHECK-NEXT: ret i1 [[AND3]]
1697 %shr = ashr i32 %X, 4
1698 %and = and i32 %shr, 15
1699 %and2 = and i32 %shr, 31 ; second use of the shift
1700 %tobool = icmp ne i32 %and, 14
1701 %tobool2 = icmp ne i32 %and2, 27
1702 %and3 = and i1 %tobool, %tobool2
1706 define i1 @icmp_and_ashr_multiuse_logical(i32 %X) {
1707 ; CHECK-LABEL: @icmp_and_ashr_multiuse_logical(
1708 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 240
1709 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
1710 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], 496
1711 ; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
1712 ; CHECK-NEXT: [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
1713 ; CHECK-NEXT: ret i1 [[AND3]]
1715 %shr = ashr i32 %X, 4
1716 %and = and i32 %shr, 15
1717 %and2 = and i32 %shr, 31 ; second use of the shift
1718 %tobool = icmp ne i32 %and, 14
1719 %tobool2 = icmp ne i32 %and2, 27
1720 %and3 = select i1 %tobool, i1 %tobool2, i1 false
1724 define i1 @icmp_lshr_and_overshift(i8 %X) {
1725 ; CHECK-LABEL: @icmp_lshr_and_overshift(
1726 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ugt i8 [[X:%.*]], 31
1727 ; CHECK-NEXT: ret i1 [[TOBOOL]]
1729 %shr = lshr i8 %X, 5
1730 %and = and i8 %shr, 15
1731 %tobool = icmp ne i8 %and, 0
1735 ; We shouldn't simplify this because the and uses bits that are shifted in.
1736 define i1 @icmp_ashr_and_overshift(i8 %X) {
1737 ; CHECK-LABEL: @icmp_ashr_and_overshift(
1738 ; CHECK-NEXT: [[SHR:%.*]] = ashr i8 [[X:%.*]], 5
1739 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[SHR]], 15
1740 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8 [[AND]], 0
1741 ; CHECK-NEXT: ret i1 [[TOBOOL]]
1743 %shr = ashr i8 %X, 5
1744 %and = and i8 %shr, 15
1745 %tobool = icmp ne i8 %and, 0
1749 define i1 @icmp_and_ashr_neg_and_legal(i8 %x) {
1750 ; CHECK-LABEL: @icmp_and_ashr_neg_and_legal(
1751 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -32
1752 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], 16
1753 ; CHECK-NEXT: ret i1 [[CMP]]
1755 %ashr = ashr i8 %x, 4
1756 %and = and i8 %ashr, -2
1757 %cmp = icmp slt i8 %and, 1
1762 define i1 @icmp_and_ashr_mixed_and_shiftout(i8 %x) {
1763 ; CHECK-LABEL: @icmp_and_ashr_mixed_and_shiftout(
1764 ; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X:%.*]], 4
1765 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[ASHR]], 31
1766 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[AND]], 8
1767 ; CHECK-NEXT: ret i1 [[CMP]]
1769 %ashr = ashr i8 %x, 4
1770 %and = and i8 %ashr, 31
1771 %cmp = icmp ugt i8 %and, 8
1775 define i1 @icmp_and_ashr_neg_cmp_slt_legal(i8 %x) {
1776 ; CHECK-LABEL: @icmp_and_ashr_neg_cmp_slt_legal(
1777 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -32
1778 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[TMP1]], -64
1779 ; CHECK-NEXT: ret i1 [[CMP]]
1781 %ashr = ashr i8 %x, 4
1782 %and = and i8 %ashr, -2
1783 %cmp = icmp slt i8 %and, -4
1788 define i1 @icmp_and_ashr_neg_cmp_slt_shiftout(i8 %x) {
1789 ; CHECK-LABEL: @icmp_and_ashr_neg_cmp_slt_shiftout(
1790 ; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X:%.*]], 4
1791 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[ASHR]], -2
1792 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[AND]], -68
1793 ; CHECK-NEXT: ret i1 [[CMP]]
1795 %ashr = ashr i8 %x, 4
1796 %and = and i8 %ashr, -2
1797 %cmp = icmp slt i8 %and, -68
1801 define i1 @icmp_and_ashr_neg_cmp_eq_legal(i8 %x) {
1802 ; CHECK-LABEL: @icmp_and_ashr_neg_cmp_eq_legal(
1803 ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -32
1804 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], -64
1805 ; CHECK-NEXT: ret i1 [[CMP]]
1807 %ashr = ashr i8 %x, 4
1808 %and = and i8 %ashr, -2
1809 %cmp = icmp eq i8 %and, -4
1813 define i1 @icmp_and_ashr_neg_cmp_eq_shiftout(i8 %x) {
1814 ; CHECK-LABEL: @icmp_and_ashr_neg_cmp_eq_shiftout(
1815 ; CHECK-NEXT: ret i1 false
1817 %ashr = ashr i8 %x, 4
1818 %and = and i8 %ashr, -2
1819 %cmp = icmp eq i8 %and, -68
1823 define i1 @icmp_and_ashr_neg_cmp_ne_shiftout(i8 %x) {
1824 ; CHECK-LABEL: @icmp_and_ashr_neg_cmp_ne_shiftout(
1825 ; CHECK-NEXT: ret i1 true
1827 %ashr = ashr i8 %x, 4
1828 %and = and i8 %ashr, -2
1829 %cmp = icmp ne i8 %and, -68
1833 define i1 @icmp_shl_1_V_ult_32(i32 %V) {
1834 ; CHECK-LABEL: @icmp_shl_1_V_ult_32(
1835 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
1836 ; CHECK-NEXT: ret i1 [[CMP]]
1838 %shl = shl i32 1, %V
1839 %cmp = icmp ult i32 %shl, 32
1843 define <2 x i1> @icmp_shl_1_V_ult_32_vec(<2 x i32> %V) {
1844 ; CHECK-LABEL: @icmp_shl_1_V_ult_32_vec(
1845 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5>
1846 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1848 %shl = shl <2 x i32> <i32 1, i32 1>, %V
1849 %cmp = icmp ult <2 x i32> %shl, <i32 32, i32 32>
1853 define i1 @icmp_shl_1_V_eq_32(i32 %V) {
1854 ; CHECK-LABEL: @icmp_shl_1_V_eq_32(
1855 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 5
1856 ; CHECK-NEXT: ret i1 [[CMP]]
1858 %shl = shl i32 1, %V
1859 %cmp = icmp eq i32 %shl, 32
1863 define <2 x i1> @icmp_shl_1_V_eq_32_vec(<2 x i32> %V) {
1864 ; CHECK-LABEL: @icmp_shl_1_V_eq_32_vec(
1865 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], <i32 5, i32 5>
1866 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1868 %shl = shl <2 x i32> <i32 1, i32 1>, %V
1869 %cmp = icmp eq <2 x i32> %shl, <i32 32, i32 32>
1873 define i1 @icmp_shl_1_V_ult_30(i32 %V) {
1874 ; CHECK-LABEL: @icmp_shl_1_V_ult_30(
1875 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
1876 ; CHECK-NEXT: ret i1 [[CMP]]
1878 %shl = shl i32 1, %V
1879 %cmp = icmp ult i32 %shl, 30
1883 define <2 x i1> @icmp_shl_1_V_ult_30_vec(<2 x i32> %V) {
1884 ; CHECK-LABEL: @icmp_shl_1_V_ult_30_vec(
1885 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5>
1886 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1888 %shl = shl <2 x i32> <i32 1, i32 1>, %V
1889 %cmp = icmp ult <2 x i32> %shl, <i32 30, i32 30>
1893 define i1 @icmp_shl_1_V_ugt_30(i32 %V) {
1894 ; CHECK-LABEL: @icmp_shl_1_V_ugt_30(
1895 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4
1896 ; CHECK-NEXT: ret i1 [[CMP]]
1898 %shl = shl i32 1, %V
1899 %cmp = icmp ugt i32 %shl, 30
1903 define <2 x i1> @icmp_shl_1_V_ugt_30_vec(<2 x i32> %V) {
1904 ; CHECK-LABEL: @icmp_shl_1_V_ugt_30_vec(
1905 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], <i32 4, i32 4>
1906 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1908 %shl = shl <2 x i32> <i32 1, i32 1>, %V
1909 %cmp = icmp ugt <2 x i32> %shl, <i32 30, i32 30>
1913 define i1 @icmp_shl_1_V_ule_30(i32 %V) {
1914 ; CHECK-LABEL: @icmp_shl_1_V_ule_30(
1915 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[V:%.*]], 5
1916 ; CHECK-NEXT: ret i1 [[CMP]]
1918 %shl = shl i32 1, %V
1919 %cmp = icmp ule i32 %shl, 30
1923 define <2 x i1> @icmp_shl_1_V_ule_30_vec(<2 x i32> %V) {
1924 ; CHECK-LABEL: @icmp_shl_1_V_ule_30_vec(
1925 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[V:%.*]], <i32 5, i32 5>
1926 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1928 %shl = shl <2 x i32> <i32 1, i32 1>, %V
1929 %cmp = icmp ule <2 x i32> %shl, <i32 30, i32 30>
1933 define i1 @icmp_shl_1_V_uge_30(i32 %V) {
1934 ; CHECK-LABEL: @icmp_shl_1_V_uge_30(
1935 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[V:%.*]], 4
1936 ; CHECK-NEXT: ret i1 [[CMP]]
1938 %shl = shl i32 1, %V
1939 %cmp = icmp uge i32 %shl, 30
1943 define <2 x i1> @icmp_shl_1_V_uge_30_vec(<2 x i32> %V) {
1944 ; CHECK-LABEL: @icmp_shl_1_V_uge_30_vec(
1945 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[V:%.*]], <i32 4, i32 4>
1946 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1948 %shl = shl <2 x i32> <i32 1, i32 1>, %V
1949 %cmp = icmp uge <2 x i32> %shl, <i32 30, i32 30>
1953 define i1 @icmp_shl_1_V_uge_2147483648(i32 %V) {
1954 ; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648(
1955 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V:%.*]], 31
1956 ; CHECK-NEXT: ret i1 [[CMP]]
1958 %shl = shl i32 1, %V
1959 %cmp = icmp uge i32 %shl, 2147483648
1963 define <2 x i1> @icmp_shl_1_V_uge_2147483648_vec(<2 x i32> %V) {
1964 ; CHECK-LABEL: @icmp_shl_1_V_uge_2147483648_vec(
1965 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[V:%.*]], <i32 31, i32 31>
1966 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1968 %shl = shl <2 x i32> <i32 1, i32 1>, %V
1969 %cmp = icmp uge <2 x i32> %shl, <i32 2147483648, i32 2147483648>
1973 define i1 @icmp_shl_1_V_ult_2147483648(i32 %V) {
1974 ; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648(
1975 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[V:%.*]], 31
1976 ; CHECK-NEXT: ret i1 [[CMP]]
1978 %shl = shl i32 1, %V
1979 %cmp = icmp ult i32 %shl, 2147483648
1983 define <2 x i1> @icmp_shl_1_V_ult_2147483648_vec(<2 x i32> %V) {
1984 ; CHECK-LABEL: @icmp_shl_1_V_ult_2147483648_vec(
1985 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[V:%.*]], <i32 31, i32 31>
1986 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
1988 %shl = shl <2 x i32> <i32 1, i32 1>, %V
1989 %cmp = icmp ult <2 x i32> %shl, <i32 2147483648, i32 2147483648>
1993 define i1 @or_icmp_eq_B_0_icmp_ult_A_B(i64 %a, i64 %b) {
1994 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B(
1995 ; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[B:%.*]], -1
1996 ; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[TMP1]], [[A:%.*]]
1997 ; CHECK-NEXT: ret i1 [[TMP2]]
1999 %1 = icmp eq i64 %b, 0
2000 %2 = icmp ult i64 %a, %b
2005 define i1 @or_icmp_eq_B_0_icmp_ult_A_B_logical(i64 %a, i64 %b) {
2006 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_logical(
2007 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[B:%.*]], 0
2008 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[A:%.*]], [[B]]
2009 ; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i1 true, i1 [[TMP2]]
2010 ; CHECK-NEXT: ret i1 [[TMP3]]
2012 %1 = icmp eq i64 %b, 0
2013 %2 = icmp ult i64 %a, %b
2014 %3 = select i1 %1, i1 true, i1 %2
2018 define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_uniform(<2 x i64> %a, <2 x i64> %b) {
2019 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_uniform(
2020 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], <i64 -1, i64 -1>
2021 ; CHECK-NEXT: [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], [[A:%.*]]
2022 ; CHECK-NEXT: ret <2 x i1> [[TMP2]]
2024 %1 = icmp eq <2 x i64> %b, zeroinitializer
2025 %2 = icmp ult <2 x i64> %a, %b
2026 %3 = or <2 x i1> %1, %2
2030 define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_undef(<2 x i64> %a, <2 x i64> %b) {
2031 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_undef(
2032 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], <i64 -1, i64 -1>
2033 ; CHECK-NEXT: [[TMP2:%.*]] = icmp uge <2 x i64> [[TMP1]], [[A:%.*]]
2034 ; CHECK-NEXT: ret <2 x i1> [[TMP2]]
2036 %1 = icmp eq <2 x i64> %b, <i64 0, i64 undef>
2037 %2 = icmp ult <2 x i64> %a, %b
2038 %3 = or <2 x i1> %1, %2
2042 define i1 @or_icmp_ne_A_0_icmp_ne_B_0(i64 %a, i64 %b) {
2043 ; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0(
2044 ; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[A:%.*]], [[B:%.*]]
2045 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i64 [[TMP1]], 0
2046 ; CHECK-NEXT: ret i1 [[TMP2]]
2048 %1 = icmp ne i64 %a, 0
2049 %2 = icmp ne i64 %b, 0
2054 define i1 @or_icmp_ne_A_0_icmp_ne_B_0_logical(i64 %a, i64 %b) {
2055 ; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_logical(
2056 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[A:%.*]], 0
2057 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i64 [[B:%.*]], 0
2058 ; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i1 true, i1 [[TMP2]]
2059 ; CHECK-NEXT: ret i1 [[TMP3]]
2061 %1 = icmp ne i64 %a, 0
2062 %2 = icmp ne i64 %b, 0
2063 %3 = select i1 %1, i1 true, i1 %2
2067 define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_uniform(<2 x i64> %a, <2 x i64> %b) {
2068 ; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_uniform(
2069 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i64> [[A:%.*]], [[B:%.*]]
2070 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer
2071 ; CHECK-NEXT: ret <2 x i1> [[TMP2]]
2073 %1 = icmp ne <2 x i64> %a, zeroinitializer
2074 %2 = icmp ne <2 x i64> %b, zeroinitializer
2075 %3 = or <2 x i1> %1, %2
2079 define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_undef(<2 x i64> %a, <2 x i64> %b) {
2080 ; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_undef(
2081 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i64> [[A:%.*]], [[B:%.*]]
2082 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer
2083 ; CHECK-NEXT: ret <2 x i1> [[TMP2]]
2085 %1 = icmp ne <2 x i64> %a, <i64 0, i64 undef>
2086 %2 = icmp ne <2 x i64> %b, <i64 0, i64 undef>
2087 %3 = or <2 x i1> %1, %2
2091 define i1 @icmp_add_ult_2(i32 %X) {
2092 ; CHECK-LABEL: @icmp_add_ult_2(
2093 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2094 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 14
2095 ; CHECK-NEXT: ret i1 [[CMP]]
2097 %add = add i32 %X, -14
2098 %cmp = icmp ult i32 %add, 2
2102 define <2 x i1> @icmp_add_X_-14_ult_2_vec(<2 x i32> %X) {
2103 ; CHECK-LABEL: @icmp_add_X_-14_ult_2_vec(
2104 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2>
2105 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 14, i32 14>
2106 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2108 %add = add <2 x i32> %X, <i32 -14, i32 -14>
2109 %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2>
2113 define i1 @icmp_sub_3_X_ult_2(i32 %X) {
2114 ; CHECK-LABEL: @icmp_sub_3_X_ult_2(
2115 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2116 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 2
2117 ; CHECK-NEXT: ret i1 [[CMP]]
2119 %add = sub i32 3, %X
2120 %cmp = icmp ult i32 %add, 2
2124 define <2 x i1> @icmp_sub_3_X_ult_2_vec(<2 x i32> %X) {
2125 ; CHECK-LABEL: @icmp_sub_3_X_ult_2_vec(
2126 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2>
2127 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 2, i32 2>
2128 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2130 %add = sub <2 x i32> <i32 3, i32 3>, %X
2131 %cmp = icmp ult <2 x i32> %add, <i32 2, i32 2>
2135 define i1 @icmp_add_X_-14_uge_2(i32 %X) {
2136 ; CHECK-LABEL: @icmp_add_X_-14_uge_2(
2137 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2138 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 14
2139 ; CHECK-NEXT: ret i1 [[CMP]]
2141 %add = add i32 %X, -14
2142 %cmp = icmp uge i32 %add, 2
2146 define <2 x i1> @icmp_add_X_-14_uge_2_vec(<2 x i32> %X) {
2147 ; CHECK-LABEL: @icmp_add_X_-14_uge_2_vec(
2148 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2>
2149 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 14, i32 14>
2150 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2152 %add = add <2 x i32> %X, <i32 -14, i32 -14>
2153 %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2>
2157 define i1 @icmp_sub_3_X_uge_2(i32 %X) {
2158 ; CHECK-LABEL: @icmp_sub_3_X_uge_2(
2159 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2
2160 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 2
2161 ; CHECK-NEXT: ret i1 [[CMP]]
2163 %add = sub i32 3, %X
2164 %cmp = icmp uge i32 %add, 2
2168 define <2 x i1> @icmp_sub_3_X_uge_2_vec(<2 x i32> %X) {
2169 ; CHECK-LABEL: @icmp_sub_3_X_uge_2_vec(
2170 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -2, i32 -2>
2171 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], <i32 2, i32 2>
2172 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2174 %add = sub <2 x i32> <i32 3, i32 3>, %X
2175 %cmp = icmp uge <2 x i32> %add, <i32 2, i32 2>
2179 define i1 @icmp_and_X_-16_eq-16(i32 %X) {
2180 ; CHECK-LABEL: @icmp_and_X_-16_eq-16(
2181 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -17
2182 ; CHECK-NEXT: ret i1 [[CMP]]
2184 %and = and i32 %X, -16
2185 %cmp = icmp eq i32 %and, -16
2189 define <2 x i1> @icmp_and_X_-16_eq-16_vec(<2 x i32> %X) {
2190 ; CHECK-LABEL: @icmp_and_X_-16_eq-16_vec(
2191 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 -17, i32 -17>
2192 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2194 %and = and <2 x i32> %X, <i32 -16, i32 -16>
2195 %cmp = icmp eq <2 x i32> %and, <i32 -16, i32 -16>
2199 define i1 @icmp_and_X_-16_ne-16(i32 %X) {
2200 ; CHECK-LABEL: @icmp_and_X_-16_ne-16(
2201 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -16
2202 ; CHECK-NEXT: ret i1 [[CMP]]
2204 %and = and i32 %X, -16
2205 %cmp = icmp ne i32 %and, -16
2209 define <2 x i1> @icmp_and_X_-16_ne-16_vec(<2 x i32> %X) {
2210 ; CHECK-LABEL: @icmp_and_X_-16_ne-16_vec(
2211 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -16, i32 -16>
2212 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2214 %and = and <2 x i32> %X, <i32 -16, i32 -16>
2215 %cmp = icmp ne <2 x i32> %and, <i32 -16, i32 -16>
2219 ; PR32524: https://bugs.llvm.org/show_bug.cgi?id=32524
2220 ; X | C == C --> X <=u C (when C+1 is PowerOf2).
2222 define i1 @or1_eq1(i32 %x) {
2223 ; CHECK-LABEL: @or1_eq1(
2224 ; CHECK-NEXT: [[T1:%.*]] = icmp ult i32 [[X:%.*]], 2
2225 ; CHECK-NEXT: ret i1 [[T1]]
2228 %t1 = icmp eq i32 %t0, 1
2232 ; X | C == C --> X <=u C (when C+1 is PowerOf2).
2234 define <2 x i1> @or3_eq3_vec(<2 x i8> %x) {
2235 ; CHECK-LABEL: @or3_eq3_vec(
2236 ; CHECK-NEXT: [[T1:%.*]] = icmp ult <2 x i8> [[X:%.*]], <i8 4, i8 4>
2237 ; CHECK-NEXT: ret <2 x i1> [[T1]]
2239 %t0 = or <2 x i8> %x, <i8 3, i8 3>
2240 %t1 = icmp eq <2 x i8> %t0, <i8 3, i8 3>
2244 ; X | C != C --> X >u C (when C+1 is PowerOf2).
2246 define i1 @or7_ne7(i32 %x) {
2247 ; CHECK-LABEL: @or7_ne7(
2248 ; CHECK-NEXT: [[T1:%.*]] = icmp ugt i32 [[X:%.*]], 7
2249 ; CHECK-NEXT: ret i1 [[T1]]
2252 %t1 = icmp ne i32 %t0, 7
2256 ; X | C != C --> X >u C (when C+1 is PowerOf2).
2258 define <2 x i1> @or63_ne63_vec(<2 x i8> %x) {
2259 ; CHECK-LABEL: @or63_ne63_vec(
2260 ; CHECK-NEXT: [[T1:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 63, i8 63>
2261 ; CHECK-NEXT: ret <2 x i1> [[T1]]
2263 %t0 = or <2 x i8> %x, <i8 63, i8 63>
2264 %t1 = icmp ne <2 x i8> %t0, <i8 63, i8 63>
2268 ; PR40611: https://bugs.llvm.org/show_bug.cgi?id=40611
2269 ; X | C == C --> (X & ~C) == 0
2271 define i1 @orC_eqC(i32 %x) {
2272 ; CHECK-LABEL: @orC_eqC(
2273 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43
2274 ; CHECK-NEXT: [[T1:%.*]] = icmp eq i32 [[TMP1]], 0
2275 ; CHECK-NEXT: ret i1 [[T1]]
2278 %t1 = icmp eq i32 %t0, 42
2282 ; X | C == C --> (X & ~C) == 0
2284 define <2 x i1> @orC_eqC_vec(<2 x i8> %x) {
2285 ; CHECK-LABEL: @orC_eqC_vec(
2286 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 -44, i8 -44>
2287 ; CHECK-NEXT: [[T1:%.*]] = icmp eq <2 x i8> [[TMP1]], zeroinitializer
2288 ; CHECK-NEXT: ret <2 x i1> [[T1]]
2290 %t0 = or <2 x i8> %x, <i8 43, i8 43>
2291 %t1 = icmp eq <2 x i8> %t0, <i8 43, i8 43>
2295 ; X | C != C --> (X & ~C) != 0
2297 define i1 @orC_neC(i32 %x) {
2298 ; CHECK-LABEL: @orC_neC(
2299 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 41
2300 ; CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[TMP1]], 0
2301 ; CHECK-NEXT: ret i1 [[T1]]
2303 %t0 = or i32 %x, -42
2304 %t1 = icmp ne i32 %t0, -42
2308 ; X | C != C --> (X & ~C) != 0
2310 define <2 x i1> @orC_neC_vec(<2 x i8> %x) {
2311 ; CHECK-LABEL: @orC_neC_vec(
2312 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 42, i8 42>
2313 ; CHECK-NEXT: [[T1:%.*]] = icmp ne <2 x i8> [[TMP1]], zeroinitializer
2314 ; CHECK-NEXT: ret <2 x i1> [[T1]]
2316 %t0 = or <2 x i8> %x, <i8 -43, i8 -43>
2317 %t1 = icmp ne <2 x i8> %t0, <i8 -43, i8 -43>
2321 define i1 @shrink_constant(i32 %X) {
2322 ; CHECK-LABEL: @shrink_constant(
2323 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], -12
2324 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[XOR]], 4
2325 ; CHECK-NEXT: ret i1 [[CMP]]
2327 %xor = xor i32 %X, -9
2328 %cmp = icmp ult i32 %xor, 4
2332 define <2 x i1> @shrink_constant_vec(<2 x i32> %X) {
2333 ; CHECK-LABEL: @shrink_constant_vec(
2334 ; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i32> [[X:%.*]], <i32 -12, i32 -12>
2335 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[XOR]], <i32 4, i32 4>
2336 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2338 %xor = xor <2 x i32> %X, <i32 -9, i32 -9>
2339 %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4>
2343 ; This test requires 3 different transforms to get to the result.
2344 define i1 @icmp_sub_-1_X_ult_4(i32 %X) {
2345 ; CHECK-LABEL: @icmp_sub_-1_X_ult_4(
2346 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], -5
2347 ; CHECK-NEXT: ret i1 [[CMP]]
2349 %sub = sub i32 -1, %X
2350 %cmp = icmp ult i32 %sub, 4
2354 define <2 x i1> @icmp_xor_neg4_X_ult_4_vec(<2 x i32> %X) {
2355 ; CHECK-LABEL: @icmp_xor_neg4_X_ult_4_vec(
2356 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 -5, i32 -5>
2357 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2359 %xor = xor <2 x i32> %X, <i32 -4, i32 -4>
2360 %cmp = icmp ult <2 x i32> %xor, <i32 4, i32 4>
2364 define i1 @icmp_sub_-1_X_uge_4(i32 %X) {
2365 ; CHECK-LABEL: @icmp_sub_-1_X_uge_4(
2366 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], -4
2367 ; CHECK-NEXT: ret i1 [[CMP]]
2369 %sub = sub i32 -1, %X
2370 %cmp = icmp uge i32 %sub, 4
2374 define <2 x i1> @icmp_xor_neg4_X_uge_4_vec(<2 x i32> %X) {
2375 ; CHECK-LABEL: @icmp_xor_neg4_X_uge_4_vec(
2376 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 -4, i32 -4>
2377 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2379 %xor = xor <2 x i32> %X, <i32 -4, i32 -4>
2380 %cmp = icmp uge <2 x i32> %xor, <i32 4, i32 4>
2384 define <2 x i1> @xor_ult(<2 x i8> %x) {
2385 ; CHECK-LABEL: @xor_ult(
2386 ; CHECK-NEXT: [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 3, i8 3>
2387 ; CHECK-NEXT: ret <2 x i1> [[R]]
2389 %xor = xor <2 x i8> %x, <i8 -4, i8 -4>
2390 %r = icmp ult <2 x i8> %xor, <i8 -4, i8 -4>
2394 define i1 @xor_ult_extra_use(i8 %x, i8* %p) {
2395 ; CHECK-LABEL: @xor_ult_extra_use(
2396 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -32
2397 ; CHECK-NEXT: store i8 [[XOR]], i8* [[P:%.*]], align 1
2398 ; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 31
2399 ; CHECK-NEXT: ret i1 [[R]]
2401 %xor = xor i8 %x, -32
2402 store i8 %xor, i8* %p
2403 %r = icmp ult i8 %xor, -32
2407 define <2 x i1> @xor_ugt(<2 x i8> %x) {
2408 ; CHECK-LABEL: @xor_ugt(
2409 ; CHECK-NEXT: [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], <i8 7, i8 7>
2410 ; CHECK-NEXT: ret <2 x i1> [[R]]
2412 %xor = xor <2 x i8> %x, <i8 7, i8 7>
2413 %r = icmp ugt <2 x i8> %xor, <i8 7, i8 7>
2417 define i1 @xor_ugt_extra_use(i8 %x, i8* %p) {
2418 ; CHECK-LABEL: @xor_ugt_extra_use(
2419 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], 63
2420 ; CHECK-NEXT: store i8 [[XOR]], i8* [[P:%.*]], align 1
2421 ; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 63
2422 ; CHECK-NEXT: ret i1 [[R]]
2424 %xor = xor i8 %x, 63
2425 store i8 %xor, i8* %p
2426 %r = icmp ugt i8 %xor, 63
2430 define i1 @icmp_swap_operands_for_cse(i32 %X, i32 %Y) {
2431 ; CHECK-LABEL: @icmp_swap_operands_for_cse(
2432 ; CHECK-NEXT: entry:
2433 ; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
2434 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X]], [[Y]]
2435 ; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
2437 ; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[SUB]], 1
2438 ; CHECK-NEXT: br label [[END:%.*]]
2440 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[SUB]], 16
2441 ; CHECK-NEXT: br label [[END]]
2443 ; CHECK-NEXT: [[RES_IN:%.*]] = phi i32 [ [[TMP0]], [[TRUE]] ], [ [[TMP1]], [[FALSE]] ]
2444 ; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0
2445 ; CHECK-NEXT: ret i1 [[RES]]
2448 %sub = sub i32 %X, %Y
2449 %cmp = icmp ugt i32 %Y, %X
2450 br i1 %cmp, label %true, label %false
2452 %restrue = trunc i32 %sub to i1
2455 %shift = lshr i32 %sub, 4
2456 %resfalse = trunc i32 %shift to i1
2459 %res = phi i1 [%restrue, %true], [%resfalse, %false]
2463 define i1 @icmp_swap_operands_for_cse2(i32 %X, i32 %Y) {
2464 ; CHECK-LABEL: @icmp_swap_operands_for_cse2(
2465 ; CHECK-NEXT: entry:
2466 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
2467 ; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
2469 ; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X]], [[Y]]
2470 ; CHECK-NEXT: [[SUB1:%.*]] = sub i32 [[X]], [[Y]]
2471 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SUB]], [[SUB1]]
2472 ; CHECK-NEXT: br label [[END:%.*]]
2474 ; CHECK-NEXT: [[SUB2:%.*]] = sub i32 [[Y]], [[X]]
2475 ; CHECK-NEXT: br label [[END]]
2477 ; CHECK-NEXT: [[RES_IN_IN:%.*]] = phi i32 [ [[ADD]], [[TRUE]] ], [ [[SUB2]], [[FALSE]] ]
2478 ; CHECK-NEXT: [[RES_IN:%.*]] = and i32 [[RES_IN_IN]], 1
2479 ; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0
2480 ; CHECK-NEXT: ret i1 [[RES]]
2483 %cmp = icmp ugt i32 %Y, %X
2484 br i1 %cmp, label %true, label %false
2486 %sub = sub i32 %X, %Y
2487 %sub1 = sub i32 %X, %Y
2488 %add = add i32 %sub, %sub1
2489 %restrue = trunc i32 %add to i1
2492 %sub2 = sub i32 %Y, %X
2493 %resfalse = trunc i32 %sub2 to i1
2496 %res = phi i1 [%restrue, %true], [%resfalse, %false]
2500 define i1 @icmp_do_not_swap_operands_for_cse(i32 %X, i32 %Y) {
2501 ; CHECK-LABEL: @icmp_do_not_swap_operands_for_cse(
2502 ; CHECK-NEXT: entry:
2503 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[Y:%.*]], [[X:%.*]]
2504 ; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
2506 ; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X]], [[Y]]
2507 ; CHECK-NEXT: br label [[END:%.*]]
2509 ; CHECK-NEXT: [[SUB2:%.*]] = sub i32 [[Y]], [[X]]
2510 ; CHECK-NEXT: br label [[END]]
2512 ; CHECK-NEXT: [[RES_IN_IN:%.*]] = phi i32 [ [[SUB]], [[TRUE]] ], [ [[SUB2]], [[FALSE]] ]
2513 ; CHECK-NEXT: [[RES_IN:%.*]] = and i32 [[RES_IN_IN]], 1
2514 ; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[RES_IN]], 0
2515 ; CHECK-NEXT: ret i1 [[RES]]
2518 %cmp = icmp ugt i32 %Y, %X
2519 br i1 %cmp, label %true, label %false
2521 %sub = sub i32 %X, %Y
2522 %restrue = trunc i32 %sub to i1
2525 %sub2 = sub i32 %Y, %X
2526 %resfalse = trunc i32 %sub2 to i1
2529 %res = phi i1 [%restrue, %true], [%resfalse, %false]
2533 define i1 @icmp_lshr_lshr_eq(i32 %a, i32 %b) {
2534 ; CHECK-LABEL: @icmp_lshr_lshr_eq(
2535 ; CHECK-NEXT: [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2536 ; CHECK-NEXT: [[Z:%.*]] = icmp ult i32 [[Z_UNSHIFTED]], 1073741824
2537 ; CHECK-NEXT: ret i1 [[Z]]
2539 %x = lshr i32 %a, 30
2540 %y = lshr i32 %b, 30
2541 %z = icmp eq i32 %x, %y
2545 define i1 @icmp_ashr_ashr_ne(i32 %a, i32 %b) {
2546 ; CHECK-LABEL: @icmp_ashr_ashr_ne(
2547 ; CHECK-NEXT: [[Z_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2548 ; CHECK-NEXT: [[Z:%.*]] = icmp ugt i32 [[Z_UNSHIFTED]], 255
2549 ; CHECK-NEXT: ret i1 [[Z]]
2553 %z = icmp ne i32 %x, %y
2557 define i1 @icmp_neg_cst_slt(i32 %a) {
2558 ; CHECK-LABEL: @icmp_neg_cst_slt(
2559 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], 10
2560 ; CHECK-NEXT: ret i1 [[TMP1]]
2562 %1 = sub nsw i32 0, %a
2563 %2 = icmp slt i32 %1, -10
2567 define i1 @icmp_and_or_lshr(i32 %x, i32 %y) {
2568 ; CHECK-LABEL: @icmp_and_or_lshr(
2569 ; CHECK-NEXT: [[SHF1:%.*]] = shl nuw i32 1, [[Y:%.*]]
2570 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[SHF1]], 1
2571 ; CHECK-NEXT: [[AND3:%.*]] = and i32 [[OR2]], [[X:%.*]]
2572 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i32 [[AND3]], 0
2573 ; CHECK-NEXT: ret i1 [[RET]]
2575 %shf = lshr i32 %x, %y
2576 %or = or i32 %shf, %x
2577 %and = and i32 %or, 1
2578 %ret = icmp ne i32 %and, 0
2582 define <2 x i1> @icmp_and_or_lshr_vec(<2 x i32> %x, <2 x i32> %y) {
2583 ; CHECK-LABEL: @icmp_and_or_lshr_vec(
2584 ; CHECK-NEXT: [[SHF:%.*]] = lshr <2 x i32> [[X:%.*]], [[Y:%.*]]
2585 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[SHF]], [[X]]
2586 ; CHECK-NEXT: [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1>
2587 ; CHECK-NEXT: ret <2 x i1> [[RET]]
2589 %shf = lshr <2 x i32> %x, %y
2590 %or = or <2 x i32> %shf, %x
2591 %and = and <2 x i32> %or, <i32 1, i32 1>
2592 %ret = icmp ne <2 x i32> %and, zeroinitializer
2596 define <2 x i1> @icmp_and_or_lshr_vec_commute(<2 x i32> %xp, <2 x i32> %y) {
2597 ; CHECK-LABEL: @icmp_and_or_lshr_vec_commute(
2598 ; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42>
2599 ; CHECK-NEXT: [[SHF:%.*]] = lshr <2 x i32> [[X]], [[Y:%.*]]
2600 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[X]], [[SHF]]
2601 ; CHECK-NEXT: [[RET:%.*]] = trunc <2 x i32> [[OR]] to <2 x i1>
2602 ; CHECK-NEXT: ret <2 x i1> [[RET]]
2604 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
2605 %shf = lshr <2 x i32> %x, %y
2606 %or = or <2 x i32> %x, %shf
2607 %and = and <2 x i32> %or, <i32 1, i32 1>
2608 %ret = icmp ne <2 x i32> %and, zeroinitializer
2612 define i1 @icmp_and_or_lshr_cst(i32 %x) {
2613 ; CHECK-LABEL: @icmp_and_or_lshr_cst(
2614 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[X:%.*]], 3
2615 ; CHECK-NEXT: [[RET:%.*]] = icmp ne i32 [[AND1]], 0
2616 ; CHECK-NEXT: ret i1 [[RET]]
2618 %shf = lshr i32 %x, 1
2619 %or = or i32 %shf, %x
2620 %and = and i32 %or, 1
2621 %ret = icmp ne i32 %and, 0
2625 define <2 x i1> @icmp_and_or_lshr_cst_vec(<2 x i32> %x) {
2626 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec(
2627 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 3>
2628 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2629 ; CHECK-NEXT: ret <2 x i1> [[RET]]
2631 %shf = lshr <2 x i32> %x, <i32 1, i32 1>
2632 %or = or <2 x i32> %shf, %x
2633 %and = and <2 x i32> %or, <i32 1, i32 1>
2634 %ret = icmp ne <2 x i32> %and, zeroinitializer
2638 define <2 x i1> @icmp_and_or_lshr_cst_vec_nonuniform(<2 x i32> %x) {
2639 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_nonuniform(
2640 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 5>
2641 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2642 ; CHECK-NEXT: ret <2 x i1> [[RET]]
2644 %shf = lshr <2 x i32> %x, <i32 1, i32 2>
2645 %or = or <2 x i32> %shf, %x
2646 %and = and <2 x i32> %or, <i32 1, i32 1>
2647 %ret = icmp ne <2 x i32> %and, zeroinitializer
2651 define <2 x i1> @icmp_and_or_lshr_cst_vec_undef(<2 x i32> %x) {
2652 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_undef(
2653 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 3, i32 poison>
2654 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2655 ; CHECK-NEXT: ret <2 x i1> [[RET]]
2657 %shf = lshr <2 x i32> %x, <i32 1, i32 undef>
2658 %or = or <2 x i32> %shf, %x
2659 %and = and <2 x i32> %or, <i32 1, i32 1>
2660 %ret = icmp ne <2 x i32> %and, zeroinitializer
2664 define <2 x i1> @icmp_and_or_lshr_cst_vec_commute(<2 x i32> %xp) {
2665 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_commute(
2666 ; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42>
2667 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 3>
2668 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2669 ; CHECK-NEXT: ret <2 x i1> [[RET]]
2671 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
2672 %shf = lshr <2 x i32> %x, <i32 1, i32 1>
2673 %or = or <2 x i32> %x, %shf
2674 %and = and <2 x i32> %or, <i32 1, i32 1>
2675 %ret = icmp ne <2 x i32> %and, zeroinitializer
2679 define <2 x i1> @icmp_and_or_lshr_cst_vec_nonuniform_commute(<2 x i32> %xp) {
2680 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_nonuniform_commute(
2681 ; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42>
2682 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 5>
2683 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2684 ; CHECK-NEXT: ret <2 x i1> [[RET]]
2686 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
2687 %shf = lshr <2 x i32> %x, <i32 1, i32 2>
2688 %or = or <2 x i32> %x, %shf
2689 %and = and <2 x i32> %or, <i32 1, i32 1>
2690 %ret = icmp ne <2 x i32> %and, zeroinitializer
2694 define <2 x i1> @icmp_and_or_lshr_cst_vec_undef_commute(<2 x i32> %xp) {
2695 ; CHECK-LABEL: @icmp_and_or_lshr_cst_vec_undef_commute(
2696 ; CHECK-NEXT: [[X:%.*]] = srem <2 x i32> [[XP:%.*]], <i32 42, i32 42>
2697 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X]], <i32 3, i32 poison>
2698 ; CHECK-NEXT: [[RET:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
2699 ; CHECK-NEXT: ret <2 x i1> [[RET]]
2701 %x = srem <2 x i32> %xp, <i32 42, i32 -42> ; prevent complexity-based canonicalization
2702 %shf = lshr <2 x i32> %x, <i32 1, i32 undef>
2703 %or = or <2 x i32> %x, %shf
2704 %and = and <2 x i32> %or, <i32 1, i32 1>
2705 %ret = icmp ne <2 x i32> %and, zeroinitializer
2709 define i1 @shl_ap1_zero_ap2_non_zero_2(i32 %a) {
2710 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2(
2711 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 29
2712 ; CHECK-NEXT: ret i1 [[CMP]]
2714 %shl = shl i32 4, %a
2715 %cmp = icmp eq i32 %shl, 0
2719 define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec(<2 x i32> %a) {
2720 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec(
2721 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i32> [[A:%.*]], <i32 29, i32 29>
2722 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2724 %shl = shl <2 x i32> <i32 4, i32 4>, %a
2725 %cmp = icmp eq <2 x i32> %shl, zeroinitializer
2729 define <2 x i1> @shl_ap1_zero_ap2_non_zero_2_vec_nonuniform(<2 x i32> %a) {
2730 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_2_vec_nonuniform(
2731 ; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> <i32 4, i32 5>, [[A:%.*]]
2732 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[SHL]], zeroinitializer
2733 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
2735 %shl = shl <2 x i32> <i32 4, i32 5>, %a
2736 %cmp = icmp eq <2 x i32> %shl, zeroinitializer
2740 define i1 @shl_ap1_zero_ap2_non_zero_4(i32 %a) {
2741 ; CHECK-LABEL: @shl_ap1_zero_ap2_non_zero_4(
2742 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 30
2743 ; CHECK-NEXT: ret i1 [[CMP]]
2745 %shl = shl i32 -2, %a
2746 %cmp = icmp eq i32 %shl, 0
2750 define i1 @shl_ap1_non_zero_ap2_non_zero_both_positive(i32 %a) {
2751 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_positive(
2752 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
2753 ; CHECK-NEXT: ret i1 [[CMP]]
2755 %shl = shl i32 50, %a
2756 %cmp = icmp eq i32 %shl, 50
2760 define i1 @shl_ap1_non_zero_ap2_non_zero_both_negative(i32 %a) {
2761 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_both_negative(
2762 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
2763 ; CHECK-NEXT: ret i1 [[CMP]]
2765 %shl = shl i32 -50, %a
2766 %cmp = icmp eq i32 %shl, -50
2770 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_1(i32 %a) {
2771 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_1(
2772 ; CHECK-NEXT: ret i1 false
2774 %shl = shl i32 50, %a
2775 %cmp = icmp eq i32 %shl, 25
2779 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_2(i32 %a) {
2780 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_2(
2781 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 1
2782 ; CHECK-NEXT: ret i1 [[CMP]]
2784 %shl = shl i32 25, %a
2785 %cmp = icmp eq i32 %shl, 50
2789 define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_3(i32 %a) {
2790 ; CHECK-LABEL: @shl_ap1_non_zero_ap2_non_zero_ap1_3(
2791 ; CHECK-NEXT: ret i1 false
2793 %shl = shl i32 26, %a
2794 %cmp = icmp eq i32 %shl, 50
2798 define i1 @icmp_sgt_zero_add_nsw(i32 %a) {
2799 ; CHECK-LABEL: @icmp_sgt_zero_add_nsw(
2800 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -1
2801 ; CHECK-NEXT: ret i1 [[CMP]]
2803 %add = add nsw i32 %a, 1
2804 %cmp = icmp sgt i32 %add, 0
2808 define i1 @icmp_sge_zero_add_nsw(i32 %a) {
2809 ; CHECK-LABEL: @icmp_sge_zero_add_nsw(
2810 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], -2
2811 ; CHECK-NEXT: ret i1 [[CMP]]
2813 %add = add nsw i32 %a, 1
2814 %cmp = icmp sge i32 %add, 0
2818 define i1 @icmp_sle_zero_add_nsw(i32 %a) {
2819 ; CHECK-LABEL: @icmp_sle_zero_add_nsw(
2820 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 0
2821 ; CHECK-NEXT: ret i1 [[CMP]]
2823 %add = add nsw i32 %a, 1
2824 %cmp = icmp sle i32 %add, 0
2828 define zeroext i1 @icmp_cmpxchg_strong(i32* %sc, i32 %old_val, i32 %new_val) {
2829 ; CHECK-LABEL: @icmp_cmpxchg_strong(
2830 ; CHECK-NEXT: [[XCHG:%.*]] = cmpxchg i32* [[SC:%.*]], i32 [[OLD_VAL:%.*]], i32 [[NEW_VAL:%.*]] seq_cst seq_cst, align 4
2831 ; CHECK-NEXT: [[ICMP:%.*]] = extractvalue { i32, i1 } [[XCHG]], 1
2832 ; CHECK-NEXT: ret i1 [[ICMP]]
2834 %xchg = cmpxchg i32* %sc, i32 %old_val, i32 %new_val seq_cst seq_cst
2835 %xtrc = extractvalue { i32, i1 } %xchg, 0
2836 %icmp = icmp eq i32 %xtrc, %old_val
2840 define i1 @f1(i64 %a, i64 %b) {
2842 ; CHECK-NEXT: [[V:%.*]] = icmp sge i64 [[A:%.*]], [[B:%.*]]
2843 ; CHECK-NEXT: ret i1 [[V]]
2845 %t = sub nsw i64 %a, %b
2846 %v = icmp sge i64 %t, 0
2850 define <2 x i1> @f1_vec(<2 x i64> %a, <2 x i64> %b) {
2851 ; CHECK-LABEL: @f1_vec(
2852 ; CHECK-NEXT: [[V:%.*]] = icmp sge <2 x i64> [[A:%.*]], [[B:%.*]]
2853 ; CHECK-NEXT: ret <2 x i1> [[V]]
2855 %t = sub nsw <2 x i64> %a, %b
2856 %v = icmp sgt <2 x i64> %t, <i64 -1, i64 -1>
2860 define i1 @f2(i64 %a, i64 %b) {
2862 ; CHECK-NEXT: [[V:%.*]] = icmp sgt i64 [[A:%.*]], [[B:%.*]]
2863 ; CHECK-NEXT: ret i1 [[V]]
2865 %t = sub nsw i64 %a, %b
2866 %v = icmp sgt i64 %t, 0
2870 define <2 x i1> @f2_vec(<2 x i64> %a, <2 x i64> %b) {
2871 ; CHECK-LABEL: @f2_vec(
2872 ; CHECK-NEXT: [[V:%.*]] = icmp sgt <2 x i64> [[A:%.*]], [[B:%.*]]
2873 ; CHECK-NEXT: ret <2 x i1> [[V]]
2875 %t = sub nsw <2 x i64> %a, %b
2876 %v = icmp sgt <2 x i64> %t, zeroinitializer
2880 define i1 @f3(i64 %a, i64 %b) {
2882 ; CHECK-NEXT: [[V:%.*]] = icmp slt i64 [[A:%.*]], [[B:%.*]]
2883 ; CHECK-NEXT: ret i1 [[V]]
2885 %t = sub nsw i64 %a, %b
2886 %v = icmp slt i64 %t, 0
2890 define <2 x i1> @f3_vec(<2 x i64> %a, <2 x i64> %b) {
2891 ; CHECK-LABEL: @f3_vec(
2892 ; CHECK-NEXT: [[V:%.*]] = icmp slt <2 x i64> [[A:%.*]], [[B:%.*]]
2893 ; CHECK-NEXT: ret <2 x i1> [[V]]
2895 %t = sub nsw <2 x i64> %a, %b
2896 %v = icmp slt <2 x i64> %t, zeroinitializer
2900 define i1 @f4(i64 %a, i64 %b) {
2902 ; CHECK-NEXT: [[V:%.*]] = icmp sle i64 [[A:%.*]], [[B:%.*]]
2903 ; CHECK-NEXT: ret i1 [[V]]
2905 %t = sub nsw i64 %a, %b
2906 %v = icmp sle i64 %t, 0
2910 define <2 x i1> @f4_vec(<2 x i64> %a, <2 x i64> %b) {
2911 ; CHECK-LABEL: @f4_vec(
2912 ; CHECK-NEXT: [[V:%.*]] = icmp sle <2 x i64> [[A:%.*]], [[B:%.*]]
2913 ; CHECK-NEXT: ret <2 x i1> [[V]]
2915 %t = sub nsw <2 x i64> %a, %b
2916 %v = icmp slt <2 x i64> %t, <i64 1, i64 1>
2920 define i32 @f5(i8 %a, i8 %b) {
2922 ; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[A:%.*]] to i32
2923 ; CHECK-NEXT: [[CONV3:%.*]] = zext i8 [[B:%.*]] to i32
2924 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV3]]
2925 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.abs.i32(i32 [[SUB]], i1 true)
2926 ; CHECK-NEXT: ret i32 [[TMP1]]
2928 %conv = zext i8 %a to i32
2929 %conv3 = zext i8 %b to i32
2930 %sub = sub nsw i32 %conv, %conv3
2931 %cmp4 = icmp slt i32 %sub, 0
2932 %sub7 = sub nsw i32 0, %sub
2933 %sub7.sub = select i1 %cmp4, i32 %sub7, i32 %sub
2937 define i32 @f6(i32 %a, i32 %b) {
2939 ; CHECK-NEXT: [[CMP_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2940 ; CHECK-NEXT: [[CMP_MASK:%.*]] = and i32 [[CMP_UNSHIFTED]], 255
2941 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CMP_MASK]], 0
2942 ; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP]], i32 10000, i32 0
2943 ; CHECK-NEXT: ret i32 [[S]]
2945 %sext = shl i32 %a, 24
2946 %conv = ashr i32 %sext, 24
2947 %sext6 = shl i32 %b, 24
2948 %conv4 = ashr i32 %sext6, 24
2949 %cmp = icmp eq i32 %conv, %conv4
2950 %s = select i1 %cmp, i32 10000, i32 0
2954 define i32 @f7(i32 %a, i32 %b) {
2956 ; CHECK-NEXT: [[CMP_NOT_UNSHIFTED:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
2957 ; CHECK-NEXT: [[CMP_NOT_MASK:%.*]] = and i32 [[CMP_NOT_UNSHIFTED]], 511
2958 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[CMP_NOT_MASK]], 0
2959 ; CHECK-NEXT: [[S:%.*]] = select i1 [[CMP_NOT]], i32 0, i32 10000
2960 ; CHECK-NEXT: ret i32 [[S]]
2962 %sext = shl i32 %a, 23
2963 %sext6 = shl i32 %b, 23
2964 %cmp = icmp ne i32 %sext, %sext6
2965 %s = select i1 %cmp, i32 10000, i32 0
2969 define i1 @f8(i32 %val, i32 %lim) {
2971 ; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0
2972 ; CHECK-NEXT: ret i1 [[R]]
2974 %lim.sub = add i32 %lim, -1
2975 %val.and = and i32 %val, %lim.sub
2976 %r = icmp ult i32 %val.and, %lim
2980 define i1 @f9(i32 %val, i32 %lim) {
2982 ; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[LIM:%.*]], 0
2983 ; CHECK-NEXT: ret i1 [[R]]
2985 %lim.sub = sub i32 %lim, 1
2986 %val.and = and i32 %val, %lim.sub
2987 %r = icmp ult i32 %val.and, %lim
2991 define i1 @f10(i16 %p) {
2992 ; CHECK-LABEL: @f10(
2993 ; CHECK-NEXT: [[CMP580:%.*]] = icmp uge i16 [[P:%.*]], mul (i16 zext (i8 ptrtoint (i1 (i16)* @f10 to i8) to i16), i16 zext (i8 ptrtoint (i1 (i16)* @f10 to i8) to i16))
2994 ; CHECK-NEXT: ret i1 [[CMP580]]
2996 %cmp580 = icmp ule i16 mul (i16 zext (i8 ptrtoint (i1 (i16)* @f10 to i8) to i16), i16 zext (i8 ptrtoint (i1 (i16)* @f10 to i8) to i16)), %p
3000 ; Note: fptosi is used in various tests below to ensure that operand complexity
3001 ; canonicalization does not kick in, which would make some of the tests
3002 ; equivalent to one another.
3004 define i1 @cmp_sgt_rhs_dec(float %x, i32 %i) {
3005 ; CHECK-LABEL: @cmp_sgt_rhs_dec(
3006 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3007 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[CONV]], [[I:%.*]]
3008 ; CHECK-NEXT: ret i1 [[CMP]]
3010 %conv = fptosi float %x to i32
3011 %dec = sub nsw i32 %i, 1
3012 %cmp = icmp sgt i32 %conv, %dec
3016 define i1 @cmp_sle_rhs_dec(float %x, i32 %i) {
3017 ; CHECK-LABEL: @cmp_sle_rhs_dec(
3018 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3019 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CONV]], [[I:%.*]]
3020 ; CHECK-NEXT: ret i1 [[CMP]]
3022 %conv = fptosi float %x to i32
3023 %dec = sub nsw i32 %i, 1
3024 %cmp = icmp sle i32 %conv, %dec
3028 define i1 @cmp_sge_rhs_inc(float %x, i32 %i) {
3029 ; CHECK-LABEL: @cmp_sge_rhs_inc(
3030 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3031 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CONV]], [[I:%.*]]
3032 ; CHECK-NEXT: ret i1 [[CMP]]
3034 %conv = fptosi float %x to i32
3035 %inc = add nsw i32 %i, 1
3036 %cmp = icmp sge i32 %conv, %inc
3040 define i1 @cmp_slt_rhs_inc(float %x, i32 %i) {
3041 ; CHECK-LABEL: @cmp_slt_rhs_inc(
3042 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3043 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[CONV]], [[I:%.*]]
3044 ; CHECK-NEXT: ret i1 [[CMP]]
3046 %conv = fptosi float %x to i32
3047 %inc = add nsw i32 %i, 1
3048 %cmp = icmp slt i32 %conv, %inc
3052 define i1 @PR26407(i32 %x, i32 %y) {
3053 ; CHECK-LABEL: @PR26407(
3054 ; CHECK-NEXT: [[ADDX:%.*]] = add i32 [[X:%.*]], 2147483647
3055 ; CHECK-NEXT: [[ADDY:%.*]] = add i32 [[Y:%.*]], 2147483647
3056 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[ADDX]], [[ADDY]]
3057 ; CHECK-NEXT: ret i1 [[CMP]]
3059 %addx = add i32 %x, 2147483647
3060 %addy = add i32 %y, 2147483647
3061 %cmp = icmp uge i32 %addx, %addy
3065 define i1 @cmp_inverse_mask_bits_set_eq(i32 %x) {
3066 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq(
3067 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43
3068 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], -43
3069 ; CHECK-NEXT: ret i1 [[CMP]]
3072 %cmp = icmp eq i32 %or, -1
3076 define <2 x i1> @cmp_inverse_mask_bits_set_eq_vec(<2 x i32> %x) {
3077 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_eq_vec(
3078 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -43, i32 -43>
3079 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 -43, i32 -43>
3080 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
3082 %or = or <2 x i32> %x, <i32 42, i32 42>
3083 %cmp = icmp eq <2 x i32> %or, <i32 -1, i32 -1>
3087 define i1 @cmp_inverse_mask_bits_set_ne(i32 %x) {
3088 ; CHECK-LABEL: @cmp_inverse_mask_bits_set_ne(
3089 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -43
3090 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], -43
3091 ; CHECK-NEXT: ret i1 [[CMP]]
3094 %cmp = icmp ne i32 %or, -1
3098 ; When canonicalizing to 'gt/lt', make sure the constant is correct.
3100 define i1 @PR27792(i128 %a) {
3101 ; CHECK-LABEL: @PR27792(
3102 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[A:%.*]], -1
3103 ; CHECK-NEXT: ret i1 [[CMP]]
3105 %cmp = icmp sge i128 %a, 0
3109 define i1 @PR27792_2(i128 %a) {
3110 ; CHECK-LABEL: @PR27792_2(
3111 ; CHECK-NEXT: [[B:%.*]] = icmp ne i128 [[A:%.*]], 0
3112 ; CHECK-NEXT: ret i1 [[B]]
3114 %b = icmp uge i128 %a, 1
3118 define i1 @ugtMaxSignedVal(i8 %a) {
3119 ; CHECK-LABEL: @ugtMaxSignedVal(
3120 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], 0
3121 ; CHECK-NEXT: ret i1 [[CMP]]
3123 %cmp = icmp ugt i8 %a, 127
3127 define <2 x i1> @ugtMaxSignedValVec(<2 x i8> %a) {
3128 ; CHECK-LABEL: @ugtMaxSignedValVec(
3129 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> [[A:%.*]], zeroinitializer
3130 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
3132 %cmp = icmp ugt <2 x i8> %a, <i8 127, i8 127>
3136 define i1 @ugtKnownBits(i8 %a) {
3137 ; CHECK-LABEL: @ugtKnownBits(
3138 ; CHECK-NEXT: [[B:%.*]] = and i8 [[A:%.*]], 17
3139 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[B]], 17
3140 ; CHECK-NEXT: ret i1 [[CMP]]
3143 %cmp = icmp ugt i8 %b, 16
3147 define <2 x i1> @ugtKnownBitsVec(<2 x i8> %a) {
3148 ; CHECK-LABEL: @ugtKnownBitsVec(
3149 ; CHECK-NEXT: [[B:%.*]] = and <2 x i8> [[A:%.*]], <i8 17, i8 17>
3150 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[B]], <i8 17, i8 17>
3151 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
3153 %b = and <2 x i8> %a, <i8 17, i8 17>
3154 %cmp = icmp ugt <2 x i8> %b, <i8 16, i8 16>
3158 define i1 @or_ptrtoint_mismatch(i8* %p, i32* %q) {
3159 ; CHECK-LABEL: @or_ptrtoint_mismatch(
3160 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* [[P:%.*]], null
3161 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32* [[Q:%.*]], null
3162 ; CHECK-NEXT: [[B:%.*]] = and i1 [[TMP1]], [[TMP2]]
3163 ; CHECK-NEXT: ret i1 [[B]]
3166 %pp = ptrtoint i8* %p to i64
3167 %qq = ptrtoint i32* %q to i64
3168 %o = or i64 %pp, %qq
3169 %b = icmp eq i64 %o, 0
3173 define i1 @icmp_add1_ugt(i32 %x, i32 %y) {
3174 ; CHECK-LABEL: @icmp_add1_ugt(
3175 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]]
3176 ; CHECK-NEXT: ret i1 [[CMP]]
3178 %add = add nuw i32 %x, 1
3179 %cmp = icmp ugt i32 %add, %y
3183 define i1 @icmp_add1_ule(i32 %x, i32 %y) {
3184 ; CHECK-LABEL: @icmp_add1_ule(
3185 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
3186 ; CHECK-NEXT: ret i1 [[CMP]]
3188 %add = add nuw i32 %x, 1
3189 %cmp = icmp ule i32 %add, %y
3193 define i1 @cmp_uge_rhs_inc(float %x, i32 %i) {
3194 ; CHECK-LABEL: @cmp_uge_rhs_inc(
3195 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3196 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[CONV]], [[I:%.*]]
3197 ; CHECK-NEXT: ret i1 [[CMP]]
3199 %conv = fptosi float %x to i32
3200 %inc = add nuw i32 %i, 1
3201 %cmp = icmp uge i32 %conv, %inc
3205 define i1 @cmp_ult_rhs_inc(float %x, i32 %i) {
3206 ; CHECK-LABEL: @cmp_ult_rhs_inc(
3207 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3208 ; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[CONV]], [[I:%.*]]
3209 ; CHECK-NEXT: ret i1 [[CMP]]
3211 %conv = fptosi float %x to i32
3212 %inc = add nuw i32 %i, 1
3213 %cmp = icmp ult i32 %conv, %inc
3217 define i1 @cmp_sge_lhs_inc(i32 %x, i32 %y) {
3218 ; CHECK-LABEL: @cmp_sge_lhs_inc(
3219 ; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[X:%.*]], 1
3220 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[INC]], [[Y:%.*]]
3221 ; CHECK-NEXT: ret i1 [[CMP]]
3223 %inc = add nsw i32 %x, 1
3224 %cmp = icmp sge i32 %inc, %y
3228 define i1 @cmp_uge_lhs_inc(i32 %x, i32 %y) {
3229 ; CHECK-LABEL: @cmp_uge_lhs_inc(
3230 ; CHECK-NEXT: [[INC:%.*]] = add nuw i32 [[X:%.*]], 1
3231 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[INC]], [[Y:%.*]]
3232 ; CHECK-NEXT: ret i1 [[CMP]]
3234 %inc = add nuw i32 %x, 1
3235 %cmp = icmp uge i32 %inc, %y
3239 define i1 @cmp_sgt_lhs_dec(i32 %x, i32 %y) {
3240 ; CHECK-LABEL: @cmp_sgt_lhs_dec(
3241 ; CHECK-NEXT: [[DEC:%.*]] = add nsw i32 [[X:%.*]], -1
3242 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[Y:%.*]]
3243 ; CHECK-NEXT: ret i1 [[CMP]]
3245 %dec = sub nsw i32 %x, 1
3246 %cmp = icmp sgt i32 %dec, %y
3250 define i1 @cmp_ugt_lhs_dec(i32 %x, i32 %y) {
3251 ; CHECK-LABEL: @cmp_ugt_lhs_dec(
3252 ; CHECK-NEXT: [[DEC:%.*]] = add i32 [[X:%.*]], -1
3253 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[Y:%.*]]
3254 ; CHECK-NEXT: ret i1 [[CMP]]
3256 %dec = sub nuw i32 %x, 1
3257 %cmp = icmp ugt i32 %dec, %y
3261 define i1 @cmp_sle_rhs_inc(float %x, i32 %y) {
3262 ; CHECK-LABEL: @cmp_sle_rhs_inc(
3263 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3264 ; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[Y:%.*]], 1
3265 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[INC]], [[CONV]]
3266 ; CHECK-NEXT: ret i1 [[CMP]]
3268 %conv = fptosi float %x to i32
3269 %inc = add nsw i32 %y, 1
3270 %cmp = icmp sle i32 %conv, %inc
3274 define i1 @cmp_ule_rhs_inc(float %x, i32 %y) {
3275 ; CHECK-LABEL: @cmp_ule_rhs_inc(
3276 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3277 ; CHECK-NEXT: [[INC:%.*]] = add nuw i32 [[Y:%.*]], 1
3278 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[INC]], [[CONV]]
3279 ; CHECK-NEXT: ret i1 [[CMP]]
3281 %conv = fptosi float %x to i32
3282 %inc = add nuw i32 %y, 1
3283 %cmp = icmp ule i32 %conv, %inc
3287 define i1 @cmp_slt_rhs_dec(float %x, i32 %y) {
3288 ; CHECK-LABEL: @cmp_slt_rhs_dec(
3289 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3290 ; CHECK-NEXT: [[DEC:%.*]] = add nsw i32 [[Y:%.*]], -1
3291 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[CONV]]
3292 ; CHECK-NEXT: ret i1 [[CMP]]
3294 %conv = fptosi float %x to i32
3295 %dec = sub nsw i32 %y, 1
3296 %cmp = icmp slt i32 %conv, %dec
3300 define i1 @cmp_ult_rhs_dec(float %x, i32 %y) {
3301 ; CHECK-LABEL: @cmp_ult_rhs_dec(
3302 ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i32
3303 ; CHECK-NEXT: [[DEC:%.*]] = add i32 [[Y:%.*]], -1
3304 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC]], [[CONV]]
3305 ; CHECK-NEXT: ret i1 [[CMP]]
3307 %conv = fptosi float %x to i32
3308 %dec = sub nuw i32 %y, 1
3309 %cmp = icmp ult i32 %conv, %dec
3313 define i1 @eq_add_constants(i32 %x, i32 %y) {
3314 ; CHECK-LABEL: @eq_add_constants(
3315 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
3316 ; CHECK-NEXT: ret i1 [[C]]
3320 %C = icmp eq i32 %A, %B
3324 declare i32 @llvm.bswap.i32(i32)
3326 define i1 @bswap_ne(i32 %x, i32 %y) {
3327 ; CHECK-LABEL: @bswap_ne(
3328 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
3329 ; CHECK-NEXT: ret i1 [[CMP]]
3331 %swapx = call i32 @llvm.bswap.i32(i32 %x)
3332 %swapy = call i32 @llvm.bswap.i32(i32 %y)
3333 %cmp = icmp ne i32 %swapx, %swapy
3337 declare <8 x i16> @llvm.bswap.v8i16(<8 x i16>)
3339 define <8 x i1> @bswap_vec_eq(<8 x i16> %x, <8 x i16> %y) {
3340 ; CHECK-LABEL: @bswap_vec_eq(
3341 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <8 x i16> [[X:%.*]], [[Y:%.*]]
3342 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
3344 %swapx = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %x)
3345 %swapy = call <8 x i16> @llvm.bswap.v8i16(<8 x i16> %y)
3346 %cmp = icmp eq <8 x i16> %swapx, %swapy
3350 declare i64 @llvm.bitreverse.i64(i64)
3352 define i1 @bitreverse_eq(i64 %x, i64 %y) {
3353 ; CHECK-LABEL: @bitreverse_eq(
3354 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]]
3355 ; CHECK-NEXT: ret i1 [[CMP]]
3357 %revx = call i64 @llvm.bitreverse.i64(i64 %x)
3358 %revy = call i64 @llvm.bitreverse.i64(i64 %y)
3359 %cmp = icmp eq i64 %revx, %revy
3363 declare <8 x i16> @llvm.bitreverse.v8i16(<8 x i16>)
3365 define <8 x i1> @bitreverse_vec_ne(<8 x i16> %x, <8 x i16> %y) {
3366 ; CHECK-LABEL: @bitreverse_vec_ne(
3367 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne <8 x i16> [[X:%.*]], [[Y:%.*]]
3368 ; CHECK-NEXT: ret <8 x i1> [[CMP]]
3370 %revx = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %x)
3371 %revy = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %y)
3372 %cmp = icmp ne <8 x i16> %revx, %revy
3376 ; These perform a comparison of a value known to be between 4 and 5 with a value between 5 and 7.
3377 ; They should all simplify to equality compares.
3378 define i1 @knownbits1(i8 %a, i8 %b) {
3379 ; CHECK-LABEL: @knownbits1(
3380 ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1
3381 ; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4
3382 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
3383 ; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5
3384 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A2]], [[B2]]
3385 ; CHECK-NEXT: ret i1 [[C]]
3391 %c = icmp uge i8 %a2, %b2
3395 define i1 @knownbits2(i8 %a, i8 %b) {
3396 ; CHECK-LABEL: @knownbits2(
3397 ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1
3398 ; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4
3399 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
3400 ; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5
3401 ; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A2]], [[B2]]
3402 ; CHECK-NEXT: ret i1 [[C]]
3408 %c = icmp ult i8 %a2, %b2
3412 define i1 @knownbits3(i8 %a, i8 %b) {
3413 ; CHECK-LABEL: @knownbits3(
3414 ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1
3415 ; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4
3416 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
3417 ; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5
3418 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[B2]], [[A2]]
3419 ; CHECK-NEXT: ret i1 [[C]]
3425 %c = icmp ule i8 %b2, %a2
3429 define <2 x i1> @knownbits4(<2 x i8> %a, <2 x i8> %b) {
3430 ; CHECK-LABEL: @knownbits4(
3431 ; CHECK-NEXT: [[A1:%.*]] = and <2 x i8> [[A:%.*]], <i8 1, i8 1>
3432 ; CHECK-NEXT: [[A2:%.*]] = or <2 x i8> [[A1]], <i8 4, i8 4>
3433 ; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B:%.*]], <i8 2, i8 2>
3434 ; CHECK-NEXT: [[B2:%.*]] = or <2 x i8> [[B1]], <i8 5, i8 5>
3435 ; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[B2]], [[A2]]
3436 ; CHECK-NEXT: ret <2 x i1> [[C]]
3438 %a1 = and <2 x i8> %a, <i8 5, i8 5>
3439 %a2 = or <2 x i8> %a1, <i8 4, i8 4>
3440 %b1 = and <2 x i8> %b, <i8 7, i8 7>
3441 %b2 = or <2 x i8> %b1, <i8 5, i8 5>
3442 %c = icmp ugt <2 x i8> %b2, %a2
3446 ; These are the signed versions of the above. One value is less than or equal to 5, but maybe negative.
3447 ; The other is known to be a value 5-7. These should simplify to equality comparisons.
3448 define i1 @knownbits5(i8 %a, i8 %b) {
3449 ; CHECK-LABEL: @knownbits5(
3450 ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127
3451 ; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4
3452 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
3453 ; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5
3454 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A2]], [[B2]]
3455 ; CHECK-NEXT: ret i1 [[C]]
3457 %a1 = and i8 %a, 133
3461 %c = icmp sge i8 %a2, %b2
3465 define i1 @knownbits6(i8 %a, i8 %b) {
3466 ; CHECK-LABEL: @knownbits6(
3467 ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127
3468 ; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4
3469 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
3470 ; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5
3471 ; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[A2]], [[B2]]
3472 ; CHECK-NEXT: ret i1 [[C]]
3474 %a1 = and i8 %a, 133
3478 %c = icmp slt i8 %a2, %b2
3482 define <2 x i1> @knownbits7(<2 x i8> %a, <2 x i8> %b) {
3483 ; CHECK-LABEL: @knownbits7(
3484 ; CHECK-NEXT: [[A1:%.*]] = and <2 x i8> [[A:%.*]], <i8 -127, i8 -127>
3485 ; CHECK-NEXT: [[A2:%.*]] = or <2 x i8> [[A1]], <i8 4, i8 4>
3486 ; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B:%.*]], <i8 2, i8 2>
3487 ; CHECK-NEXT: [[B2:%.*]] = or <2 x i8> [[B1]], <i8 5, i8 5>
3488 ; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i8> [[B2]], [[A2]]
3489 ; CHECK-NEXT: ret <2 x i1> [[C]]
3491 %a1 = and <2 x i8> %a, <i8 133, i8 133>
3492 %a2 = or <2 x i8> %a1, <i8 4, i8 4>
3493 %b1 = and <2 x i8> %b, <i8 7, i8 7>
3494 %b2 = or <2 x i8> %b1, <i8 5, i8 5>
3495 %c = icmp sle <2 x i8> %b2, %a2
3499 define i1 @knownbits8(i8 %a, i8 %b) {
3500 ; CHECK-LABEL: @knownbits8(
3501 ; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127
3502 ; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4
3503 ; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
3504 ; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5
3505 ; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[B2]], [[A2]]
3506 ; CHECK-NEXT: ret i1 [[C]]
3508 %a1 = and i8 %a, 133
3512 %c = icmp sgt i8 %b2, %a2
3516 ; Make sure InstCombine doesn't try too hard to simplify the icmp and break the abs idiom
3517 define i32 @abs_preserve(i32 %x) {
3518 ; CHECK-LABEL: @abs_preserve(
3519 ; CHECK-NEXT: [[A:%.*]] = shl nsw i32 [[X:%.*]], 1
3520 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.abs.i32(i32 [[A]], i1 false)
3521 ; CHECK-NEXT: ret i32 [[TMP1]]
3523 %a = mul nsw i32 %x, 2
3524 %c = icmp sge i32 %a, 0
3525 %nega = sub i32 0, %a
3526 %abs = select i1 %c, i32 %a, i32 %nega
3530 ; Don't crash by assuming the compared values are integers.
3532 declare void @llvm.assume(i1)
3533 define i1 @PR35794(i32* %a) {
3534 ; CHECK-LABEL: @PR35794(
3535 ; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i32* [[A:%.*]], null
3536 ; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]])
3537 ; CHECK-NEXT: ret i1 true
3539 %cmp = icmp sgt i32* %a, inttoptr (i64 -1 to i32*)
3540 %maskcond = icmp eq i32* %a, null
3541 tail call void @llvm.assume(i1 %maskcond)
3545 ; Don't crash by assuming the compared values are integers.
3546 define <2 x i1> @PR36583(<2 x i8*>) {
3547 ; CHECK-LABEL: @PR36583(
3548 ; CHECK-NEXT: [[RES:%.*]] = icmp eq <2 x i8*> [[TMP0:%.*]], zeroinitializer
3549 ; CHECK-NEXT: ret <2 x i1> [[RES]]
3551 %cast = ptrtoint <2 x i8*> %0 to <2 x i64>
3552 %res = icmp eq <2 x i64> %cast, zeroinitializer
3556 ; fold (icmp pred (sub (0, X)) C1) for vec type
3557 define <2 x i32> @Op1Negated_Vec(<2 x i32> %x) {
3558 ; CHECK-LABEL: @Op1Negated_Vec(
3559 ; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.abs.v2i32(<2 x i32> [[X:%.*]], i1 true)
3560 ; CHECK-NEXT: ret <2 x i32> [[TMP1]]
3562 %sub = sub nsw <2 x i32> zeroinitializer, %x
3563 %cmp = icmp sgt <2 x i32> %sub, <i32 -1, i32 -1>
3564 %cond = select <2 x i1> %cmp, <2 x i32> %sub, <2 x i32> %x
3568 define i1 @signbit_bitcast_fpext(float %x) {
3569 ; CHECK-LABEL: @signbit_bitcast_fpext(
3570 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast float [[X:%.*]] to i32
3571 ; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0
3572 ; CHECK-NEXT: ret i1 [[R]]
3574 %f = fpext float %x to double
3575 %b = bitcast double %f to i64
3576 %r = icmp slt i64 %b, 0
3580 define <2 x i1> @signbit_bitcast_fpext_vec(<2 x half> %x) {
3581 ; CHECK-LABEL: @signbit_bitcast_fpext_vec(
3582 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x half> [[X:%.*]] to <2 x i16>
3583 ; CHECK-NEXT: [[R:%.*]] = icmp slt <2 x i16> [[TMP1]], zeroinitializer
3584 ; CHECK-NEXT: ret <2 x i1> [[R]]
3586 %f = fpext <2 x half> %x to <2 x float>
3587 %b = bitcast <2 x float> %f to <2 x i32>
3588 %r = icmp ugt <2 x i32> %b, <i32 2147483647, i32 2147483647>
3592 define i1 @signbit_bitcast_fptrunc(float %x) {
3593 ; CHECK-LABEL: @signbit_bitcast_fptrunc(
3594 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast float [[X:%.*]] to i32
3595 ; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1
3596 ; CHECK-NEXT: ret i1 [[R]]
3598 %f = fptrunc float %x to half
3599 %b = bitcast half %f to i16
3600 %r = icmp ult i16 %b, 32768
3604 define <2 x i1> @signbit_bitcast_fptrunc_vec(<2 x double> %x) {
3605 ; CHECK-LABEL: @signbit_bitcast_fptrunc_vec(
3606 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[X:%.*]] to <2 x i64>
3607 ; CHECK-NEXT: [[R:%.*]] = icmp sgt <2 x i64> [[TMP1]], <i64 -1, i64 -1>
3608 ; CHECK-NEXT: ret <2 x i1> [[R]]
3610 %f = fptrunc <2 x double> %x to <2 x half>
3611 %b = bitcast <2 x half> %f to <2 x i16>
3612 %r = icmp sge <2 x i16> %b, zeroinitializer
3616 define i1 @signbit_bitcast_fpext_wrong_cmp(float %x) {
3617 ; CHECK-LABEL: @signbit_bitcast_fpext_wrong_cmp(
3618 ; CHECK-NEXT: [[F:%.*]] = fpext float [[X:%.*]] to double
3619 ; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64
3620 ; CHECK-NEXT: [[R:%.*]] = icmp slt i64 [[B]], 1
3621 ; CHECK-NEXT: ret i1 [[R]]
3623 %f = fpext float %x to double
3624 %b = bitcast double %f to i64
3625 %r = icmp slt i64 %b, 1
3629 define <4 x i1> @signbit_bitcast_fpext_vec_wrong_bitcast(<2 x half> %x) {
3630 ; CHECK-LABEL: @signbit_bitcast_fpext_vec_wrong_bitcast(
3631 ; CHECK-NEXT: [[F:%.*]] = fpext <2 x half> [[X:%.*]] to <2 x float>
3632 ; CHECK-NEXT: [[B:%.*]] = bitcast <2 x float> [[F]] to <4 x i16>
3633 ; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i16> [[B]], <i16 -1, i16 -1, i16 -1, i16 -1>
3634 ; CHECK-NEXT: ret <4 x i1> [[R]]
3636 %f = fpext <2 x half> %x to <2 x float>
3637 %b = bitcast <2 x float> %f to <4 x i16>
3638 %r = icmp sgt <4 x i16> %b, <i16 -1, i16 -1, i16 -1, i16 -1>
3642 declare void @use_i64(i64)
3644 define i1 @signbit_bitcast_fpext_extra_use(float %x, i64* %p) {
3645 ; CHECK-LABEL: @signbit_bitcast_fpext_extra_use(
3646 ; CHECK-NEXT: [[F:%.*]] = fpext float [[X:%.*]] to double
3647 ; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64
3648 ; CHECK-NEXT: call void @use_i64(i64 [[B]])
3649 ; CHECK-NEXT: [[R:%.*]] = icmp slt i64 [[B]], 0
3650 ; CHECK-NEXT: ret i1 [[R]]
3652 %f = fpext float %x to double
3653 %b = bitcast double %f to i64
3654 call void @use_i64(i64 %b)
3655 %r = icmp slt i64 %b, 0
3659 define i1 @signbit_bitcast_fpext_ppc_fp128(float %x) {
3660 ; CHECK-LABEL: @signbit_bitcast_fpext_ppc_fp128(
3661 ; CHECK-NEXT: [[S2:%.*]] = fpext float [[X:%.*]] to ppc_fp128
3662 ; CHECK-NEXT: [[S3:%.*]] = bitcast ppc_fp128 [[S2]] to i128
3663 ; CHECK-NEXT: [[S4:%.*]] = icmp slt i128 [[S3]], 0
3664 ; CHECK-NEXT: ret i1 [[S4]]
3666 %s2 = fpext float %x to ppc_fp128
3667 %s3 = bitcast ppc_fp128 %s2 to i128
3668 %s4 = icmp slt i128 %s3, 0
3672 define i1 @signbit_bitcast_fptrunc_ppc_fp128(ppc_fp128 %x) {
3673 ; CHECK-LABEL: @signbit_bitcast_fptrunc_ppc_fp128(
3674 ; CHECK-NEXT: [[S2:%.*]] = fptrunc ppc_fp128 [[X:%.*]] to float
3675 ; CHECK-NEXT: [[S3:%.*]] = bitcast float [[S2]] to i32
3676 ; CHECK-NEXT: [[S4:%.*]] = icmp slt i32 [[S3]], 0
3677 ; CHECK-NEXT: ret i1 [[S4]]
3679 %s2 = fptrunc ppc_fp128 %x to float
3680 %s3 = bitcast float %s2 to i32
3681 %s4 = icmp slt i32 %s3, 0
3685 @x = external dso_local local_unnamed_addr global i32, align 4
3686 @y = external dso_local local_unnamed_addr global i32, align 4
3687 define i1 @pr47997(i32 %arg) {
3688 ; CHECK-LABEL: @pr47997(
3690 ; CHECK-NEXT: [[I:%.*]] = add nsw i32 [[ARG:%.*]], -1
3691 ; CHECK-NEXT: store i32 [[I]], i32* @x, align 4
3692 ; CHECK-NEXT: [[I1:%.*]] = sub nsw i32 1, [[ARG]]
3693 ; CHECK-NEXT: store i32 [[I1]], i32* @y, align 4
3694 ; CHECK-NEXT: ret i1 true
3697 %i = add nsw i32 %arg, -1
3698 store i32 %i, i32* @x
3699 %i1 = sub nsw i32 1, %arg
3700 store i32 %i1, i32* @y
3701 %i2 = sub nsw i32 0, %i1
3702 %i3 = icmp eq i32 %i, %i2
3708 define i1 @thread_cmp_over_select_with_poison_trueval(i1 %b) {
3709 ; CHECK-LABEL: @thread_cmp_over_select_with_poison_trueval(
3710 ; CHECK-NEXT: ret i1 false
3712 %s = select i1 %b, i32 poison, i32 0
3713 %tobool = icmp ne i32 %s, 0
3717 define i1 @thread_cmp_over_select_with_poison_falseval(i1 %b) {
3718 ; CHECK-LABEL: @thread_cmp_over_select_with_poison_falseval(
3719 ; CHECK-NEXT: ret i1 true
3721 %s = select i1 %b, i32 1, i32 poison
3722 %tobool = icmp ne i32 %s, 0
3726 define i1 @signbit_true_logic(i8 %x) {
3727 ; CHECK-LABEL: @signbit_true_logic(
3728 ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X:%.*]], 0
3729 ; CHECK-NEXT: ret i1 [[R]]
3731 %dec = add i8 %x, -1
3732 %not = xor i8 %x, -1
3733 %and = and i8 %dec, %not
3734 %r = icmp slt i8 %and, 0
3738 define <2 x i1> @signbit_false_logic(<2 x i5> %x) {
3739 ; CHECK-LABEL: @signbit_false_logic(
3740 ; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i5> [[X:%.*]], zeroinitializer
3741 ; CHECK-NEXT: ret <2 x i1> [[R]]
3743 %dec = add <2 x i5> %x, <i5 -1, i5 undef>
3744 %not = xor <2 x i5> %x, <i5 -1, i5 -1>
3745 %and = and <2 x i5> %dec, %not
3746 %r = icmp sgt <2 x i5> %and, <i5 -1, i5 -1>
3750 ; Confirm that complexity canonicalization works for commuted pattern.
3752 define i1 @signbit_true_logic_uses_commute(i64 %x) {
3753 ; CHECK-LABEL: @signbit_true_logic_uses_commute(
3754 ; CHECK-NEXT: [[DEC:%.*]] = add i64 [[X:%.*]], -1
3755 ; CHECK-NEXT: call void @use_i64(i64 [[DEC]])
3756 ; CHECK-NEXT: [[NOT:%.*]] = xor i64 [[X]], -1
3757 ; CHECK-NEXT: call void @use_i64(i64 [[NOT]])
3758 ; CHECK-NEXT: [[AND:%.*]] = and i64 [[DEC]], [[NOT]]
3759 ; CHECK-NEXT: call void @use_i64(i64 [[AND]])
3760 ; CHECK-NEXT: [[R:%.*]] = icmp eq i64 [[X]], 0
3761 ; CHECK-NEXT: ret i1 [[R]]
3763 %dec = add i64 %x, -1
3764 call void @use_i64(i64 %dec)
3765 %not = xor i64 %x, -1
3766 call void @use_i64(i64 %not)
3767 %and = and i64 %not, %dec
3768 call void @use_i64(i64 %and)
3769 %r = icmp slt i64 %and, 0