1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=i686-unknown-linux | FileCheck %s --check-prefixes=X86
3 ; RUN: llc < %s -mtriple=x86_64-unknown-linux | FileCheck %s --check-prefixes=X64
5 define i64 @rotl64(i64 %A, i8 %Amt) nounwind {
10 ; X86-NEXT: pushl %esi
11 ; X86-NEXT: movb {{[0-9]+}}(%esp), %cl
12 ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
13 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edi
14 ; X86-NEXT: movl %esi, %eax
15 ; X86-NEXT: shll %cl, %eax
16 ; X86-NEXT: movl %edi, %edx
17 ; X86-NEXT: shldl %cl, %esi, %edx
18 ; X86-NEXT: testb $32, %cl
19 ; X86-NEXT: je .LBB0_2
21 ; X86-NEXT: movl %eax, %edx
22 ; X86-NEXT: xorl %eax, %eax
24 ; X86-NEXT: movb $64, %ch
25 ; X86-NEXT: subb %cl, %ch
26 ; X86-NEXT: movl %edi, %ebx
27 ; X86-NEXT: movb %ch, %cl
28 ; X86-NEXT: shrl %cl, %ebx
29 ; X86-NEXT: shrdl %cl, %edi, %esi
30 ; X86-NEXT: testb $32, %ch
31 ; X86-NEXT: je .LBB0_4
33 ; X86-NEXT: movl %ebx, %esi
34 ; X86-NEXT: xorl %ebx, %ebx
36 ; X86-NEXT: orl %ebx, %edx
37 ; X86-NEXT: orl %esi, %eax
45 ; X64-NEXT: movl %esi, %ecx
46 ; X64-NEXT: movq %rdi, %rax
47 ; X64-NEXT: # kill: def $cl killed $cl killed $ecx
48 ; X64-NEXT: rolq %cl, %rax
50 %shift.upgrd.1 = zext i8 %Amt to i64
51 %B = shl i64 %A, %shift.upgrd.1
52 %Amt2 = sub i8 64, %Amt
53 %shift.upgrd.2 = zext i8 %Amt2 to i64
54 %C = lshr i64 %A, %shift.upgrd.2
59 define i64 @rotr64(i64 %A, i8 %Amt) nounwind {
62 ; X86-NEXT: pushl %ebx
63 ; X86-NEXT: pushl %edi
64 ; X86-NEXT: pushl %esi
65 ; X86-NEXT: movb {{[0-9]+}}(%esp), %cl
66 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edi
67 ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
68 ; X86-NEXT: movl %esi, %edx
69 ; X86-NEXT: shrl %cl, %edx
70 ; X86-NEXT: movl %edi, %eax
71 ; X86-NEXT: shrdl %cl, %esi, %eax
72 ; X86-NEXT: testb $32, %cl
73 ; X86-NEXT: je .LBB1_2
75 ; X86-NEXT: movl %edx, %eax
76 ; X86-NEXT: xorl %edx, %edx
78 ; X86-NEXT: movb $64, %ch
79 ; X86-NEXT: subb %cl, %ch
80 ; X86-NEXT: movl %edi, %ebx
81 ; X86-NEXT: movb %ch, %cl
82 ; X86-NEXT: shll %cl, %ebx
83 ; X86-NEXT: shldl %cl, %edi, %esi
84 ; X86-NEXT: testb $32, %ch
85 ; X86-NEXT: je .LBB1_4
87 ; X86-NEXT: movl %ebx, %esi
88 ; X86-NEXT: xorl %ebx, %ebx
90 ; X86-NEXT: orl %esi, %edx
91 ; X86-NEXT: orl %ebx, %eax
99 ; X64-NEXT: movl %esi, %ecx
100 ; X64-NEXT: movq %rdi, %rax
101 ; X64-NEXT: # kill: def $cl killed $cl killed $ecx
102 ; X64-NEXT: rorq %cl, %rax
104 %shift.upgrd.3 = zext i8 %Amt to i64
105 %B = lshr i64 %A, %shift.upgrd.3
106 %Amt2 = sub i8 64, %Amt
107 %shift.upgrd.4 = zext i8 %Amt2 to i64
108 %C = shl i64 %A, %shift.upgrd.4
113 define i64 @rotli64(i64 %A) nounwind {
114 ; X86-LABEL: rotli64:
116 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
117 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
118 ; X86-NEXT: movl %ecx, %edx
119 ; X86-NEXT: shldl $5, %eax, %edx
120 ; X86-NEXT: shldl $5, %ecx, %eax
123 ; X64-LABEL: rotli64:
125 ; X64-NEXT: movq %rdi, %rax
126 ; X64-NEXT: rolq $5, %rax
134 define i64 @rotri64(i64 %A) nounwind {
135 ; X86-LABEL: rotri64:
137 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
138 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
139 ; X86-NEXT: movl %ecx, %eax
140 ; X86-NEXT: shldl $27, %edx, %eax
141 ; X86-NEXT: shldl $27, %ecx, %edx
144 ; X64-LABEL: rotri64:
146 ; X64-NEXT: movq %rdi, %rax
147 ; X64-NEXT: rolq $59, %rax
155 define i64 @rotl1_64(i64 %A) nounwind {
156 ; X86-LABEL: rotl1_64:
158 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
159 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
160 ; X86-NEXT: movl %ecx, %edx
161 ; X86-NEXT: shldl $1, %eax, %edx
162 ; X86-NEXT: shldl $1, %ecx, %eax
165 ; X64-LABEL: rotl1_64:
167 ; X64-NEXT: movq %rdi, %rax
168 ; X64-NEXT: rolq %rax
176 define i64 @rotr1_64(i64 %A) nounwind {
177 ; X86-LABEL: rotr1_64:
179 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
180 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
181 ; X86-NEXT: movl %ecx, %eax
182 ; X86-NEXT: shldl $31, %edx, %eax
183 ; X86-NEXT: shldl $31, %ecx, %edx
186 ; X64-LABEL: rotr1_64:
188 ; X64-NEXT: movq %rdi, %rax
189 ; X64-NEXT: rorq %rax
197 define i32 @rotl32(i32 %A, i8 %Amt) nounwind {
200 ; X86-NEXT: movb {{[0-9]+}}(%esp), %cl
201 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
202 ; X86-NEXT: roll %cl, %eax
207 ; X64-NEXT: movl %esi, %ecx
208 ; X64-NEXT: movl %edi, %eax
209 ; X64-NEXT: # kill: def $cl killed $cl killed $ecx
210 ; X64-NEXT: roll %cl, %eax
212 %shift.upgrd.1 = zext i8 %Amt to i32
213 %B = shl i32 %A, %shift.upgrd.1
214 %Amt2 = sub i8 32, %Amt
215 %shift.upgrd.2 = zext i8 %Amt2 to i32
216 %C = lshr i32 %A, %shift.upgrd.2
221 define i32 @rotr32(i32 %A, i8 %Amt) nounwind {
224 ; X86-NEXT: movb {{[0-9]+}}(%esp), %cl
225 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
226 ; X86-NEXT: rorl %cl, %eax
231 ; X64-NEXT: movl %esi, %ecx
232 ; X64-NEXT: movl %edi, %eax
233 ; X64-NEXT: # kill: def $cl killed $cl killed $ecx
234 ; X64-NEXT: rorl %cl, %eax
236 %shift.upgrd.3 = zext i8 %Amt to i32
237 %B = lshr i32 %A, %shift.upgrd.3
238 %Amt2 = sub i8 32, %Amt
239 %shift.upgrd.4 = zext i8 %Amt2 to i32
240 %C = shl i32 %A, %shift.upgrd.4
245 define i32 @rotli32(i32 %A) nounwind {
246 ; X86-LABEL: rotli32:
248 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
249 ; X86-NEXT: roll $5, %eax
252 ; X64-LABEL: rotli32:
254 ; X64-NEXT: movl %edi, %eax
255 ; X64-NEXT: roll $5, %eax
263 define i32 @rotri32(i32 %A) nounwind {
264 ; X86-LABEL: rotri32:
266 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
267 ; X86-NEXT: roll $27, %eax
270 ; X64-LABEL: rotri32:
272 ; X64-NEXT: movl %edi, %eax
273 ; X64-NEXT: roll $27, %eax
281 define i32 @rotl1_32(i32 %A) nounwind {
282 ; X86-LABEL: rotl1_32:
284 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
285 ; X86-NEXT: roll %eax
288 ; X64-LABEL: rotl1_32:
290 ; X64-NEXT: movl %edi, %eax
291 ; X64-NEXT: roll %eax
299 define i32 @rotr1_32(i32 %A) nounwind {
300 ; X86-LABEL: rotr1_32:
302 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
303 ; X86-NEXT: rorl %eax
306 ; X64-LABEL: rotr1_32:
308 ; X64-NEXT: movl %edi, %eax
309 ; X64-NEXT: rorl %eax
317 define i16 @rotl16(i16 %A, i8 %Amt) nounwind {
320 ; X86-NEXT: movb {{[0-9]+}}(%esp), %cl
321 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
322 ; X86-NEXT: rolw %cl, %ax
327 ; X64-NEXT: movl %esi, %ecx
328 ; X64-NEXT: movl %edi, %eax
329 ; X64-NEXT: # kill: def $cl killed $cl killed $ecx
330 ; X64-NEXT: rolw %cl, %ax
331 ; X64-NEXT: # kill: def $ax killed $ax killed $eax
333 %shift.upgrd.5 = zext i8 %Amt to i16
334 %B = shl i16 %A, %shift.upgrd.5
335 %Amt2 = sub i8 16, %Amt
336 %shift.upgrd.6 = zext i8 %Amt2 to i16
337 %C = lshr i16 %A, %shift.upgrd.6
342 define i16 @rotr16(i16 %A, i8 %Amt) nounwind {
345 ; X86-NEXT: movb {{[0-9]+}}(%esp), %cl
346 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
347 ; X86-NEXT: rorw %cl, %ax
352 ; X64-NEXT: movl %esi, %ecx
353 ; X64-NEXT: movl %edi, %eax
354 ; X64-NEXT: # kill: def $cl killed $cl killed $ecx
355 ; X64-NEXT: rorw %cl, %ax
356 ; X64-NEXT: # kill: def $ax killed $ax killed $eax
358 %shift.upgrd.7 = zext i8 %Amt to i16
359 %B = lshr i16 %A, %shift.upgrd.7
360 %Amt2 = sub i8 16, %Amt
361 %shift.upgrd.8 = zext i8 %Amt2 to i16
362 %C = shl i16 %A, %shift.upgrd.8
367 define i16 @rotli16(i16 %A) nounwind {
368 ; X86-LABEL: rotli16:
370 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
371 ; X86-NEXT: rolw $5, %ax
374 ; X64-LABEL: rotli16:
376 ; X64-NEXT: movl %edi, %eax
377 ; X64-NEXT: rolw $5, %ax
378 ; X64-NEXT: # kill: def $ax killed $ax killed $eax
386 define i16 @rotri16(i16 %A) nounwind {
387 ; X86-LABEL: rotri16:
389 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
390 ; X86-NEXT: rolw $11, %ax
393 ; X64-LABEL: rotri16:
395 ; X64-NEXT: movl %edi, %eax
396 ; X64-NEXT: rolw $11, %ax
397 ; X64-NEXT: # kill: def $ax killed $ax killed $eax
405 define i16 @rotl1_16(i16 %A) nounwind {
406 ; X86-LABEL: rotl1_16:
408 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
412 ; X64-LABEL: rotl1_16:
414 ; X64-NEXT: movl %edi, %eax
416 ; X64-NEXT: # kill: def $ax killed $ax killed $eax
424 define i16 @rotr1_16(i16 %A) nounwind {
425 ; X86-LABEL: rotr1_16:
427 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
431 ; X64-LABEL: rotr1_16:
433 ; X64-NEXT: movl %edi, %eax
435 ; X64-NEXT: # kill: def $ax killed $ax killed $eax
443 define i8 @rotl8(i8 %A, i8 %Amt) nounwind {
446 ; X86-NEXT: movb {{[0-9]+}}(%esp), %cl
447 ; X86-NEXT: movb {{[0-9]+}}(%esp), %al
448 ; X86-NEXT: rolb %cl, %al
453 ; X64-NEXT: movl %esi, %ecx
454 ; X64-NEXT: movl %edi, %eax
455 ; X64-NEXT: # kill: def $cl killed $cl killed $ecx
456 ; X64-NEXT: rolb %cl, %al
457 ; X64-NEXT: # kill: def $al killed $al killed $eax
460 %Amt2 = sub i8 8, %Amt
461 %C = lshr i8 %A, %Amt2
466 define i8 @rotr8(i8 %A, i8 %Amt) nounwind {
469 ; X86-NEXT: movb {{[0-9]+}}(%esp), %cl
470 ; X86-NEXT: movb {{[0-9]+}}(%esp), %al
471 ; X86-NEXT: rorb %cl, %al
476 ; X64-NEXT: movl %esi, %ecx
477 ; X64-NEXT: movl %edi, %eax
478 ; X64-NEXT: # kill: def $cl killed $cl killed $ecx
479 ; X64-NEXT: rorb %cl, %al
480 ; X64-NEXT: # kill: def $al killed $al killed $eax
482 %B = lshr i8 %A, %Amt
483 %Amt2 = sub i8 8, %Amt
484 %C = shl i8 %A, %Amt2
489 define i8 @rotli8(i8 %A) nounwind {
492 ; X86-NEXT: movb {{[0-9]+}}(%esp), %al
493 ; X86-NEXT: rolb $5, %al
498 ; X64-NEXT: movl %edi, %eax
499 ; X64-NEXT: rolb $5, %al
500 ; X64-NEXT: # kill: def $al killed $al killed $eax
508 define i8 @rotri8(i8 %A) nounwind {
511 ; X86-NEXT: movb {{[0-9]+}}(%esp), %al
512 ; X86-NEXT: rolb $3, %al
517 ; X64-NEXT: movl %edi, %eax
518 ; X64-NEXT: rolb $3, %al
519 ; X64-NEXT: # kill: def $al killed $al killed $eax
527 define i8 @rotl1_8(i8 %A) nounwind {
528 ; X86-LABEL: rotl1_8:
530 ; X86-NEXT: movb {{[0-9]+}}(%esp), %al
534 ; X64-LABEL: rotl1_8:
536 ; X64-NEXT: movl %edi, %eax
538 ; X64-NEXT: # kill: def $al killed $al killed $eax
546 define i8 @rotr1_8(i8 %A) nounwind {
547 ; X86-LABEL: rotr1_8:
549 ; X86-NEXT: movb {{[0-9]+}}(%esp), %al
553 ; X64-LABEL: rotr1_8:
555 ; X64-NEXT: movl %edi, %eax
557 ; X64-NEXT: # kill: def $al killed $al killed $eax
565 define void @rotr1_64_mem(i64* %Aptr) nounwind {
566 ; X86-LABEL: rotr1_64_mem:
568 ; X86-NEXT: pushl %esi
569 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
570 ; X86-NEXT: movl (%eax), %ecx
571 ; X86-NEXT: movl 4(%eax), %edx
572 ; X86-NEXT: movl %edx, %esi
573 ; X86-NEXT: shldl $31, %ecx, %esi
574 ; X86-NEXT: shldl $31, %edx, %ecx
575 ; X86-NEXT: movl %esi, (%eax)
576 ; X86-NEXT: movl %ecx, 4(%eax)
577 ; X86-NEXT: popl %esi
580 ; X64-LABEL: rotr1_64_mem:
582 ; X64-NEXT: rorq (%rdi)
585 %A = load i64, i64 *%Aptr
589 store i64 %D, i64* %Aptr
593 define void @rotr1_32_mem(i32* %Aptr) nounwind {
594 ; X86-LABEL: rotr1_32_mem:
596 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
597 ; X86-NEXT: rorl (%eax)
600 ; X64-LABEL: rotr1_32_mem:
602 ; X64-NEXT: rorl (%rdi)
604 %A = load i32, i32 *%Aptr
608 store i32 %D, i32* %Aptr
612 define void @rotr1_16_mem(i16* %Aptr) nounwind {
613 ; X86-LABEL: rotr1_16_mem:
615 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
616 ; X86-NEXT: rorw (%eax)
619 ; X64-LABEL: rotr1_16_mem:
621 ; X64-NEXT: rorw (%rdi)
623 %A = load i16, i16 *%Aptr
627 store i16 %D, i16* %Aptr
631 define void @rotr1_8_mem(i8* %Aptr) nounwind {
632 ; X86-LABEL: rotr1_8_mem:
634 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
635 ; X86-NEXT: rorb (%eax)
638 ; X64-LABEL: rotr1_8_mem:
640 ; X64-NEXT: rorb (%rdi)
642 %A = load i8, i8 *%Aptr
646 store i8 %D, i8* %Aptr
650 define i64 @truncated_rot(i64 %x, i32 %amt) nounwind {
651 ; X86-LABEL: truncated_rot:
652 ; X86: # %bb.0: # %entry
653 ; X86-NEXT: pushl %ebx
654 ; X86-NEXT: pushl %edi
655 ; X86-NEXT: pushl %esi
656 ; X86-NEXT: movb {{[0-9]+}}(%esp), %cl
657 ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
658 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx
659 ; X86-NEXT: movl %esi, %eax
660 ; X86-NEXT: shll %cl, %eax
661 ; X86-NEXT: testb $32, %cl
662 ; X86-NEXT: movl $0, %edi
663 ; X86-NEXT: jne .LBB28_2
664 ; X86-NEXT: # %bb.1: # %entry
665 ; X86-NEXT: movl %eax, %edi
666 ; X86-NEXT: .LBB28_2: # %entry
667 ; X86-NEXT: movb $64, %dl
668 ; X86-NEXT: subb %cl, %dl
669 ; X86-NEXT: movl %ebx, %eax
670 ; X86-NEXT: movl %edx, %ecx
671 ; X86-NEXT: shrl %cl, %eax
672 ; X86-NEXT: shrdl %cl, %ebx, %esi
673 ; X86-NEXT: testb $32, %dl
674 ; X86-NEXT: jne .LBB28_4
675 ; X86-NEXT: # %bb.3: # %entry
676 ; X86-NEXT: movl %esi, %eax
677 ; X86-NEXT: .LBB28_4: # %entry
678 ; X86-NEXT: orl %edi, %eax
679 ; X86-NEXT: xorl %edx, %edx
680 ; X86-NEXT: popl %esi
681 ; X86-NEXT: popl %edi
682 ; X86-NEXT: popl %ebx
685 ; X64-LABEL: truncated_rot:
686 ; X64: # %bb.0: # %entry
687 ; X64-NEXT: movl %esi, %ecx
688 ; X64-NEXT: # kill: def $cl killed $cl killed $ecx
689 ; X64-NEXT: rolq %cl, %rdi
690 ; X64-NEXT: movl %edi, %eax
693 %sh_prom = zext i32 %amt to i64
694 %shl = shl i64 %x, %sh_prom
695 %sub = sub nsw i32 64, %amt
696 %sh_prom1 = zext i32 %sub to i64
697 %shr = lshr i64 %x, %sh_prom1
698 %or = or i64 %shr, %shl
699 %and = and i64 %or, 4294967295