[InstCombine] Signed saturation patterns
[llvm-core.git] / test / CodeGen / X86 / test-vs-bittest.ll
blob2f93ad58ad32af04506b7c1028a9771603d0aca4
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
4 define void @test64(i64 inreg %x) {
5 ; CHECK-LABEL: test64:
6 ; CHECK:       # %bb.0:
7 ; CHECK-NEXT:    pushq %rax
8 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
9 ; CHECK-NEXT:    testl $2048, %edi # imm = 0x800
10 ; CHECK-NEXT:    jne .LBB0_2
11 ; CHECK-NEXT:  # %bb.1: # %yes
12 ; CHECK-NEXT:    callq bar
13 ; CHECK-NEXT:  .LBB0_2: # %no
14 ; CHECK-NEXT:    popq %rax
15 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
16 ; CHECK-NEXT:    retq
17   %t = and i64 %x, 2048
18   %s = icmp eq i64 %t, 0
19   br i1 %s, label %yes, label %no
21 yes:
22   call void @bar()
23   ret void
24 no:
25   ret void
28 define void @test64_optsize(i64 inreg %x) optsize {
29 ; CHECK-LABEL: test64_optsize:
30 ; CHECK:       # %bb.0:
31 ; CHECK-NEXT:    pushq %rax
32 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
33 ; CHECK-NEXT:    btl $11, %edi
34 ; CHECK-NEXT:    jb .LBB1_2
35 ; CHECK-NEXT:  # %bb.1: # %yes
36 ; CHECK-NEXT:    callq bar
37 ; CHECK-NEXT:  .LBB1_2: # %no
38 ; CHECK-NEXT:    popq %rax
39 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
40 ; CHECK-NEXT:    retq
41   %t = and i64 %x, 2048
42   %s = icmp eq i64 %t, 0
43   br i1 %s, label %yes, label %no
45 yes:
46   call void @bar()
47   ret void
48 no:
49   ret void
52 ; This test is identical to test64 above with only the destination of the br
53 ; reversed. This somehow causes the two functions to get slightly different
54 ; initial IR. One has an extra invert of the setcc. This previous caused one
55 ; the functions to use a BT while the other used a TEST due to another DAG
56 ; combine messing with an expected canonical form.
57 define void @test64_2(i64 inreg %x) {
58 ; CHECK-LABEL: test64_2:
59 ; CHECK:       # %bb.0:
60 ; CHECK-NEXT:    pushq %rax
61 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
62 ; CHECK-NEXT:    testl $2048, %edi # imm = 0x800
63 ; CHECK-NEXT:    je .LBB2_2
64 ; CHECK-NEXT:  # %bb.1: # %yes
65 ; CHECK-NEXT:    callq bar
66 ; CHECK-NEXT:  .LBB2_2: # %no
67 ; CHECK-NEXT:    popq %rax
68 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
69 ; CHECK-NEXT:    retq
70   %t = and i64 %x, 2048
71   %s = icmp eq i64 %t, 0
72   br i1 %s, label %no, label %yes
74 yes:
75   call void @bar()
76   ret void
77 no:
78   ret void
81 define void @test64_optsize_2(i64 inreg %x) optsize {
82 ; CHECK-LABEL: test64_optsize_2:
83 ; CHECK:       # %bb.0:
84 ; CHECK-NEXT:    pushq %rax
85 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
86 ; CHECK-NEXT:    btl $11, %edi
87 ; CHECK-NEXT:    jae .LBB3_2
88 ; CHECK-NEXT:  # %bb.1: # %yes
89 ; CHECK-NEXT:    callq bar
90 ; CHECK-NEXT:  .LBB3_2: # %no
91 ; CHECK-NEXT:    popq %rax
92 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
93 ; CHECK-NEXT:    retq
94   %t = and i64 %x, 2048
95   %s = icmp eq i64 %t, 0
96   br i1 %s, label %no, label %yes
98 yes:
99   call void @bar()
100   ret void
102   ret void
105 define void @test64_3(i64 inreg %x) {
106 ; CHECK-LABEL: test64_3:
107 ; CHECK:       # %bb.0:
108 ; CHECK-NEXT:    pushq %rax
109 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
110 ; CHECK-NEXT:    btq $32, %rdi
111 ; CHECK-NEXT:    jb .LBB4_2
112 ; CHECK-NEXT:  # %bb.1: # %yes
113 ; CHECK-NEXT:    callq bar
114 ; CHECK-NEXT:  .LBB4_2: # %no
115 ; CHECK-NEXT:    popq %rax
116 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
117 ; CHECK-NEXT:    retq
118   %t = and i64 %x, 4294967296
119   %s = icmp eq i64 %t, 0
120   br i1 %s, label %yes, label %no
122 yes:
123   call void @bar()
124   ret void
126   ret void
129 define void @test64_optsize_3(i64 inreg %x) optsize {
130 ; CHECK-LABEL: test64_optsize_3:
131 ; CHECK:       # %bb.0:
132 ; CHECK-NEXT:    pushq %rax
133 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
134 ; CHECK-NEXT:    btq $32, %rdi
135 ; CHECK-NEXT:    jb .LBB5_2
136 ; CHECK-NEXT:  # %bb.1: # %yes
137 ; CHECK-NEXT:    callq bar
138 ; CHECK-NEXT:  .LBB5_2: # %no
139 ; CHECK-NEXT:    popq %rax
140 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
141 ; CHECK-NEXT:    retq
142   %t = and i64 %x, 4294967296
143   %s = icmp eq i64 %t, 0
144   br i1 %s, label %yes, label %no
146 yes:
147   call void @bar()
148   ret void
150   ret void
153 define void @test64_4(i64 inreg %x) {
154 ; CHECK-LABEL: test64_4:
155 ; CHECK:       # %bb.0:
156 ; CHECK-NEXT:    pushq %rax
157 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
158 ; CHECK-NEXT:    btq $32, %rdi
159 ; CHECK-NEXT:    jae .LBB6_2
160 ; CHECK-NEXT:  # %bb.1: # %yes
161 ; CHECK-NEXT:    callq bar
162 ; CHECK-NEXT:  .LBB6_2: # %no
163 ; CHECK-NEXT:    popq %rax
164 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
165 ; CHECK-NEXT:    retq
166   %t = and i64 %x, 4294967296
167   %s = icmp eq i64 %t, 0
168   br i1 %s, label %no, label %yes
170 yes:
171   call void @bar()
172   ret void
174   ret void
177 define void @test64_optsize_4(i64 inreg %x) optsize {
178 ; CHECK-LABEL: test64_optsize_4:
179 ; CHECK:       # %bb.0:
180 ; CHECK-NEXT:    pushq %rax
181 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
182 ; CHECK-NEXT:    btq $32, %rdi
183 ; CHECK-NEXT:    jae .LBB7_2
184 ; CHECK-NEXT:  # %bb.1: # %yes
185 ; CHECK-NEXT:    callq bar
186 ; CHECK-NEXT:  .LBB7_2: # %no
187 ; CHECK-NEXT:    popq %rax
188 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
189 ; CHECK-NEXT:    retq
190   %t = and i64 %x, 4294967296
191   %s = icmp eq i64 %t, 0
192   br i1 %s, label %no, label %yes
194 yes:
195   call void @bar()
196   ret void
198   ret void
201 define void @test32(i32 inreg %x) {
202 ; CHECK-LABEL: test32:
203 ; CHECK:       # %bb.0:
204 ; CHECK-NEXT:    pushq %rax
205 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
206 ; CHECK-NEXT:    testl $2048, %edi # imm = 0x800
207 ; CHECK-NEXT:    jne .LBB8_2
208 ; CHECK-NEXT:  # %bb.1: # %yes
209 ; CHECK-NEXT:    callq bar
210 ; CHECK-NEXT:  .LBB8_2: # %no
211 ; CHECK-NEXT:    popq %rax
212 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
213 ; CHECK-NEXT:    retq
214   %t = and i32 %x, 2048
215   %s = icmp eq i32 %t, 0
216   br i1 %s, label %yes, label %no
218 yes:
219   call void @bar()
220   ret void
222   ret void
225 define void @test32_optsize(i32 inreg %x) optsize {
226 ; CHECK-LABEL: test32_optsize:
227 ; CHECK:       # %bb.0:
228 ; CHECK-NEXT:    pushq %rax
229 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
230 ; CHECK-NEXT:    btl $11, %edi
231 ; CHECK-NEXT:    jb .LBB9_2
232 ; CHECK-NEXT:  # %bb.1: # %yes
233 ; CHECK-NEXT:    callq bar
234 ; CHECK-NEXT:  .LBB9_2: # %no
235 ; CHECK-NEXT:    popq %rax
236 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
237 ; CHECK-NEXT:    retq
238   %t = and i32 %x, 2048
239   %s = icmp eq i32 %t, 0
240   br i1 %s, label %yes, label %no
242 yes:
243   call void @bar()
244   ret void
246   ret void
249 define void @test32_2(i32 inreg %x) {
250 ; CHECK-LABEL: test32_2:
251 ; CHECK:       # %bb.0:
252 ; CHECK-NEXT:    pushq %rax
253 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
254 ; CHECK-NEXT:    testl $2048, %edi # imm = 0x800
255 ; CHECK-NEXT:    je .LBB10_2
256 ; CHECK-NEXT:  # %bb.1: # %yes
257 ; CHECK-NEXT:    callq bar
258 ; CHECK-NEXT:  .LBB10_2: # %no
259 ; CHECK-NEXT:    popq %rax
260 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
261 ; CHECK-NEXT:    retq
262   %t = and i32 %x, 2048
263   %s = icmp eq i32 %t, 0
264   br i1 %s, label %no, label %yes
266 yes:
267   call void @bar()
268   ret void
270   ret void
273 define void @test32_optsize_2(i32 inreg %x) optsize {
274 ; CHECK-LABEL: test32_optsize_2:
275 ; CHECK:       # %bb.0:
276 ; CHECK-NEXT:    pushq %rax
277 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
278 ; CHECK-NEXT:    btl $11, %edi
279 ; CHECK-NEXT:    jae .LBB11_2
280 ; CHECK-NEXT:  # %bb.1: # %yes
281 ; CHECK-NEXT:    callq bar
282 ; CHECK-NEXT:  .LBB11_2: # %no
283 ; CHECK-NEXT:    popq %rax
284 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
285 ; CHECK-NEXT:    retq
286   %t = and i32 %x, 2048
287   %s = icmp eq i32 %t, 0
288   br i1 %s, label %no, label %yes
290 yes:
291   call void @bar()
292   ret void
294   ret void
297 define void @test16(i16 inreg %x) {
298 ; CHECK-LABEL: test16:
299 ; CHECK:       # %bb.0:
300 ; CHECK-NEXT:    pushq %rax
301 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
302 ; CHECK-NEXT:    testl $2048, %edi # imm = 0x800
303 ; CHECK-NEXT:    jne .LBB12_2
304 ; CHECK-NEXT:  # %bb.1: # %yes
305 ; CHECK-NEXT:    callq bar
306 ; CHECK-NEXT:  .LBB12_2: # %no
307 ; CHECK-NEXT:    popq %rax
308 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
309 ; CHECK-NEXT:    retq
310   %t = and i16 %x, 2048
311   %s = icmp eq i16 %t, 0
312   br i1 %s, label %yes, label %no
314 yes:
315   call void @bar()
316   ret void
318   ret void
321 define void @test16_optsize(i16 inreg %x) optsize {
322 ; CHECK-LABEL: test16_optsize:
323 ; CHECK:       # %bb.0:
324 ; CHECK-NEXT:    pushq %rax
325 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
326 ; CHECK-NEXT:    btl $11, %edi
327 ; CHECK-NEXT:    jb .LBB13_2
328 ; CHECK-NEXT:  # %bb.1: # %yes
329 ; CHECK-NEXT:    callq bar
330 ; CHECK-NEXT:  .LBB13_2: # %no
331 ; CHECK-NEXT:    popq %rax
332 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
333 ; CHECK-NEXT:    retq
334   %t = and i16 %x, 2048
335   %s = icmp eq i16 %t, 0
336   br i1 %s, label %yes, label %no
338 yes:
339   call void @bar()
340   ret void
342   ret void
345 define void @test16_2(i16 inreg %x) {
346 ; CHECK-LABEL: test16_2:
347 ; CHECK:       # %bb.0:
348 ; CHECK-NEXT:    pushq %rax
349 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
350 ; CHECK-NEXT:    testl $2048, %edi # imm = 0x800
351 ; CHECK-NEXT:    je .LBB14_2
352 ; CHECK-NEXT:  # %bb.1: # %yes
353 ; CHECK-NEXT:    callq bar
354 ; CHECK-NEXT:  .LBB14_2: # %no
355 ; CHECK-NEXT:    popq %rax
356 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
357 ; CHECK-NEXT:    retq
358   %t = and i16 %x, 2048
359   %s = icmp eq i16 %t, 0
360   br i1 %s, label %no, label %yes
362 yes:
363   call void @bar()
364   ret void
366   ret void
369 define void @test16_optsize_2(i16 inreg %x) optsize {
370 ; CHECK-LABEL: test16_optsize_2:
371 ; CHECK:       # %bb.0:
372 ; CHECK-NEXT:    pushq %rax
373 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
374 ; CHECK-NEXT:    btl $11, %edi
375 ; CHECK-NEXT:    jae .LBB15_2
376 ; CHECK-NEXT:  # %bb.1: # %yes
377 ; CHECK-NEXT:    callq bar
378 ; CHECK-NEXT:  .LBB15_2: # %no
379 ; CHECK-NEXT:    popq %rax
380 ; CHECK-NEXT:    .cfi_def_cfa_offset 8
381 ; CHECK-NEXT:    retq
382   %t = and i16 %x, 2048
383   %s = icmp eq i16 %t, 0
384   br i1 %s, label %no, label %yes
386 yes:
387   call void @bar()
388   ret void
390   ret void
393 define i64 @is_upper_bit_clear_i64(i64 %x) {
394 ; CHECK-LABEL: is_upper_bit_clear_i64:
395 ; CHECK:       # %bb.0:
396 ; CHECK-NEXT:    xorl %eax, %eax
397 ; CHECK-NEXT:    btq $37, %rdi
398 ; CHECK-NEXT:    setae %al
399 ; CHECK-NEXT:    retq
400   %sh = lshr i64 %x, 37
401   %m = and i64 %sh, 1
402   %r = xor i64 %m, 1
403   ret i64 %r
406 define i64 @is_lower_bit_clear_i64(i64 %x) {
407 ; CHECK-LABEL: is_lower_bit_clear_i64:
408 ; CHECK:       # %bb.0:
409 ; CHECK-NEXT:    xorl %eax, %eax
410 ; CHECK-NEXT:    testl $134217728, %edi # imm = 0x8000000
411 ; CHECK-NEXT:    sete %al
412 ; CHECK-NEXT:    retq
413   %sh = lshr i64 %x, 27
414   %m = and i64 %sh, 1
415   %r = xor i64 %m, 1
416   ret i64 %r
419 define i32 @is_bit_clear_i32(i32 %x) {
420 ; CHECK-LABEL: is_bit_clear_i32:
421 ; CHECK:       # %bb.0:
422 ; CHECK-NEXT:    xorl %eax, %eax
423 ; CHECK-NEXT:    testl $134217728, %edi # imm = 0x8000000
424 ; CHECK-NEXT:    sete %al
425 ; CHECK-NEXT:    retq
426   %sh = lshr i32 %x, 27
427   %n = xor i32 %sh, -1
428   %r = and i32 %n, 1
429   ret i32 %r
432 define i16 @is_bit_clear_i16(i16 %x) {
433 ; CHECK-LABEL: is_bit_clear_i16:
434 ; CHECK:       # %bb.0:
435 ; CHECK-NEXT:    xorl %eax, %eax
436 ; CHECK-NEXT:    testb $-128, %dil
437 ; CHECK-NEXT:    sete %al
438 ; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
439 ; CHECK-NEXT:    retq
440   %sh = lshr i16 %x, 7
441   %m = and i16 %sh, 1
442   %r = xor i16 %m, 1
443   ret i16 %r
446 define i8 @is_bit_clear_i8(i8 %x) {
447 ; CHECK-LABEL: is_bit_clear_i8:
448 ; CHECK:       # %bb.0:
449 ; CHECK-NEXT:    testb $8, %dil
450 ; CHECK-NEXT:    sete %al
451 ; CHECK-NEXT:    retq
452   %sh = lshr i8 %x, 3
453   %m = and i8 %sh, 1
454   %r = xor i8 %m, 1
455   ret i8 %r
458 ; TODO: We could use bt/test on the 64-bit value.
460 define i8 @overshift(i64 %x) {
461 ; CHECK-LABEL: overshift:
462 ; CHECK:       # %bb.0:
463 ; CHECK-NEXT:    movq %rdi, %rax
464 ; CHECK-NEXT:    shrq $42, %rax
465 ; CHECK-NEXT:    notb %al
466 ; CHECK-NEXT:    andb $1, %al
467 ; CHECK-NEXT:    # kill: def $al killed $al killed $rax
468 ; CHECK-NEXT:    retq
469   %a = lshr i64 %x, 42
470   %t = trunc i64 %a to i8
471   %n = xor i8 %t, -1
472   %r = and i8 %n, 1
473   ret i8 %r
476 define i32 @setcc_is_bit_clear(i32 %x) {
477 ; CHECK-LABEL: setcc_is_bit_clear:
478 ; CHECK:       # %bb.0:
479 ; CHECK-NEXT:    xorl %eax, %eax
480 ; CHECK-NEXT:    testl $1024, %edi # imm = 0x400
481 ; CHECK-NEXT:    sete %al
482 ; CHECK-NEXT:    retq
483   %a1 = and i32 %x, 1024
484   %b1 = icmp eq i32 %a1, 0
485   %r = zext i1 %b1 to i32
486   ret i32 %r
489 define i32 @is_bit_set(i32 %x) {
490 ; CHECK-LABEL: is_bit_set:
491 ; CHECK:       # %bb.0:
492 ; CHECK-NEXT:    movl %edi, %eax
493 ; CHECK-NEXT:    shrl $10, %eax
494 ; CHECK-NEXT:    andl $1, %eax
495 ; CHECK-NEXT:    retq
496   %sh = lshr i32 %x, 10
497   %m = and i32 %sh, 1
498   ret i32 %m
501 define i32 @setcc_is_bit_set(i32 %x) {
502 ; CHECK-LABEL: setcc_is_bit_set:
503 ; CHECK:       # %bb.0:
504 ; CHECK-NEXT:    movl %edi, %eax
505 ; CHECK-NEXT:    shrl $10, %eax
506 ; CHECK-NEXT:    andl $1, %eax
507 ; CHECK-NEXT:    retq
508   %a1 = and i32 %x, 1024
509   %b1 = icmp ne i32 %a1, 0
510   %r = zext i1 %b1 to i32
511   ret i32 %r
514 declare void @bar()