1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=i686-pc-linux | FileCheck %s --check-prefixes=CHECK,X86
3 ; RUN: llc < %s -mtriple=x86_64-pc-linux | FileCheck %s --check-prefixes=CHECK,X64,X64-MASK
4 ; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=bdver1 | FileCheck %s --check-prefixes=CHECK,X64,X64-SHIFT,X64-SHIFT2
5 ; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=bdver2 | FileCheck %s --check-prefixes=CHECK,X64,X64-SHIFT,X64-TBM
6 ; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=bdver3 | FileCheck %s --check-prefixes=CHECK,X64,X64-SHIFT,X64-TBM
7 ; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=bdver4 | FileCheck %s --check-prefixes=CHECK,X64,X64-SHIFT,X64-TBM
8 ; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=btver1 | FileCheck %s --check-prefixes=CHECK,X64,X64-SHIFT,X64-SHIFT2
9 ; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=btver2 | FileCheck %s --check-prefixes=CHECK,X64,X64-SHIFT,X64-BMI,X64-BMI1
10 ; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=znver1 | FileCheck %s --check-prefixes=CHECK,X64,X64-SHIFT,X64-BMI,X64-BMI2
11 ; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=znver2 | FileCheck %s --check-prefixes=CHECK,X64,X64-SHIFT,X64-BMI,X64-BMI2
12 ; RUN: llc < %s -mtriple=x86_64-pc-linux -mattr=+fast-scalar-shift-masks | FileCheck %s --check-prefixes=CHECK,X64,X64-SHIFT,X64-SHIFT2
15 ; fold (shl (lshr x, c1), c2) -> (0) (and x, MASK) or
16 ; (1) (and (shl x, (sub c2, c1), MASK) or
17 ; (2) (and (lshr x, (sub c1, c2), MASK)
20 define i8 @test_i8_shl_lshr_0(i8 %a0) {
21 ; X86-LABEL: test_i8_shl_lshr_0:
23 ; X86-NEXT: movb {{[0-9]+}}(%esp), %al
24 ; X86-NEXT: andb $-8, %al
27 ; X64-LABEL: test_i8_shl_lshr_0:
29 ; X64-NEXT: movl %edi, %eax
30 ; X64-NEXT: andb $-8, %al
31 ; X64-NEXT: # kill: def $al killed $al killed $eax
38 define i8 @test_i8_shl_lshr_1(i8 %a0) {
39 ; X86-LABEL: test_i8_shl_lshr_1:
41 ; X86-NEXT: movb {{[0-9]+}}(%esp), %al
42 ; X86-NEXT: shlb $2, %al
43 ; X86-NEXT: andb $-32, %al
46 ; X64-MASK-LABEL: test_i8_shl_lshr_1:
48 ; X64-MASK-NEXT: # kill: def $edi killed $edi def $rdi
49 ; X64-MASK-NEXT: leal (,%rdi,4), %eax
50 ; X64-MASK-NEXT: andb $-32, %al
51 ; X64-MASK-NEXT: # kill: def $al killed $al killed $eax
54 ; X64-SHIFT-LABEL: test_i8_shl_lshr_1:
56 ; X64-SHIFT-NEXT: movl %edi, %eax
57 ; X64-SHIFT-NEXT: shrb $3, %al
58 ; X64-SHIFT-NEXT: shlb $5, %al
59 ; X64-SHIFT-NEXT: # kill: def $al killed $al killed $eax
60 ; X64-SHIFT-NEXT: retq
66 define i8 @test_i8_shl_lshr_2(i8 %a0) {
67 ; X86-LABEL: test_i8_shl_lshr_2:
69 ; X86-NEXT: movb {{[0-9]+}}(%esp), %al
70 ; X86-NEXT: shrb $2, %al
71 ; X86-NEXT: andb $56, %al
74 ; X64-MASK-LABEL: test_i8_shl_lshr_2:
76 ; X64-MASK-NEXT: movl %edi, %eax
77 ; X64-MASK-NEXT: shrb $2, %al
78 ; X64-MASK-NEXT: andb $56, %al
79 ; X64-MASK-NEXT: # kill: def $al killed $al killed $eax
82 ; X64-SHIFT-LABEL: test_i8_shl_lshr_2:
84 ; X64-SHIFT-NEXT: # kill: def $edi killed $edi def $rdi
85 ; X64-SHIFT-NEXT: shrb $5, %dil
86 ; X64-SHIFT-NEXT: leal (,%rdi,8), %eax
87 ; X64-SHIFT-NEXT: # kill: def $al killed $al killed $eax
88 ; X64-SHIFT-NEXT: retq
94 define i16 @test_i16_shl_lshr_0(i16 %a0) {
95 ; X86-LABEL: test_i16_shl_lshr_0:
97 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
98 ; X86-NEXT: andl $-8, %eax
99 ; X86-NEXT: # kill: def $ax killed $ax killed $eax
102 ; X64-LABEL: test_i16_shl_lshr_0:
104 ; X64-NEXT: movl %edi, %eax
105 ; X64-NEXT: andl $65528, %eax # imm = 0xFFF8
106 ; X64-NEXT: # kill: def $ax killed $ax killed $eax
113 define i16 @test_i16_shl_lshr_1(i16 %a0) {
114 ; X86-LABEL: test_i16_shl_lshr_1:
116 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
117 ; X86-NEXT: shll $2, %eax
118 ; X86-NEXT: andl $65504, %eax # imm = 0xFFE0
119 ; X86-NEXT: # kill: def $ax killed $ax killed $eax
122 ; X64-MASK-LABEL: test_i16_shl_lshr_1:
124 ; X64-MASK-NEXT: # kill: def $edi killed $edi def $rdi
125 ; X64-MASK-NEXT: leal (,%rdi,4), %eax
126 ; X64-MASK-NEXT: andl $65504, %eax # imm = 0xFFE0
127 ; X64-MASK-NEXT: # kill: def $ax killed $ax killed $eax
128 ; X64-MASK-NEXT: retq
130 ; X64-SHIFT-LABEL: test_i16_shl_lshr_1:
131 ; X64-SHIFT: # %bb.0:
132 ; X64-SHIFT-NEXT: movzwl %di, %eax
133 ; X64-SHIFT-NEXT: shrl $3, %eax
134 ; X64-SHIFT-NEXT: shll $5, %eax
135 ; X64-SHIFT-NEXT: # kill: def $ax killed $ax killed $eax
136 ; X64-SHIFT-NEXT: retq
142 define i16 @test_i16_shl_lshr_2(i16 %a0) {
143 ; X86-LABEL: test_i16_shl_lshr_2:
145 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
146 ; X86-NEXT: shrl $2, %eax
147 ; X86-NEXT: andl $16376, %eax # imm = 0x3FF8
148 ; X86-NEXT: # kill: def $ax killed $ax killed $eax
151 ; X64-MASK-LABEL: test_i16_shl_lshr_2:
153 ; X64-MASK-NEXT: movl %edi, %eax
154 ; X64-MASK-NEXT: shrl $2, %eax
155 ; X64-MASK-NEXT: andl $16376, %eax # imm = 0x3FF8
156 ; X64-MASK-NEXT: # kill: def $ax killed $ax killed $eax
157 ; X64-MASK-NEXT: retq
159 ; X64-SHIFT-LABEL: test_i16_shl_lshr_2:
160 ; X64-SHIFT: # %bb.0:
161 ; X64-SHIFT-NEXT: movzwl %di, %eax
162 ; X64-SHIFT-NEXT: shrl $5, %eax
163 ; X64-SHIFT-NEXT: shll $3, %eax
164 ; X64-SHIFT-NEXT: # kill: def $ax killed $ax killed $eax
165 ; X64-SHIFT-NEXT: retq
171 define i32 @test_i32_shl_lshr_0(i32 %a0) {
172 ; X86-LABEL: test_i32_shl_lshr_0:
174 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
175 ; X86-NEXT: andl $-8, %eax
178 ; X64-LABEL: test_i32_shl_lshr_0:
180 ; X64-NEXT: movl %edi, %eax
181 ; X64-NEXT: andl $-8, %eax
188 define i32 @test_i32_shl_lshr_1(i32 %a0) {
189 ; X86-LABEL: test_i32_shl_lshr_1:
191 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
192 ; X86-NEXT: shll $2, %eax
193 ; X86-NEXT: andl $-32, %eax
196 ; X64-MASK-LABEL: test_i32_shl_lshr_1:
198 ; X64-MASK-NEXT: # kill: def $edi killed $edi def $rdi
199 ; X64-MASK-NEXT: leal (,%rdi,4), %eax
200 ; X64-MASK-NEXT: andl $-32, %eax
201 ; X64-MASK-NEXT: retq
203 ; X64-SHIFT-LABEL: test_i32_shl_lshr_1:
204 ; X64-SHIFT: # %bb.0:
205 ; X64-SHIFT-NEXT: movl %edi, %eax
206 ; X64-SHIFT-NEXT: shrl $3, %eax
207 ; X64-SHIFT-NEXT: shll $5, %eax
208 ; X64-SHIFT-NEXT: retq
214 define i32 @test_i32_shl_lshr_2(i32 %a0) {
215 ; X86-LABEL: test_i32_shl_lshr_2:
217 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
218 ; X86-NEXT: shrl $2, %eax
219 ; X86-NEXT: andl $-8, %eax
222 ; X64-MASK-LABEL: test_i32_shl_lshr_2:
224 ; X64-MASK-NEXT: movl %edi, %eax
225 ; X64-MASK-NEXT: shrl $2, %eax
226 ; X64-MASK-NEXT: andl $-8, %eax
227 ; X64-MASK-NEXT: retq
229 ; X64-SHIFT-LABEL: test_i32_shl_lshr_2:
230 ; X64-SHIFT: # %bb.0:
231 ; X64-SHIFT-NEXT: # kill: def $edi killed $edi def $rdi
232 ; X64-SHIFT-NEXT: shrl $5, %edi
233 ; X64-SHIFT-NEXT: leal (,%rdi,8), %eax
234 ; X64-SHIFT-NEXT: retq
240 define i64 @test_i64_shl_lshr_0(i64 %a0) {
241 ; X86-LABEL: test_i64_shl_lshr_0:
243 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
244 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
245 ; X86-NEXT: andl $-8, %eax
248 ; X64-LABEL: test_i64_shl_lshr_0:
250 ; X64-NEXT: movq %rdi, %rax
251 ; X64-NEXT: andq $-8, %rax
258 define i64 @test_i64_shl_lshr_1(i64 %a0) {
259 ; X86-LABEL: test_i64_shl_lshr_1:
261 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
262 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
263 ; X86-NEXT: leal (,%ecx,4), %eax
264 ; X86-NEXT: andl $-32, %eax
265 ; X86-NEXT: shldl $2, %ecx, %edx
268 ; X64-MASK-LABEL: test_i64_shl_lshr_1:
270 ; X64-MASK-NEXT: leaq (,%rdi,4), %rax
271 ; X64-MASK-NEXT: andq $-32, %rax
272 ; X64-MASK-NEXT: retq
274 ; X64-SHIFT-LABEL: test_i64_shl_lshr_1:
275 ; X64-SHIFT: # %bb.0:
276 ; X64-SHIFT-NEXT: movq %rdi, %rax
277 ; X64-SHIFT-NEXT: shrq $3, %rax
278 ; X64-SHIFT-NEXT: shlq $5, %rax
279 ; X64-SHIFT-NEXT: retq
285 define i64 @test_i64_shl_lshr_2(i64 %a0) {
286 ; X86-LABEL: test_i64_shl_lshr_2:
288 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
289 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
290 ; X86-NEXT: shrdl $2, %edx, %eax
291 ; X86-NEXT: andl $-8, %eax
292 ; X86-NEXT: shrl $2, %edx
295 ; X64-MASK-LABEL: test_i64_shl_lshr_2:
297 ; X64-MASK-NEXT: movq %rdi, %rax
298 ; X64-MASK-NEXT: shrq $2, %rax
299 ; X64-MASK-NEXT: andq $-8, %rax
300 ; X64-MASK-NEXT: retq
302 ; X64-SHIFT-LABEL: test_i64_shl_lshr_2:
303 ; X64-SHIFT: # %bb.0:
304 ; X64-SHIFT-NEXT: shrq $5, %rdi
305 ; X64-SHIFT-NEXT: leaq (,%rdi,8), %rax
306 ; X64-SHIFT-NEXT: retq
313 ; fold (lshr (shl x, c1), c2) -> (0) (and x, MASK) or
314 ; (1) (and (shl x, (sub c1, c2), MASK) or
315 ; (2) (and (lshr x, (sub c2, c1), MASK)
318 define i8 @test_i8_lshr_lshr_0(i8 %a0) {
319 ; X86-LABEL: test_i8_lshr_lshr_0:
321 ; X86-NEXT: movb {{[0-9]+}}(%esp), %al
322 ; X86-NEXT: andb $31, %al
325 ; X64-LABEL: test_i8_lshr_lshr_0:
327 ; X64-NEXT: movl %edi, %eax
328 ; X64-NEXT: andb $31, %al
329 ; X64-NEXT: # kill: def $al killed $al killed $eax
336 define i8 @test_i8_lshr_lshr_1(i8 %a0) {
337 ; X86-LABEL: test_i8_lshr_lshr_1:
339 ; X86-NEXT: movb {{[0-9]+}}(%esp), %al
340 ; X86-NEXT: shlb $3, %al
341 ; X86-NEXT: shrb $5, %al
344 ; X64-LABEL: test_i8_lshr_lshr_1:
346 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
347 ; X64-NEXT: leal (,%rdi,8), %eax
348 ; X64-NEXT: shrb $5, %al
349 ; X64-NEXT: # kill: def $al killed $al killed $eax
356 define i8 @test_i8_lshr_lshr_2(i8 %a0) {
357 ; X86-LABEL: test_i8_lshr_lshr_2:
359 ; X86-NEXT: movb {{[0-9]+}}(%esp), %al
360 ; X86-NEXT: shlb $5, %al
361 ; X86-NEXT: shrb $3, %al
364 ; X64-LABEL: test_i8_lshr_lshr_2:
366 ; X64-NEXT: movl %edi, %eax
367 ; X64-NEXT: shlb $5, %al
368 ; X64-NEXT: shrb $3, %al
369 ; X64-NEXT: # kill: def $al killed $al killed $eax
376 define i16 @test_i16_lshr_lshr_0(i16 %a0) {
377 ; X86-LABEL: test_i16_lshr_lshr_0:
379 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
380 ; X86-NEXT: andl $8191, %eax # imm = 0x1FFF
381 ; X86-NEXT: # kill: def $ax killed $ax killed $eax
384 ; X64-LABEL: test_i16_lshr_lshr_0:
386 ; X64-NEXT: movl %edi, %eax
387 ; X64-NEXT: andl $8191, %eax # imm = 0x1FFF
388 ; X64-NEXT: # kill: def $ax killed $ax killed $eax
395 define i16 @test_i16_lshr_lshr_1(i16 %a0) {
396 ; X86-LABEL: test_i16_lshr_lshr_1:
398 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
399 ; X86-NEXT: shrl $2, %eax
400 ; X86-NEXT: andl $2047, %eax # imm = 0x7FF
401 ; X86-NEXT: # kill: def $ax killed $ax killed $eax
404 ; X64-MASK-LABEL: test_i16_lshr_lshr_1:
406 ; X64-MASK-NEXT: movl %edi, %eax
407 ; X64-MASK-NEXT: shrl $2, %eax
408 ; X64-MASK-NEXT: andl $2047, %eax # imm = 0x7FF
409 ; X64-MASK-NEXT: # kill: def $ax killed $ax killed $eax
410 ; X64-MASK-NEXT: retq
412 ; X64-SHIFT2-LABEL: test_i16_lshr_lshr_1:
413 ; X64-SHIFT2: # %bb.0:
414 ; X64-SHIFT2-NEXT: movl %edi, %eax
415 ; X64-SHIFT2-NEXT: shrl $2, %eax
416 ; X64-SHIFT2-NEXT: andl $2047, %eax # imm = 0x7FF
417 ; X64-SHIFT2-NEXT: # kill: def $ax killed $ax killed $eax
418 ; X64-SHIFT2-NEXT: retq
420 ; X64-TBM-LABEL: test_i16_lshr_lshr_1:
422 ; X64-TBM-NEXT: bextrl $2818, %edi, %eax # imm = 0xB02
423 ; X64-TBM-NEXT: # kill: def $ax killed $ax killed $eax
426 ; X64-BMI-LABEL: test_i16_lshr_lshr_1:
428 ; X64-BMI-NEXT: movl $2818, %eax # imm = 0xB02
429 ; X64-BMI-NEXT: bextrl %eax, %edi, %eax
430 ; X64-BMI-NEXT: # kill: def $ax killed $ax killed $eax
437 define i16 @test_i16_lshr_lshr_2(i16 %a0) {
438 ; X86-LABEL: test_i16_lshr_lshr_2:
440 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
441 ; X86-NEXT: shll $2, %eax
442 ; X86-NEXT: andl $8188, %eax # imm = 0x1FFC
443 ; X86-NEXT: # kill: def $ax killed $ax killed $eax
446 ; X64-LABEL: test_i16_lshr_lshr_2:
448 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
449 ; X64-NEXT: leal (,%rdi,4), %eax
450 ; X64-NEXT: andl $8188, %eax # imm = 0x1FFC
451 ; X64-NEXT: # kill: def $ax killed $ax killed $eax
458 define i32 @test_i32_lshr_lshr_0(i32 %a0) {
459 ; X86-LABEL: test_i32_lshr_lshr_0:
461 ; X86-NEXT: movl $536870911, %eax # imm = 0x1FFFFFFF
462 ; X86-NEXT: andl {{[0-9]+}}(%esp), %eax
465 ; X64-LABEL: test_i32_lshr_lshr_0:
467 ; X64-NEXT: movl %edi, %eax
468 ; X64-NEXT: andl $536870911, %eax # imm = 0x1FFFFFFF
475 define i32 @test_i32_lshr_lshr_1(i32 %a0) {
476 ; X86-LABEL: test_i32_lshr_lshr_1:
478 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
479 ; X86-NEXT: shll $3, %eax
480 ; X86-NEXT: shrl $5, %eax
483 ; X64-LABEL: test_i32_lshr_lshr_1:
485 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
486 ; X64-NEXT: leal (,%rdi,8), %eax
487 ; X64-NEXT: shrl $5, %eax
494 define i32 @test_i32_lshr_lshr_2(i32 %a0) {
495 ; X86-LABEL: test_i32_lshr_lshr_2:
497 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
498 ; X86-NEXT: shll $5, %eax
499 ; X86-NEXT: shrl $3, %eax
502 ; X64-LABEL: test_i32_lshr_lshr_2:
504 ; X64-NEXT: movl %edi, %eax
505 ; X64-NEXT: shll $5, %eax
506 ; X64-NEXT: shrl $3, %eax
513 define i64 @test_i64_lshr_lshr_0(i64 %a0) {
514 ; X86-LABEL: test_i64_lshr_lshr_0:
516 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
517 ; X86-NEXT: movl $536870911, %edx # imm = 0x1FFFFFFF
518 ; X86-NEXT: andl {{[0-9]+}}(%esp), %edx
521 ; X64-MASK-LABEL: test_i64_lshr_lshr_0:
523 ; X64-MASK-NEXT: movabsq $2305843009213693951, %rax # imm = 0x1FFFFFFFFFFFFFFF
524 ; X64-MASK-NEXT: andq %rdi, %rax
525 ; X64-MASK-NEXT: retq
527 ; X64-SHIFT2-LABEL: test_i64_lshr_lshr_0:
528 ; X64-SHIFT2: # %bb.0:
529 ; X64-SHIFT2-NEXT: movabsq $2305843009213693951, %rax # imm = 0x1FFFFFFFFFFFFFFF
530 ; X64-SHIFT2-NEXT: andq %rdi, %rax
531 ; X64-SHIFT2-NEXT: retq
533 ; X64-TBM-LABEL: test_i64_lshr_lshr_0:
535 ; X64-TBM-NEXT: bextrq $15616, %rdi, %rax # imm = 0x3D00
538 ; X64-BMI1-LABEL: test_i64_lshr_lshr_0:
540 ; X64-BMI1-NEXT: movl $15616, %eax # imm = 0x3D00
541 ; X64-BMI1-NEXT: bextrq %rax, %rdi, %rax
542 ; X64-BMI1-NEXT: retq
544 ; X64-BMI2-LABEL: test_i64_lshr_lshr_0:
546 ; X64-BMI2-NEXT: movb $61, %al
547 ; X64-BMI2-NEXT: bzhiq %rax, %rdi, %rax
548 ; X64-BMI2-NEXT: retq
554 define i64 @test_i64_lshr_lshr_1(i64 %a0) {
555 ; X86-LABEL: test_i64_lshr_lshr_1:
557 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
558 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
559 ; X86-NEXT: shldl $3, %eax, %edx
560 ; X86-NEXT: shll $3, %eax
561 ; X86-NEXT: shrdl $5, %edx, %eax
562 ; X86-NEXT: shrl $5, %edx
565 ; X64-LABEL: test_i64_lshr_lshr_1:
567 ; X64-NEXT: leaq (,%rdi,8), %rax
568 ; X64-NEXT: shrq $5, %rax
575 define i64 @test_i64_lshr_lshr_2(i64 %a0) {
576 ; X86-LABEL: test_i64_lshr_lshr_2:
578 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
579 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
580 ; X86-NEXT: shldl $5, %eax, %edx
581 ; X86-NEXT: shll $5, %eax
582 ; X86-NEXT: shrdl $3, %edx, %eax
583 ; X86-NEXT: shrl $3, %edx
586 ; X64-LABEL: test_i64_lshr_lshr_2:
588 ; X64-NEXT: movq %rdi, %rax
589 ; X64-NEXT: shlq $5, %rax
590 ; X64-NEXT: shrq $3, %rax