[SLP] Add cost model for `llvm.powi.*` intrinsics
[llvm-project.git] / llvm / test / Transforms / InstCombine / icmp-shr.ll
blobf013e6bdcbe2c46cc85e536ba1126b9ef6af2ed4
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=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 define i1 @lshr_eq_msb_low_last_zero(i8 %a) {
7 ; CHECK-LABEL: @lshr_eq_msb_low_last_zero(
8 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[A:%.*]], 6
9 ; CHECK-NEXT:    ret i1 [[CMP]]
11   %shr = lshr i8 127, %a
12   %cmp = icmp eq i8 %shr, 0
13   ret i1 %cmp
16 define <2 x i1> @lshr_eq_msb_low_last_zero_vec(<2 x i8> %a) {
17 ; CHECK-LABEL: @lshr_eq_msb_low_last_zero_vec(
18 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i8> [[A:%.*]], <i8 6, i8 6>
19 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
21   %shr = lshr <2 x i8> <i8 127, i8 127>, %a
22   %cmp = icmp eq <2 x i8> %shr, zeroinitializer
23   ret <2 x i1> %cmp
26 define i1 @ashr_eq_msb_low_second_zero(i8 %a) {
27 ; CHECK-LABEL: @ashr_eq_msb_low_second_zero(
28 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[A:%.*]], 6
29 ; CHECK-NEXT:    ret i1 [[CMP]]
31   %shr = ashr i8 127, %a
32   %cmp = icmp eq i8 %shr, 0
33   ret i1 %cmp
36 define i1 @lshr_ne_msb_low_last_zero(i8 %a) {
37 ; CHECK-LABEL: @lshr_ne_msb_low_last_zero(
38 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[A:%.*]], 7
39 ; CHECK-NEXT:    ret i1 [[CMP]]
41   %shr = lshr i8 127, %a
42   %cmp = icmp ne i8 %shr, 0
43   ret i1 %cmp
46 define i1 @ashr_ne_msb_low_second_zero(i8 %a) {
47 ; CHECK-LABEL: @ashr_ne_msb_low_second_zero(
48 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[A:%.*]], 7
49 ; CHECK-NEXT:    ret i1 [[CMP]]
51   %shr = ashr i8 127, %a
52   %cmp = icmp ne i8 %shr, 0
53   ret i1 %cmp
56 define i1 @ashr_eq_both_equal(i8 %a) {
57 ; CHECK-LABEL: @ashr_eq_both_equal(
58 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 0
59 ; CHECK-NEXT:    ret i1 [[CMP]]
61   %shr = ashr i8 128, %a
62   %cmp = icmp eq i8 %shr, 128
63   ret i1 %cmp
66 define i1 @ashr_ne_both_equal(i8 %a) {
67 ; CHECK-LABEL: @ashr_ne_both_equal(
68 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[A:%.*]], 0
69 ; CHECK-NEXT:    ret i1 [[CMP]]
71   %shr = ashr i8 128, %a
72   %cmp = icmp ne i8 %shr, 128
73   ret i1 %cmp
76 define i1 @lshr_eq_both_equal(i8 %a) {
77 ; CHECK-LABEL: @lshr_eq_both_equal(
78 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 0
79 ; CHECK-NEXT:    ret i1 [[CMP]]
81   %shr = lshr i8 127, %a
82   %cmp = icmp eq i8 %shr, 127
83   ret i1 %cmp
86 define i1 @lshr_ne_both_equal(i8 %a) {
87 ; CHECK-LABEL: @lshr_ne_both_equal(
88 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[A:%.*]], 0
89 ; CHECK-NEXT:    ret i1 [[CMP]]
91   %shr = lshr i8 127, %a
92   %cmp = icmp ne i8 %shr, 127
93   ret i1 %cmp
96 define i1 @exact_ashr_eq_both_equal(i8 %a) {
97 ; CHECK-LABEL: @exact_ashr_eq_both_equal(
98 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 0
99 ; CHECK-NEXT:    ret i1 [[CMP]]
101   %shr = ashr exact i8 128, %a
102   %cmp = icmp eq i8 %shr, 128
103   ret i1 %cmp
106 define i1 @exact_ashr_ne_both_equal(i8 %a) {
107 ; CHECK-LABEL: @exact_ashr_ne_both_equal(
108 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[A:%.*]], 0
109 ; CHECK-NEXT:    ret i1 [[CMP]]
111   %shr = ashr exact i8 128, %a
112   %cmp = icmp ne i8 %shr, 128
113   ret i1 %cmp
116 define i1 @exact_lshr_eq_both_equal(i8 %a) {
117 ; CHECK-LABEL: @exact_lshr_eq_both_equal(
118 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 0
119 ; CHECK-NEXT:    ret i1 [[CMP]]
121   %shr = lshr exact i8 126, %a
122   %cmp = icmp eq i8 %shr, 126
123   ret i1 %cmp
126 define i1 @exact_lshr_ne_both_equal(i8 %a) {
127 ; CHECK-LABEL: @exact_lshr_ne_both_equal(
128 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[A:%.*]], 0
129 ; CHECK-NEXT:    ret i1 [[CMP]]
131   %shr = lshr exact i8 126, %a
132   %cmp = icmp ne i8 %shr, 126
133   ret i1 %cmp
136 define i1 @exact_lshr_eq_opposite_msb(i8 %a) {
137 ; CHECK-LABEL: @exact_lshr_eq_opposite_msb(
138 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 7
139 ; CHECK-NEXT:    ret i1 [[CMP]]
141   %shr = lshr exact i8 -128, %a
142   %cmp = icmp eq i8 %shr, 1
143   ret i1 %cmp
146 define i1 @lshr_eq_opposite_msb(i8 %a) {
147 ; CHECK-LABEL: @lshr_eq_opposite_msb(
148 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 7
149 ; CHECK-NEXT:    ret i1 [[CMP]]
151   %shr = lshr i8 -128, %a
152   %cmp = icmp eq i8 %shr, 1
153   ret i1 %cmp
156 define i1 @exact_lshr_ne_opposite_msb(i8 %a) {
157 ; CHECK-LABEL: @exact_lshr_ne_opposite_msb(
158 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[A:%.*]], 7
159 ; CHECK-NEXT:    ret i1 [[CMP]]
161   %shr = lshr exact i8 -128, %a
162   %cmp = icmp ne i8 %shr, 1
163   ret i1 %cmp
166 define i1 @lshr_ne_opposite_msb(i8 %a) {
167 ; CHECK-LABEL: @lshr_ne_opposite_msb(
168 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[A:%.*]], 7
169 ; CHECK-NEXT:    ret i1 [[CMP]]
171   %shr = lshr i8 -128, %a
172   %cmp = icmp ne i8 %shr, 1
173   ret i1 %cmp
176 define i1 @exact_ashr_eq(i8 %a) {
177 ; CHECK-LABEL: @exact_ashr_eq(
178 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 7
179 ; CHECK-NEXT:    ret i1 [[CMP]]
181   %shr = ashr exact i8 -128, %a
182   %cmp = icmp eq i8 %shr, -1
183   ret i1 %cmp
186 define i1 @exact_ashr_ne(i8 %a) {
187 ; CHECK-LABEL: @exact_ashr_ne(
188 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[A:%.*]], 7
189 ; CHECK-NEXT:    ret i1 [[CMP]]
191   %shr = ashr exact i8 -128, %a
192   %cmp = icmp ne i8 %shr, -1
193   ret i1 %cmp
196 define i1 @exact_lshr_eq(i8 %a) {
197 ; CHECK-LABEL: @exact_lshr_eq(
198 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 2
199 ; CHECK-NEXT:    ret i1 [[CMP]]
201   %shr = lshr exact i8 4, %a
202   %cmp = icmp eq i8 %shr, 1
203   ret i1 %cmp
206 define i1 @exact_lshr_ne(i8 %a) {
207 ; CHECK-LABEL: @exact_lshr_ne(
208 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[A:%.*]], 2
209 ; CHECK-NEXT:    ret i1 [[CMP]]
211   %shr = lshr exact i8 4, %a
212   %cmp = icmp ne i8 %shr, 1
213   ret i1 %cmp
216 define i1 @nonexact_ashr_eq(i8 %a) {
217 ; CHECK-LABEL: @nonexact_ashr_eq(
218 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 7
219 ; CHECK-NEXT:    ret i1 [[CMP]]
221   %shr = ashr i8 -128, %a
222   %cmp = icmp eq i8 %shr, -1
223   ret i1 %cmp
226 define i1 @nonexact_ashr_ne(i8 %a) {
227 ; CHECK-LABEL: @nonexact_ashr_ne(
228 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[A:%.*]], 7
229 ; CHECK-NEXT:    ret i1 [[CMP]]
231   %shr = ashr i8 -128, %a
232   %cmp = icmp ne i8 %shr, -1
233   ret i1 %cmp
236 define i1 @nonexact_lshr_eq(i8 %a) {
237 ; CHECK-LABEL: @nonexact_lshr_eq(
238 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 2
239 ; CHECK-NEXT:    ret i1 [[CMP]]
241   %shr = lshr i8 4, %a
242   %cmp = icmp eq i8 %shr, 1
243   ret i1 %cmp
246 define i1 @nonexact_lshr_ne(i8 %a) {
247 ; CHECK-LABEL: @nonexact_lshr_ne(
248 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[A:%.*]], 2
249 ; CHECK-NEXT:    ret i1 [[CMP]]
251   %shr = lshr i8 4, %a
252   %cmp = icmp ne i8 %shr, 1
253   ret i1 %cmp
256 define i1 @exact_lshr_eq_exactdiv(i8 %a) {
257 ; CHECK-LABEL: @exact_lshr_eq_exactdiv(
258 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 4
259 ; CHECK-NEXT:    ret i1 [[CMP]]
261   %shr = lshr exact i8 80, %a
262   %cmp = icmp eq i8 %shr, 5
263   ret i1 %cmp
266 define i1 @exact_lshr_ne_exactdiv(i8 %a) {
267 ; CHECK-LABEL: @exact_lshr_ne_exactdiv(
268 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[A:%.*]], 4
269 ; CHECK-NEXT:    ret i1 [[CMP]]
271   %shr = lshr exact i8 80, %a
272   %cmp = icmp ne i8 %shr, 5
273   ret i1 %cmp
276 define i1 @nonexact_lshr_eq_exactdiv(i8 %a) {
277 ; CHECK-LABEL: @nonexact_lshr_eq_exactdiv(
278 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 4
279 ; CHECK-NEXT:    ret i1 [[CMP]]
281   %shr = lshr i8 80, %a
282   %cmp = icmp eq i8 %shr, 5
283   ret i1 %cmp
286 define i1 @nonexact_lshr_ne_exactdiv(i8 %a) {
287 ; CHECK-LABEL: @nonexact_lshr_ne_exactdiv(
288 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[A:%.*]], 4
289 ; CHECK-NEXT:    ret i1 [[CMP]]
291   %shr = lshr i8 80, %a
292   %cmp = icmp ne i8 %shr, 5
293   ret i1 %cmp
296 define i1 @exact_ashr_eq_exactdiv(i8 %a) {
297 ; CHECK-LABEL: @exact_ashr_eq_exactdiv(
298 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 4
299 ; CHECK-NEXT:    ret i1 [[CMP]]
301   %shr = ashr exact i8 -80, %a
302   %cmp = icmp eq i8 %shr, -5
303   ret i1 %cmp
306 define i1 @exact_ashr_ne_exactdiv(i8 %a) {
307 ; CHECK-LABEL: @exact_ashr_ne_exactdiv(
308 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[A:%.*]], 4
309 ; CHECK-NEXT:    ret i1 [[CMP]]
311   %shr = ashr exact i8 -80, %a
312   %cmp = icmp ne i8 %shr, -5
313   ret i1 %cmp
316 define i1 @nonexact_ashr_eq_exactdiv(i8 %a) {
317 ; CHECK-LABEL: @nonexact_ashr_eq_exactdiv(
318 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 4
319 ; CHECK-NEXT:    ret i1 [[CMP]]
321   %shr = ashr i8 -80, %a
322   %cmp = icmp eq i8 %shr, -5
323   ret i1 %cmp
326 define i1 @nonexact_ashr_ne_exactdiv(i8 %a) {
327 ; CHECK-LABEL: @nonexact_ashr_ne_exactdiv(
328 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[A:%.*]], 4
329 ; CHECK-NEXT:    ret i1 [[CMP]]
331   %shr = ashr i8 -80, %a
332   %cmp = icmp ne i8 %shr, -5
333   ret i1 %cmp
336 define i1 @exact_lshr_eq_noexactdiv(i8 %a) {
337 ; CHECK-LABEL: @exact_lshr_eq_noexactdiv(
338 ; CHECK-NEXT:    ret i1 false
340   %shr = lshr exact i8 80, %a
341   %cmp = icmp eq i8 %shr, 31
342   ret i1 %cmp
345 define i1 @exact_lshr_ne_noexactdiv(i8 %a) {
346 ; CHECK-LABEL: @exact_lshr_ne_noexactdiv(
347 ; CHECK-NEXT:    ret i1 true
349   %shr = lshr exact i8 80, %a
350   %cmp = icmp ne i8 %shr, 31
351   ret i1 %cmp
354 define i1 @nonexact_lshr_eq_noexactdiv(i8 %a) {
355 ; CHECK-LABEL: @nonexact_lshr_eq_noexactdiv(
356 ; CHECK-NEXT:    ret i1 false
358   %shr = lshr i8 80, %a
359   %cmp = icmp eq i8 %shr, 31
360   ret i1 %cmp
363 define i1 @nonexact_lshr_ne_noexactdiv(i8 %a) {
364 ; CHECK-LABEL: @nonexact_lshr_ne_noexactdiv(
365 ; CHECK-NEXT:    ret i1 true
367   %shr = lshr i8 80, %a
368   %cmp = icmp ne i8 %shr, 31
369   ret i1 %cmp
372 define i1 @exact_ashr_eq_noexactdiv(i8 %a) {
373 ; CHECK-LABEL: @exact_ashr_eq_noexactdiv(
374 ; CHECK-NEXT:    ret i1 false
376   %shr = ashr exact i8 -80, %a
377   %cmp = icmp eq i8 %shr, -31
378   ret i1 %cmp
381 define i1 @exact_ashr_ne_noexactdiv(i8 %a) {
382 ; CHECK-LABEL: @exact_ashr_ne_noexactdiv(
383 ; CHECK-NEXT:    ret i1 true
385   %shr = ashr exact i8 -80, %a
386   %cmp = icmp ne i8 %shr, -31
387   ret i1 %cmp
390 define i1 @nonexact_ashr_eq_noexactdiv(i8 %a) {
391 ; CHECK-LABEL: @nonexact_ashr_eq_noexactdiv(
392 ; CHECK-NEXT:    ret i1 false
394   %shr = ashr i8 -80, %a
395   %cmp = icmp eq i8 %shr, -31
396   ret i1 %cmp
399 define i1 @nonexact_ashr_ne_noexactdiv(i8 %a) {
400 ; CHECK-LABEL: @nonexact_ashr_ne_noexactdiv(
401 ; CHECK-NEXT:    ret i1 true
403   %shr = ashr i8 -80, %a
404   %cmp = icmp ne i8 %shr, -31
405   ret i1 %cmp
408 define i1 @nonexact_lshr_eq_noexactlog(i8 %a) {
409 ; CHECK-LABEL: @nonexact_lshr_eq_noexactlog(
410 ; CHECK-NEXT:    ret i1 false
412   %shr = lshr i8 90, %a
413   %cmp = icmp eq i8 %shr, 30
414   ret i1 %cmp
417 define i1 @nonexact_lshr_ne_noexactlog(i8 %a) {
418 ; CHECK-LABEL: @nonexact_lshr_ne_noexactlog(
419 ; CHECK-NEXT:    ret i1 true
421   %shr = lshr i8 90, %a
422   %cmp = icmp ne i8 %shr, 30
423   ret i1 %cmp
426 define i1 @nonexact_ashr_eq_noexactlog(i8 %a) {
427 ; CHECK-LABEL: @nonexact_ashr_eq_noexactlog(
428 ; CHECK-NEXT:    ret i1 false
430   %shr = ashr i8 -90, %a
431   %cmp = icmp eq i8 %shr, -30
432   ret i1 %cmp
435 define i1 @nonexact_ashr_ne_noexactlog(i8 %a) {
436 ; CHECK-LABEL: @nonexact_ashr_ne_noexactlog(
437 ; CHECK-NEXT:    ret i1 true
439   %shr = ashr i8 -90, %a
440   %cmp = icmp ne i8 %shr, -30
441   ret i1 %cmp
444 ; Don't try to fold the entire body of function @PR20945 into a
445 ; single `ret i1 true` statement.
446 ; If %B is equal to 1, then this function would return false.
447 ; As a consequence, the instruction combiner is not allowed to fold %cmp
448 ; to 'true'. Instead, it should replace %cmp with a simpler comparison
449 ; between %B and 1.
451 define i1 @PR20945(i32 %B) {
452 ; CHECK-LABEL: @PR20945(
453 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[B:%.*]], 1
454 ; CHECK-NEXT:    ret i1 [[CMP]]
456   %shr = ashr i32 -9, %B
457   %cmp = icmp ne i32 %shr, -5
458   ret i1 %cmp
461 define i1 @PR21222(i32 %B) {
462 ; CHECK-LABEL: @PR21222(
463 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[B:%.*]], 6
464 ; CHECK-NEXT:    ret i1 [[CMP]]
466   %shr = ashr i32 -93, %B
467   %cmp = icmp eq i32 %shr, -2
468   ret i1 %cmp
471 define i1 @PR24873(i64 %V) {
472 ; CHECK-LABEL: @PR24873(
473 ; CHECK-NEXT:    [[ICMP:%.*]] = icmp ugt i64 [[V:%.*]], 61
474 ; CHECK-NEXT:    ret i1 [[ICMP]]
476   %ashr = ashr i64 -4611686018427387904, %V
477   %icmp = icmp eq i64 %ashr, -1
478   ret i1 %icmp
481 declare void @foo(i32)
483 define i1 @exact_multiuse(i32 %x) {
484 ; CHECK-LABEL: @exact_multiuse(
485 ; CHECK-NEXT:    [[SH:%.*]] = lshr exact i32 [[X:%.*]], 7
486 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X]], 131072
487 ; CHECK-NEXT:    call void @foo(i32 [[SH]])
488 ; CHECK-NEXT:    ret i1 [[CMP]]
490   %sh = lshr exact i32 %x, 7
491   %cmp = icmp eq i32 %sh, 1024
492   call void @foo(i32 %sh)
493   ret i1 %cmp
496 ; PR9343 #1
497 define i1 @ashr_exact_eq_0(i32 %X, i32 %Y) {
498 ; CHECK-LABEL: @ashr_exact_eq_0(
499 ; CHECK-NEXT:    [[B:%.*]] = icmp eq i32 [[X:%.*]], 0
500 ; CHECK-NEXT:    ret i1 [[B]]
502   %A = ashr exact i32 %X, %Y
503   %B = icmp eq i32 %A, 0
504   ret i1 %B
507 define i1 @ashr_exact_ne_0_uses(i32 %X, i32 %Y) {
508 ; CHECK-LABEL: @ashr_exact_ne_0_uses(
509 ; CHECK-NEXT:    [[A:%.*]] = ashr exact i32 [[X:%.*]], [[Y:%.*]]
510 ; CHECK-NEXT:    call void @foo(i32 [[A]])
511 ; CHECK-NEXT:    [[B:%.*]] = icmp ne i32 [[X]], 0
512 ; CHECK-NEXT:    ret i1 [[B]]
514   %A = ashr exact i32 %X, %Y
515   call void @foo(i32 %A)
516   %B = icmp ne i32 %A, 0
517   ret i1 %B
520 define <2 x i1> @ashr_exact_eq_0_vec(<2 x i32> %X, <2 x i32> %Y) {
521 ; CHECK-LABEL: @ashr_exact_eq_0_vec(
522 ; CHECK-NEXT:    [[B:%.*]] = icmp eq <2 x i32> [[X:%.*]], zeroinitializer
523 ; CHECK-NEXT:    ret <2 x i1> [[B]]
525   %A = ashr exact <2 x i32> %X, %Y
526   %B = icmp eq <2 x i32> %A, zeroinitializer
527   ret <2 x i1> %B
530 define i1 @lshr_exact_ne_0(i32 %X, i32 %Y) {
531 ; CHECK-LABEL: @lshr_exact_ne_0(
532 ; CHECK-NEXT:    [[B:%.*]] = icmp ne i32 [[X:%.*]], 0
533 ; CHECK-NEXT:    ret i1 [[B]]
535   %A = lshr exact i32 %X, %Y
536   %B = icmp ne i32 %A, 0
537   ret i1 %B
540 define i1 @lshr_exact_eq_0_uses(i32 %X, i32 %Y) {
541 ; CHECK-LABEL: @lshr_exact_eq_0_uses(
542 ; CHECK-NEXT:    [[A:%.*]] = lshr exact i32 [[X:%.*]], [[Y:%.*]]
543 ; CHECK-NEXT:    call void @foo(i32 [[A]])
544 ; CHECK-NEXT:    [[B:%.*]] = icmp eq i32 [[X]], 0
545 ; CHECK-NEXT:    ret i1 [[B]]
547   %A = lshr exact i32 %X, %Y
548   call void @foo(i32 %A)
549   %B = icmp eq i32 %A, 0
550   ret i1 %B
553 define <2 x i1> @lshr_exact_ne_0_vec(<2 x i32> %X, <2 x i32> %Y) {
554 ; CHECK-LABEL: @lshr_exact_ne_0_vec(
555 ; CHECK-NEXT:    [[B:%.*]] = icmp ne <2 x i32> [[X:%.*]], zeroinitializer
556 ; CHECK-NEXT:    ret <2 x i1> [[B]]
558   %A = lshr exact <2 x i32> %X, %Y
559   %B = icmp ne <2 x i32> %A, zeroinitializer
560   ret <2 x i1> %B
563 ; Verify conversions of ashr+icmp to a sign-bit test.
565 ; negative test, but different transform possible
567 define i1 @ashr_ugt_0(i4 %x) {
568 ; CHECK-LABEL: @ashr_ugt_0(
569 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i4 [[X:%.*]], 1
570 ; CHECK-NEXT:    ret i1 [[R]]
572   %s = ashr i4 %x, 1
573   %r = icmp ugt i4 %s, 0 ; 0b0000
574   ret i1 %r
577 define i1 @ashr_ugt_1(i4 %x) {
578 ; CHECK-LABEL: @ashr_ugt_1(
579 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i4 [[X:%.*]], 3
580 ; CHECK-NEXT:    ret i1 [[R]]
582   %s = ashr i4 %x, 1
583   %r = icmp ugt i4 %s, 1 ; 0b0001
584   ret i1 %r
587 define i1 @ashr_ugt_2(i4 %x) {
588 ; CHECK-LABEL: @ashr_ugt_2(
589 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i4 [[X:%.*]], 5
590 ; CHECK-NEXT:    ret i1 [[R]]
592   %s = ashr i4 %x, 1
593   %r = icmp ugt i4 %s, 2 ; 0b0010
594   ret i1 %r
597 define i1 @ashr_ugt_3(i4 %x) {
598 ; CHECK-LABEL: @ashr_ugt_3(
599 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i4 [[X:%.*]], 0
600 ; CHECK-NEXT:    ret i1 [[R]]
602   %s = ashr i4 %x, 1
603   %r = icmp ugt i4 %s, 3 ; 0b0011
604   ret i1 %r
607 define i1 @ashr_ugt_4(i4 %x) {
608 ; CHECK-LABEL: @ashr_ugt_4(
609 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i4 [[X:%.*]], 0
610 ; CHECK-NEXT:    ret i1 [[R]]
612   %s = ashr i4 %x, 1
613   %r = icmp ugt i4 %s, 4 ; 0b0100
614   ret i1 %r
617 define i1 @ashr_ugt_5(i4 %x) {
618 ; CHECK-LABEL: @ashr_ugt_5(
619 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i4 [[X:%.*]], 0
620 ; CHECK-NEXT:    ret i1 [[R]]
622   %s = ashr i4 %x, 1
623   %r = icmp ugt i4 %s, 5 ; 0b0101
624   ret i1 %r
627 define i1 @ashr_ugt_6(i4 %x) {
628 ; CHECK-LABEL: @ashr_ugt_6(
629 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i4 [[X:%.*]], 0
630 ; CHECK-NEXT:    ret i1 [[R]]
632   %s = ashr i4 %x, 1
633   %r = icmp ugt i4 %s, 6 ; 0b0110
634   ret i1 %r
637 define i1 @ashr_ugt_7(i4 %x) {
638 ; CHECK-LABEL: @ashr_ugt_7(
639 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i4 [[X:%.*]], 0
640 ; CHECK-NEXT:    ret i1 [[R]]
642   %s = ashr i4 %x, 1
643   %r = icmp ugt i4 %s, 7 ; 0b0111
644   ret i1 %r
647 define i1 @ashr_ugt_8(i4 %x) {
648 ; CHECK-LABEL: @ashr_ugt_8(
649 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i4 [[X:%.*]], 0
650 ; CHECK-NEXT:    ret i1 [[R]]
652   %s = ashr i4 %x, 1
653   %r = icmp ugt i4 %s, 8 ; 0b1000
654   ret i1 %r
657 define i1 @ashr_ugt_9(i4 %x) {
658 ; CHECK-LABEL: @ashr_ugt_9(
659 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i4 [[X:%.*]], 0
660 ; CHECK-NEXT:    ret i1 [[R]]
662   %s = ashr i4 %x, 1
663   %r = icmp ugt i4 %s, 9 ; 0b1001
664   ret i1 %r
667 define i1 @ashr_ugt_10(i4 %x) {
668 ; CHECK-LABEL: @ashr_ugt_10(
669 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i4 [[X:%.*]], 0
670 ; CHECK-NEXT:    ret i1 [[R]]
672   %s = ashr i4 %x, 1
673   %r = icmp ugt i4 %s, 10 ; 0b1010
674   ret i1 %r
677 define i1 @ashr_ugt_11(i4 %x) {
678 ; CHECK-LABEL: @ashr_ugt_11(
679 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i4 [[X:%.*]], 0
680 ; CHECK-NEXT:    ret i1 [[R]]
682   %s = ashr i4 %x, 1
683   %r = icmp ugt i4 %s, 11 ; 0b1011
684   ret i1 %r
687 define i1 @ashr_ugt_12(i4 %x) {
688 ; CHECK-LABEL: @ashr_ugt_12(
689 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i4 [[X:%.*]], -7
690 ; CHECK-NEXT:    ret i1 [[R]]
692   %s = ashr i4 %x, 1
693   %r = icmp ugt i4 %s, 12 ; 0b1100
694   ret i1 %r
697 define i1 @ashr_ugt_13(i4 %x) {
698 ; CHECK-LABEL: @ashr_ugt_13(
699 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i4 [[X:%.*]], -5
700 ; CHECK-NEXT:    ret i1 [[R]]
702   %s = ashr i4 %x, 1
703   %r = icmp ugt i4 %s, 13 ; 0b1101
704   ret i1 %r
707 ; negative test, but different transform possible
709 define i1 @ashr_ugt_14(i4 %x) {
710 ; CHECK-LABEL: @ashr_ugt_14(
711 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i4 [[X:%.*]], -3
712 ; CHECK-NEXT:    ret i1 [[R]]
714   %s = ashr i4 %x, 1
715   %r = icmp ugt i4 %s, 14 ; 0b1110
716   ret i1 %r
719 ; negative test, but simplifies
721 define i1 @ashr_ugt_15(i4 %x) {
722 ; CHECK-LABEL: @ashr_ugt_15(
723 ; CHECK-NEXT:    ret i1 false
725   %s = ashr i4 %x, 1
726   %r = icmp ugt i4 %s, 15 ; 0b1111
727   ret i1 %r
730 ; negative test, but simplifies
732 define i1 @ashr_ult_0(i4 %x) {
733 ; CHECK-LABEL: @ashr_ult_0(
734 ; CHECK-NEXT:    ret i1 false
736   %s = ashr i4 %x, 1
737   %r = icmp ult i4 %s, 0 ; 0b0000
738   ret i1 %r
741 ; negative test, but different transform possible
743 define i1 @ashr_ult_1(i4 %x) {
744 ; CHECK-LABEL: @ashr_ult_1(
745 ; CHECK-NEXT:    [[R:%.*]] = icmp ult i4 [[X:%.*]], 2
746 ; CHECK-NEXT:    ret i1 [[R]]
748   %s = ashr i4 %x, 1
749   %r = icmp ult i4 %s, 1 ; 0b0001
750   ret i1 %r
753 ; negative test
755 define i1 @ashr_ult_2(i4 %x) {
756 ; CHECK-LABEL: @ashr_ult_2(
757 ; CHECK-NEXT:    [[R:%.*]] = icmp ult i4 [[X:%.*]], 4
758 ; CHECK-NEXT:    ret i1 [[R]]
760   %s = ashr i4 %x, 1
761   %r = icmp ult i4 %s, 2 ; 0b0010
762   ret i1 %r
765 ; negative test
767 define i1 @ashr_ult_3(i4 %x) {
768 ; CHECK-LABEL: @ashr_ult_3(
769 ; CHECK-NEXT:    [[R:%.*]] = icmp ult i4 [[X:%.*]], 6
770 ; CHECK-NEXT:    ret i1 [[R]]
772   %s = ashr i4 %x, 1
773   %r = icmp ult i4 %s, 3 ; 0b0011
774   ret i1 %r
777 define i1 @ashr_ult_4(i4 %x) {
778 ; CHECK-LABEL: @ashr_ult_4(
779 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i4 [[X:%.*]], -1
780 ; CHECK-NEXT:    ret i1 [[R]]
782   %s = ashr i4 %x, 1
783   %r = icmp ult i4 %s, 4 ; 0b0100
784   ret i1 %r
787 define i1 @ashr_ult_5(i4 %x) {
788 ; CHECK-LABEL: @ashr_ult_5(
789 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i4 [[X:%.*]], -1
790 ; CHECK-NEXT:    ret i1 [[R]]
792   %s = ashr i4 %x, 1
793   %r = icmp ult i4 %s, 5 ; 0b0101
794   ret i1 %r
797 define i1 @ashr_ult_6(i4 %x) {
798 ; CHECK-LABEL: @ashr_ult_6(
799 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i4 [[X:%.*]], -1
800 ; CHECK-NEXT:    ret i1 [[R]]
802   %s = ashr i4 %x, 1
803   %r = icmp ult i4 %s, 6 ; 0b0110
804   ret i1 %r
807 define i1 @ashr_ult_7(i4 %x) {
808 ; CHECK-LABEL: @ashr_ult_7(
809 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i4 [[X:%.*]], -1
810 ; CHECK-NEXT:    ret i1 [[R]]
812   %s = ashr i4 %x, 1
813   %r = icmp ult i4 %s, 7 ; 0b0111
814   ret i1 %r
817 define i1 @ashr_ult_8(i4 %x) {
818 ; CHECK-LABEL: @ashr_ult_8(
819 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i4 [[X:%.*]], -1
820 ; CHECK-NEXT:    ret i1 [[R]]
822   %s = ashr i4 %x, 1
823   %r = icmp ult i4 %s, 8 ; 0b1000
824   ret i1 %r
827 define i1 @ashr_ult_9(i4 %x) {
828 ; CHECK-LABEL: @ashr_ult_9(
829 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i4 [[X:%.*]], -1
830 ; CHECK-NEXT:    ret i1 [[R]]
832   %s = ashr i4 %x, 1
833   %r = icmp ult i4 %s, 9 ; 0b1001
834   ret i1 %r
837 define i1 @ashr_ult_10(i4 %x) {
838 ; CHECK-LABEL: @ashr_ult_10(
839 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i4 [[X:%.*]], -1
840 ; CHECK-NEXT:    ret i1 [[R]]
842   %s = ashr i4 %x, 1
843   %r = icmp ult i4 %s, 10 ; 0b1010
844   ret i1 %r
847 define i1 @ashr_ult_11(i4 %x) {
848 ; CHECK-LABEL: @ashr_ult_11(
849 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i4 [[X:%.*]], -1
850 ; CHECK-NEXT:    ret i1 [[R]]
852   %s = ashr i4 %x, 1
853   %r = icmp ult i4 %s, 11 ; 0b1011
854   ret i1 %r
857 ; negative test
859 define i1 @ashr_ult_12(i4 %x) {
860 ; CHECK-LABEL: @ashr_ult_12(
861 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i4 [[X:%.*]], -1
862 ; CHECK-NEXT:    ret i1 [[R]]
864   %s = ashr i4 %x, 1
865   %r = icmp ult i4 %s, 12 ; 0b1100
866   ret i1 %r
869 ; negative test
871 define i1 @ashr_ult_13(i4 %x) {
872 ; CHECK-LABEL: @ashr_ult_13(
873 ; CHECK-NEXT:    [[R:%.*]] = icmp ult i4 [[X:%.*]], -6
874 ; CHECK-NEXT:    ret i1 [[R]]
876   %s = ashr i4 %x, 1
877   %r = icmp ult i4 %s, 13 ; 0b1101
878   ret i1 %r
881 ; negative test
883 define i1 @ashr_ult_14(i4 %x) {
884 ; CHECK-LABEL: @ashr_ult_14(
885 ; CHECK-NEXT:    [[R:%.*]] = icmp ult i4 [[X:%.*]], -4
886 ; CHECK-NEXT:    ret i1 [[R]]
888   %s = ashr i4 %x, 1
889   %r = icmp ult i4 %s, 14 ; 0b1110
890   ret i1 %r
893 ; negative test, but different transform possible
895 define i1 @ashr_ult_15(i4 %x) {
896 ; CHECK-LABEL: @ashr_ult_15(
897 ; CHECK-NEXT:    [[R:%.*]] = icmp ult i4 [[X:%.*]], -2
898 ; CHECK-NEXT:    ret i1 [[R]]
900   %s = ashr i4 %x, 1
901   %r = icmp ult i4 %s, 15 ; 0b1111
902   ret i1 %r
905 define i1 @lshr_eq_0_multiuse(i8 %x) {
906 ; CHECK-LABEL: @lshr_eq_0_multiuse(
907 ; CHECK-NEXT:    [[S:%.*]] = lshr i8 [[X:%.*]], 2
908 ; CHECK-NEXT:    call void @use(i8 [[S]])
909 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[X]], 4
910 ; CHECK-NEXT:    ret i1 [[C]]
912   %s = lshr i8 %x, 2
913   call void @use(i8 %s)
914   %c = icmp eq i8 %s, 0
915   ret i1 %c
918 define i1 @lshr_ne_0_multiuse(i8 %x) {
919 ; CHECK-LABEL: @lshr_ne_0_multiuse(
920 ; CHECK-NEXT:    [[S:%.*]] = lshr i8 [[X:%.*]], 2
921 ; CHECK-NEXT:    call void @use(i8 [[S]])
922 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 [[X]], 3
923 ; CHECK-NEXT:    ret i1 [[C]]
925   %s = lshr i8 %x, 2
926   call void @use(i8 %s)
927   %c = icmp ne i8 %s, 0
928   ret i1 %c
931 define i1 @ashr_eq_0_multiuse(i8 %x) {
932 ; CHECK-LABEL: @ashr_eq_0_multiuse(
933 ; CHECK-NEXT:    [[S:%.*]] = ashr i8 [[X:%.*]], 2
934 ; CHECK-NEXT:    call void @use(i8 [[S]])
935 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[X]], 4
936 ; CHECK-NEXT:    ret i1 [[C]]
938   %s = ashr i8 %x, 2
939   call void @use(i8 %s)
940   %c = icmp eq i8 %s, 0
941   ret i1 %c
944 define i1 @ashr_ne_0_multiuse(i8 %x) {
945 ; CHECK-LABEL: @ashr_ne_0_multiuse(
946 ; CHECK-NEXT:    [[S:%.*]] = ashr i8 [[X:%.*]], 2
947 ; CHECK-NEXT:    call void @use(i8 [[S]])
948 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 [[X]], 3
949 ; CHECK-NEXT:    ret i1 [[C]]
951   %s = ashr i8 %x, 2
952   call void @use(i8 %s)
953   %c = icmp ne i8 %s, 0
954   ret i1 %c
957 define i1 @lshr_exact_eq_0_multiuse(i8 %x) {
958 ; CHECK-LABEL: @lshr_exact_eq_0_multiuse(
959 ; CHECK-NEXT:    [[S:%.*]] = lshr exact i8 [[X:%.*]], 2
960 ; CHECK-NEXT:    call void @use(i8 [[S]])
961 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[X]], 0
962 ; CHECK-NEXT:    ret i1 [[C]]
964   %s = lshr exact i8 %x, 2
965   call void @use(i8 %s)
966   %c = icmp eq i8 %s, 0
967   ret i1 %c
970 define i1 @lshr_exact_ne_0_multiuse(i8 %x) {
971 ; CHECK-LABEL: @lshr_exact_ne_0_multiuse(
972 ; CHECK-NEXT:    [[S:%.*]] = lshr exact i8 [[X:%.*]], 2
973 ; CHECK-NEXT:    call void @use(i8 [[S]])
974 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[X]], 0
975 ; CHECK-NEXT:    ret i1 [[C]]
977   %s = lshr exact i8 %x, 2
978   call void @use(i8 %s)
979   %c = icmp ne i8 %s, 0
980   ret i1 %c
983 define i1 @ashr_exact_eq_0_multiuse(i8 %x) {
984 ; CHECK-LABEL: @ashr_exact_eq_0_multiuse(
985 ; CHECK-NEXT:    [[S:%.*]] = ashr exact i8 [[X:%.*]], 2
986 ; CHECK-NEXT:    call void @use(i8 [[S]])
987 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[X]], 0
988 ; CHECK-NEXT:    ret i1 [[C]]
990   %s = ashr exact i8 %x, 2
991   call void @use(i8 %s)
992   %c = icmp eq i8 %s, 0
993   ret i1 %c
996 define i1 @ashr_exact_ne_0_multiuse(i8 %x) {
997 ; CHECK-LABEL: @ashr_exact_ne_0_multiuse(
998 ; CHECK-NEXT:    [[S:%.*]] = ashr exact i8 [[X:%.*]], 2
999 ; CHECK-NEXT:    call void @use(i8 [[S]])
1000 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[X]], 0
1001 ; CHECK-NEXT:    ret i1 [[C]]
1003   %s = ashr exact i8 %x, 2
1004   call void @use(i8 %s)
1005   %c = icmp ne i8 %s, 0
1006   ret i1 %c
1009 define i1 @lshr_pow2_ugt(i8 %x) {
1010 ; CHECK-LABEL: @lshr_pow2_ugt(
1011 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[X:%.*]], 0
1012 ; CHECK-NEXT:    ret i1 [[R]]
1014   %s = lshr i8 2, %x
1015   %r = icmp ugt i8 %s, 1
1016   ret i1 %r
1019 define i1 @lshr_pow2_ugt_use(i8 %x) {
1020 ; CHECK-LABEL: @lshr_pow2_ugt_use(
1021 ; CHECK-NEXT:    [[S:%.*]] = lshr i8 -128, [[X:%.*]]
1022 ; CHECK-NEXT:    call void @use(i8 [[S]])
1023 ; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[X]], 5
1024 ; CHECK-NEXT:    ret i1 [[R]]
1026   %s = lshr i8 128, %x
1027   call void @use(i8 %s)
1028   %r = icmp ugt i8 %s, 5
1029   ret i1 %r
1032 define <2 x i1> @lshr_pow2_ugt_vec(<2 x i8> %x) {
1033 ; CHECK-LABEL: @lshr_pow2_ugt_vec(
1034 ; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[X:%.*]], zeroinitializer
1035 ; CHECK-NEXT:    ret <2 x i1> [[R]]
1037   %s = lshr <2 x i8> <i8 8, i8 8>, %x
1038   %r = icmp ugt <2 x i8> %s, <i8 6, i8 6>
1039   ret <2 x i1> %r
1042 ; negative test - need power-of-2
1044 define i1 @lshr_not_pow2_ugt(i8 %x) {
1045 ; CHECK-LABEL: @lshr_not_pow2_ugt(
1046 ; CHECK-NEXT:    [[S:%.*]] = lshr i8 3, [[X:%.*]]
1047 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[S]], 1
1048 ; CHECK-NEXT:    ret i1 [[R]]
1050   %s = lshr i8 3, %x
1051   %r = icmp ugt i8 %s, 1
1052   ret i1 %r
1055 define i1 @lshr_pow2_ugt1(i8 %x) {
1056 ; CHECK-LABEL: @lshr_pow2_ugt1(
1057 ; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[X:%.*]], 7
1058 ; CHECK-NEXT:    ret i1 [[R]]
1060   %s = lshr i8 128, %x
1061   %r = icmp ugt i8 %s, 1
1062   ret i1 %r
1065 ; negative test - need logical shift
1067 define i1 @ashr_pow2_ugt(i8 %x) {
1068 ; CHECK-LABEL: @ashr_pow2_ugt(
1069 ; CHECK-NEXT:    [[S:%.*]] = ashr i8 -128, [[X:%.*]]
1070 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[S]], -96
1071 ; CHECK-NEXT:    ret i1 [[R]]
1073   %s = ashr i8 128, %x
1074   %r = icmp ugt i8 %s, 160
1075   ret i1 %r
1078 ; negative test - need unsigned pred
1080 define i1 @lshr_pow2_sgt(i8 %x) {
1081 ; CHECK-LABEL: @lshr_pow2_sgt(
1082 ; CHECK-NEXT:    [[S:%.*]] = lshr i8 -128, [[X:%.*]]
1083 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i8 [[S]], 3
1084 ; CHECK-NEXT:    ret i1 [[R]]
1086   %s = lshr i8 128, %x
1087   %r = icmp sgt i8 %s, 3
1088   ret i1 %r
1091 declare void @use(i8)