1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=i686-unknown-linux | FileCheck %s --check-prefix=32
3; RUN: llc < %s -mtriple=x86_64-unknown-linux | FileCheck %s --check-prefix=64
4
5define i64 @rotl64(i64 %A, i8 %Amt) nounwind {
6; 32-LABEL: rotl64:
7; 32:       # BB#0:
8; 32-NEXT:    pushl %ebx
9; 32-NEXT:    pushl %edi
10; 32-NEXT:    pushl %esi
11; 32-NEXT:    movb {{[0-9]+}}(%esp), %cl
12; 32-NEXT:    movl {{[0-9]+}}(%esp), %esi
13; 32-NEXT:    movl {{[0-9]+}}(%esp), %edi
14; 32-NEXT:    movl %esi, %eax
15; 32-NEXT:    shll %cl, %eax
16; 32-NEXT:    movl %edi, %edx
17; 32-NEXT:    shldl %cl, %esi, %edx
18; 32-NEXT:    testb $32, %cl
19; 32-NEXT:    je .LBB0_2
20; 32-NEXT:  # BB#1:
21; 32-NEXT:    movl %eax, %edx
22; 32-NEXT:    xorl %eax, %eax
23; 32-NEXT:  .LBB0_2:
24; 32-NEXT:    movb $64, %ch
25; 32-NEXT:    subb %cl, %ch
26; 32-NEXT:    movl %edi, %ebx
27; 32-NEXT:    movb %ch, %cl
28; 32-NEXT:    shrl %cl, %ebx
29; 32-NEXT:    shrdl %cl, %edi, %esi
30; 32-NEXT:    testb $32, %ch
31; 32-NEXT:    je .LBB0_4
32; 32-NEXT:  # BB#3:
33; 32-NEXT:    movl %ebx, %esi
34; 32-NEXT:    xorl %ebx, %ebx
35; 32-NEXT:  .LBB0_4:
36; 32-NEXT:    orl %esi, %eax
37; 32-NEXT:    orl %ebx, %edx
38; 32-NEXT:    popl %esi
39; 32-NEXT:    popl %edi
40; 32-NEXT:    popl %ebx
41; 32-NEXT:    retl
42;
43; 64-LABEL: rotl64:
44; 64:       # BB#0:
45; 64-NEXT:    movl %esi, %ecx
46; 64-NEXT:    rolq %cl, %rdi
47; 64-NEXT:    movq %rdi, %rax
48; 64-NEXT:    retq
49	%shift.upgrd.1 = zext i8 %Amt to i64
50	%B = shl i64 %A, %shift.upgrd.1
51	%Amt2 = sub i8 64, %Amt
52	%shift.upgrd.2 = zext i8 %Amt2 to i64
53	%C = lshr i64 %A, %shift.upgrd.2
54	%D = or i64 %B, %C
55	ret i64 %D
56}
57
58define i64 @rotr64(i64 %A, i8 %Amt) nounwind {
59; 32-LABEL: rotr64:
60; 32:       # BB#0:
61; 32-NEXT:    pushl %ebx
62; 32-NEXT:    pushl %edi
63; 32-NEXT:    pushl %esi
64; 32-NEXT:    movb {{[0-9]+}}(%esp), %cl
65; 32-NEXT:    movl {{[0-9]+}}(%esp), %edi
66; 32-NEXT:    movl {{[0-9]+}}(%esp), %esi
67; 32-NEXT:    movl %esi, %edx
68; 32-NEXT:    shrl %cl, %edx
69; 32-NEXT:    movl %edi, %eax
70; 32-NEXT:    shrdl %cl, %esi, %eax
71; 32-NEXT:    testb $32, %cl
72; 32-NEXT:    je .LBB1_2
73; 32-NEXT:  # BB#1:
74; 32-NEXT:    movl %edx, %eax
75; 32-NEXT:    xorl %edx, %edx
76; 32-NEXT:  .LBB1_2:
77; 32-NEXT:    movb $64, %ch
78; 32-NEXT:    subb %cl, %ch
79; 32-NEXT:    movl %edi, %ebx
80; 32-NEXT:    movb %ch, %cl
81; 32-NEXT:    shll %cl, %ebx
82; 32-NEXT:    shldl %cl, %edi, %esi
83; 32-NEXT:    testb $32, %ch
84; 32-NEXT:    je .LBB1_4
85; 32-NEXT:  # BB#3:
86; 32-NEXT:    movl %ebx, %esi
87; 32-NEXT:    xorl %ebx, %ebx
88; 32-NEXT:  .LBB1_4:
89; 32-NEXT:    orl %ebx, %eax
90; 32-NEXT:    orl %esi, %edx
91; 32-NEXT:    popl %esi
92; 32-NEXT:    popl %edi
93; 32-NEXT:    popl %ebx
94; 32-NEXT:    retl
95;
96; 64-LABEL: rotr64:
97; 64:       # BB#0:
98; 64-NEXT:    movl %esi, %ecx
99; 64-NEXT:    rorq %cl, %rdi
100; 64-NEXT:    movq %rdi, %rax
101; 64-NEXT:    retq
102	%shift.upgrd.3 = zext i8 %Amt to i64
103	%B = lshr i64 %A, %shift.upgrd.3
104	%Amt2 = sub i8 64, %Amt
105	%shift.upgrd.4 = zext i8 %Amt2 to i64
106	%C = shl i64 %A, %shift.upgrd.4
107	%D = or i64 %B, %C
108	ret i64 %D
109}
110
111define i64 @rotli64(i64 %A) nounwind {
112; 32-LABEL: rotli64:
113; 32:       # BB#0:
114; 32-NEXT:    movl {{[0-9]+}}(%esp), %eax
115; 32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
116; 32-NEXT:    movl %ecx, %edx
117; 32-NEXT:    shldl $5, %eax, %edx
118; 32-NEXT:    shldl $5, %ecx, %eax
119; 32-NEXT:    retl
120;
121; 64-LABEL: rotli64:
122; 64:       # BB#0:
123; 64-NEXT:    rolq $5, %rdi
124; 64-NEXT:    movq %rdi, %rax
125; 64-NEXT:    retq
126	%B = shl i64 %A, 5
127	%C = lshr i64 %A, 59
128	%D = or i64 %B, %C
129	ret i64 %D
130}
131
132define i64 @rotri64(i64 %A) nounwind {
133; 32-LABEL: rotri64:
134; 32:       # BB#0:
135; 32-NEXT:    movl {{[0-9]+}}(%esp), %edx
136; 32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
137; 32-NEXT:    movl %ecx, %eax
138; 32-NEXT:    shldl $27, %edx, %eax
139; 32-NEXT:    shldl $27, %ecx, %edx
140; 32-NEXT:    retl
141;
142; 64-LABEL: rotri64:
143; 64:       # BB#0:
144; 64-NEXT:    rolq $59, %rdi
145; 64-NEXT:    movq %rdi, %rax
146; 64-NEXT:    retq
147	%B = lshr i64 %A, 5
148	%C = shl i64 %A, 59
149	%D = or i64 %B, %C
150	ret i64 %D
151}
152
153define i64 @rotl1_64(i64 %A) nounwind {
154; 32-LABEL: rotl1_64:
155; 32:       # BB#0:
156; 32-NEXT:    movl {{[0-9]+}}(%esp), %eax
157; 32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
158; 32-NEXT:    movl %ecx, %edx
159; 32-NEXT:    shldl $1, %eax, %edx
160; 32-NEXT:    shldl $1, %ecx, %eax
161; 32-NEXT:    retl
162;
163; 64-LABEL: rotl1_64:
164; 64:       # BB#0:
165; 64-NEXT:    rolq %rdi
166; 64-NEXT:    movq %rdi, %rax
167; 64-NEXT:    retq
168	%B = shl i64 %A, 1
169	%C = lshr i64 %A, 63
170	%D = or i64 %B, %C
171	ret i64 %D
172}
173
174define i64 @rotr1_64(i64 %A) nounwind {
175; 32-LABEL: rotr1_64:
176; 32:       # BB#0:
177; 32-NEXT:    movl {{[0-9]+}}(%esp), %edx
178; 32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
179; 32-NEXT:    movl %ecx, %eax
180; 32-NEXT:    shldl $31, %edx, %eax
181; 32-NEXT:    shldl $31, %ecx, %edx
182; 32-NEXT:    retl
183;
184; 64-LABEL: rotr1_64:
185; 64:       # BB#0:
186; 64-NEXT:    rorq %rdi
187; 64-NEXT:    movq %rdi, %rax
188; 64-NEXT:    retq
189	%B = shl i64 %A, 63
190	%C = lshr i64 %A, 1
191	%D = or i64 %B, %C
192	ret i64 %D
193}
194
195define i32 @rotl32(i32 %A, i8 %Amt) nounwind {
196; 32-LABEL: rotl32:
197; 32:       # BB#0:
198; 32-NEXT:    movb {{[0-9]+}}(%esp), %cl
199; 32-NEXT:    movl {{[0-9]+}}(%esp), %eax
200; 32-NEXT:    roll %cl, %eax
201; 32-NEXT:    retl
202;
203; 64-LABEL: rotl32:
204; 64:       # BB#0:
205; 64-NEXT:    movl %esi, %ecx
206; 64-NEXT:    roll %cl, %edi
207; 64-NEXT:    movl %edi, %eax
208; 64-NEXT:    retq
209	%shift.upgrd.1 = zext i8 %Amt to i32
210	%B = shl i32 %A, %shift.upgrd.1
211	%Amt2 = sub i8 32, %Amt
212	%shift.upgrd.2 = zext i8 %Amt2 to i32
213	%C = lshr i32 %A, %shift.upgrd.2
214	%D = or i32 %B, %C
215	ret i32 %D
216}
217
218define i32 @rotr32(i32 %A, i8 %Amt) nounwind {
219; 32-LABEL: rotr32:
220; 32:       # BB#0:
221; 32-NEXT:    movb {{[0-9]+}}(%esp), %cl
222; 32-NEXT:    movl {{[0-9]+}}(%esp), %eax
223; 32-NEXT:    rorl %cl, %eax
224; 32-NEXT:    retl
225;
226; 64-LABEL: rotr32:
227; 64:       # BB#0:
228; 64-NEXT:    movl %esi, %ecx
229; 64-NEXT:    rorl %cl, %edi
230; 64-NEXT:    movl %edi, %eax
231; 64-NEXT:    retq
232	%shift.upgrd.3 = zext i8 %Amt to i32
233	%B = lshr i32 %A, %shift.upgrd.3
234	%Amt2 = sub i8 32, %Amt
235	%shift.upgrd.4 = zext i8 %Amt2 to i32
236	%C = shl i32 %A, %shift.upgrd.4
237	%D = or i32 %B, %C
238	ret i32 %D
239}
240
241define i32 @rotli32(i32 %A) nounwind {
242; 32-LABEL: rotli32:
243; 32:       # BB#0:
244; 32-NEXT:    movl {{[0-9]+}}(%esp), %eax
245; 32-NEXT:    roll $5, %eax
246; 32-NEXT:    retl
247;
248; 64-LABEL: rotli32:
249; 64:       # BB#0:
250; 64-NEXT:    roll $5, %edi
251; 64-NEXT:    movl %edi, %eax
252; 64-NEXT:    retq
253	%B = shl i32 %A, 5
254	%C = lshr i32 %A, 27
255	%D = or i32 %B, %C
256	ret i32 %D
257}
258
259define i32 @rotri32(i32 %A) nounwind {
260; 32-LABEL: rotri32:
261; 32:       # BB#0:
262; 32-NEXT:    movl {{[0-9]+}}(%esp), %eax
263; 32-NEXT:    roll $27, %eax
264; 32-NEXT:    retl
265;
266; 64-LABEL: rotri32:
267; 64:       # BB#0:
268; 64-NEXT:    roll $27, %edi
269; 64-NEXT:    movl %edi, %eax
270; 64-NEXT:    retq
271	%B = lshr i32 %A, 5
272	%C = shl i32 %A, 27
273	%D = or i32 %B, %C
274	ret i32 %D
275}
276
277define i32 @rotl1_32(i32 %A) nounwind {
278; 32-LABEL: rotl1_32:
279; 32:       # BB#0:
280; 32-NEXT:    movl {{[0-9]+}}(%esp), %eax
281; 32-NEXT:    roll %eax
282; 32-NEXT:    retl
283;
284; 64-LABEL: rotl1_32:
285; 64:       # BB#0:
286; 64-NEXT:    roll %edi
287; 64-NEXT:    movl %edi, %eax
288; 64-NEXT:    retq
289	%B = shl i32 %A, 1
290	%C = lshr i32 %A, 31
291	%D = or i32 %B, %C
292	ret i32 %D
293}
294
295define i32 @rotr1_32(i32 %A) nounwind {
296; 32-LABEL: rotr1_32:
297; 32:       # BB#0:
298; 32-NEXT:    movl {{[0-9]+}}(%esp), %eax
299; 32-NEXT:    rorl %eax
300; 32-NEXT:    retl
301;
302; 64-LABEL: rotr1_32:
303; 64:       # BB#0:
304; 64-NEXT:    rorl %edi
305; 64-NEXT:    movl %edi, %eax
306; 64-NEXT:    retq
307	%B = shl i32 %A, 31
308	%C = lshr i32 %A, 1
309	%D = or i32 %B, %C
310	ret i32 %D
311}
312
313define i16 @rotl16(i16 %A, i8 %Amt) nounwind {
314; 32-LABEL: rotl16:
315; 32:       # BB#0:
316; 32-NEXT:    movb {{[0-9]+}}(%esp), %cl
317; 32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
318; 32-NEXT:    rolw %cl, %ax
319; 32-NEXT:    retl
320;
321; 64-LABEL: rotl16:
322; 64:       # BB#0:
323; 64-NEXT:    movl %esi, %ecx
324; 64-NEXT:    rolw %cl, %di
325; 64-NEXT:    movl %edi, %eax
326; 64-NEXT:    retq
327	%shift.upgrd.5 = zext i8 %Amt to i16
328	%B = shl i16 %A, %shift.upgrd.5
329	%Amt2 = sub i8 16, %Amt
330	%shift.upgrd.6 = zext i8 %Amt2 to i16
331	%C = lshr i16 %A, %shift.upgrd.6
332	%D = or i16 %B, %C
333	ret i16 %D
334}
335
336define i16 @rotr16(i16 %A, i8 %Amt) nounwind {
337; 32-LABEL: rotr16:
338; 32:       # BB#0:
339; 32-NEXT:    movb {{[0-9]+}}(%esp), %cl
340; 32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
341; 32-NEXT:    rorw %cl, %ax
342; 32-NEXT:    retl
343;
344; 64-LABEL: rotr16:
345; 64:       # BB#0:
346; 64-NEXT:    movl %esi, %ecx
347; 64-NEXT:    rorw %cl, %di
348; 64-NEXT:    movl %edi, %eax
349; 64-NEXT:    retq
350	%shift.upgrd.7 = zext i8 %Amt to i16
351	%B = lshr i16 %A, %shift.upgrd.7
352	%Amt2 = sub i8 16, %Amt
353	%shift.upgrd.8 = zext i8 %Amt2 to i16
354	%C = shl i16 %A, %shift.upgrd.8
355	%D = or i16 %B, %C
356	ret i16 %D
357}
358
359define i16 @rotli16(i16 %A) nounwind {
360; 32-LABEL: rotli16:
361; 32:       # BB#0:
362; 32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
363; 32-NEXT:    rolw $5, %ax
364; 32-NEXT:    retl
365;
366; 64-LABEL: rotli16:
367; 64:       # BB#0:
368; 64-NEXT:    rolw $5, %di
369; 64-NEXT:    movl %edi, %eax
370; 64-NEXT:    retq
371	%B = shl i16 %A, 5
372	%C = lshr i16 %A, 11
373	%D = or i16 %B, %C
374	ret i16 %D
375}
376
377define i16 @rotri16(i16 %A) nounwind {
378; 32-LABEL: rotri16:
379; 32:       # BB#0:
380; 32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
381; 32-NEXT:    rolw $11, %ax
382; 32-NEXT:    retl
383;
384; 64-LABEL: rotri16:
385; 64:       # BB#0:
386; 64-NEXT:    rolw $11, %di
387; 64-NEXT:    movl %edi, %eax
388; 64-NEXT:    retq
389	%B = lshr i16 %A, 5
390	%C = shl i16 %A, 11
391	%D = or i16 %B, %C
392	ret i16 %D
393}
394
395define i16 @rotl1_16(i16 %A) nounwind {
396; 32-LABEL: rotl1_16:
397; 32:       # BB#0:
398; 32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
399; 32-NEXT:    rolw %ax
400; 32-NEXT:    retl
401;
402; 64-LABEL: rotl1_16:
403; 64:       # BB#0:
404; 64-NEXT:    rolw %di
405; 64-NEXT:    movl %edi, %eax
406; 64-NEXT:    retq
407	%B = shl i16 %A, 1
408	%C = lshr i16 %A, 15
409	%D = or i16 %B, %C
410	ret i16 %D
411}
412
413define i16 @rotr1_16(i16 %A) nounwind {
414; 32-LABEL: rotr1_16:
415; 32:       # BB#0:
416; 32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
417; 32-NEXT:    rorw %ax
418; 32-NEXT:    retl
419;
420; 64-LABEL: rotr1_16:
421; 64:       # BB#0:
422; 64-NEXT:    rorw %di
423; 64-NEXT:    movl %edi, %eax
424; 64-NEXT:    retq
425	%B = lshr i16 %A, 1
426	%C = shl i16 %A, 15
427	%D = or i16 %B, %C
428	ret i16 %D
429}
430
431define i8 @rotl8(i8 %A, i8 %Amt) nounwind {
432; 32-LABEL: rotl8:
433; 32:       # BB#0:
434; 32-NEXT:    movb {{[0-9]+}}(%esp), %cl
435; 32-NEXT:    movb {{[0-9]+}}(%esp), %al
436; 32-NEXT:    rolb %cl, %al
437; 32-NEXT:    retl
438;
439; 64-LABEL: rotl8:
440; 64:       # BB#0:
441; 64-NEXT:    movl %esi, %ecx
442; 64-NEXT:    rolb %cl, %dil
443; 64-NEXT:    movl %edi, %eax
444; 64-NEXT:    retq
445	%B = shl i8 %A, %Amt
446	%Amt2 = sub i8 8, %Amt
447	%C = lshr i8 %A, %Amt2
448	%D = or i8 %B, %C
449	ret i8 %D
450}
451
452define i8 @rotr8(i8 %A, i8 %Amt) nounwind {
453; 32-LABEL: rotr8:
454; 32:       # BB#0:
455; 32-NEXT:    movb {{[0-9]+}}(%esp), %cl
456; 32-NEXT:    movb {{[0-9]+}}(%esp), %al
457; 32-NEXT:    rorb %cl, %al
458; 32-NEXT:    retl
459;
460; 64-LABEL: rotr8:
461; 64:       # BB#0:
462; 64-NEXT:    movl %esi, %ecx
463; 64-NEXT:    rorb %cl, %dil
464; 64-NEXT:    movl %edi, %eax
465; 64-NEXT:    retq
466	%B = lshr i8 %A, %Amt
467	%Amt2 = sub i8 8, %Amt
468	%C = shl i8 %A, %Amt2
469	%D = or i8 %B, %C
470	ret i8 %D
471}
472
473define i8 @rotli8(i8 %A) nounwind {
474; 32-LABEL: rotli8:
475; 32:       # BB#0:
476; 32-NEXT:    movb {{[0-9]+}}(%esp), %al
477; 32-NEXT:    rolb $5, %al
478; 32-NEXT:    retl
479;
480; 64-LABEL: rotli8:
481; 64:       # BB#0:
482; 64-NEXT:    rolb $5, %dil
483; 64-NEXT:    movl %edi, %eax
484; 64-NEXT:    retq
485	%B = shl i8 %A, 5
486	%C = lshr i8 %A, 3
487	%D = or i8 %B, %C
488	ret i8 %D
489}
490
491define i8 @rotri8(i8 %A) nounwind {
492; 32-LABEL: rotri8:
493; 32:       # BB#0:
494; 32-NEXT:    movb {{[0-9]+}}(%esp), %al
495; 32-NEXT:    rolb $3, %al
496; 32-NEXT:    retl
497;
498; 64-LABEL: rotri8:
499; 64:       # BB#0:
500; 64-NEXT:    rolb $3, %dil
501; 64-NEXT:    movl %edi, %eax
502; 64-NEXT:    retq
503	%B = lshr i8 %A, 5
504	%C = shl i8 %A, 3
505	%D = or i8 %B, %C
506	ret i8 %D
507}
508
509define i8 @rotl1_8(i8 %A) nounwind {
510; 32-LABEL: rotl1_8:
511; 32:       # BB#0:
512; 32-NEXT:    movb {{[0-9]+}}(%esp), %al
513; 32-NEXT:    rolb %al
514; 32-NEXT:    retl
515;
516; 64-LABEL: rotl1_8:
517; 64:       # BB#0:
518; 64-NEXT:    rolb %dil
519; 64-NEXT:    movl %edi, %eax
520; 64-NEXT:    retq
521	%B = shl i8 %A, 1
522	%C = lshr i8 %A, 7
523	%D = or i8 %B, %C
524	ret i8 %D
525}
526
527define i8 @rotr1_8(i8 %A) nounwind {
528; 32-LABEL: rotr1_8:
529; 32:       # BB#0:
530; 32-NEXT:    movb {{[0-9]+}}(%esp), %al
531; 32-NEXT:    rorb %al
532; 32-NEXT:    retl
533;
534; 64-LABEL: rotr1_8:
535; 64:       # BB#0:
536; 64-NEXT:    rorb %dil
537; 64-NEXT:    movl %edi, %eax
538; 64-NEXT:    retq
539	%B = lshr i8 %A, 1
540	%C = shl i8 %A, 7
541	%D = or i8 %B, %C
542	ret i8 %D
543}
544