xref: /llvm-project/llvm/test/CodeGen/X86/rotate.ll (revision 7b3bbd83c0c24087072ec5b22a76799ab31f87d5)
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
4
5define i64 @rotl64(i64 %A, i8 %Amt) nounwind {
6; X86-LABEL: rotl64:
7; X86:       # %bb.0:
8; X86-NEXT:    pushl %ebx
9; X86-NEXT:    pushl %edi
10; X86-NEXT:    pushl %esi
11; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
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
20; X86-NEXT:  # %bb.1:
21; X86-NEXT:    movl %eax, %edx
22; X86-NEXT:    xorl %eax, %eax
23; X86-NEXT:  .LBB0_2:
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
32; X86-NEXT:  # %bb.3:
33; X86-NEXT:    movl %ebx, %esi
34; X86-NEXT:    xorl %ebx, %ebx
35; X86-NEXT:  .LBB0_4:
36; X86-NEXT:    orl %ebx, %edx
37; X86-NEXT:    orl %esi, %eax
38; X86-NEXT:    popl %esi
39; X86-NEXT:    popl %edi
40; X86-NEXT:    popl %ebx
41; X86-NEXT:    retl
42;
43; X64-LABEL: rotl64:
44; X64:       # %bb.0:
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
49; X64-NEXT:    retq
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
55	%D = or i64 %B, %C
56	ret i64 %D
57}
58
59define i64 @rotr64(i64 %A, i8 %Amt) nounwind {
60; X86-LABEL: rotr64:
61; X86:       # %bb.0:
62; X86-NEXT:    pushl %ebx
63; X86-NEXT:    pushl %edi
64; X86-NEXT:    pushl %esi
65; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
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
74; X86-NEXT:  # %bb.1:
75; X86-NEXT:    movl %edx, %eax
76; X86-NEXT:    xorl %edx, %edx
77; X86-NEXT:  .LBB1_2:
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
86; X86-NEXT:  # %bb.3:
87; X86-NEXT:    movl %ebx, %esi
88; X86-NEXT:    xorl %ebx, %ebx
89; X86-NEXT:  .LBB1_4:
90; X86-NEXT:    orl %esi, %edx
91; X86-NEXT:    orl %ebx, %eax
92; X86-NEXT:    popl %esi
93; X86-NEXT:    popl %edi
94; X86-NEXT:    popl %ebx
95; X86-NEXT:    retl
96;
97; X64-LABEL: rotr64:
98; X64:       # %bb.0:
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
103; X64-NEXT:    retq
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
109	%D = or i64 %B, %C
110	ret i64 %D
111}
112
113define i64 @rotli64(i64 %A) nounwind {
114; X86-LABEL: rotli64:
115; X86:       # %bb.0:
116; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
117; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
118; X86-NEXT:    movl %ecx, %eax
119; X86-NEXT:    shldl $5, %edx, %eax
120; X86-NEXT:    shldl $5, %ecx, %edx
121; X86-NEXT:    retl
122;
123; X64-LABEL: rotli64:
124; X64:       # %bb.0:
125; X64-NEXT:    movq %rdi, %rax
126; X64-NEXT:    rolq $5, %rax
127; X64-NEXT:    retq
128	%B = shl i64 %A, 5
129	%C = lshr i64 %A, 59
130	%D = or i64 %B, %C
131	ret i64 %D
132}
133
134define i64 @rotri64(i64 %A) nounwind {
135; X86-LABEL: rotri64:
136; X86:       # %bb.0:
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
142; X86-NEXT:    retl
143;
144; X64-LABEL: rotri64:
145; X64:       # %bb.0:
146; X64-NEXT:    movq %rdi, %rax
147; X64-NEXT:    rolq $59, %rax
148; X64-NEXT:    retq
149	%B = lshr i64 %A, 5
150	%C = shl i64 %A, 59
151	%D = or i64 %B, %C
152	ret i64 %D
153}
154
155define i64 @rotl1_64(i64 %A) nounwind {
156; X86-LABEL: rotl1_64:
157; X86:       # %bb.0:
158; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
159; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
160; X86-NEXT:    movl %ecx, %eax
161; X86-NEXT:    shldl $1, %edx, %eax
162; X86-NEXT:    shldl $1, %ecx, %edx
163; X86-NEXT:    retl
164;
165; X64-LABEL: rotl1_64:
166; X64:       # %bb.0:
167; X64-NEXT:    movq %rdi, %rax
168; X64-NEXT:    rolq %rax
169; X64-NEXT:    retq
170	%B = shl i64 %A, 1
171	%C = lshr i64 %A, 63
172	%D = or i64 %B, %C
173	ret i64 %D
174}
175
176define i64 @rotr1_64(i64 %A) nounwind {
177; X86-LABEL: rotr1_64:
178; X86:       # %bb.0:
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
184; X86-NEXT:    retl
185;
186; X64-LABEL: rotr1_64:
187; X64:       # %bb.0:
188; X64-NEXT:    movq %rdi, %rax
189; X64-NEXT:    rorq %rax
190; X64-NEXT:    retq
191	%B = shl i64 %A, 63
192	%C = lshr i64 %A, 1
193	%D = or i64 %B, %C
194	ret i64 %D
195}
196
197define i32 @rotl32(i32 %A, i8 %Amt) nounwind {
198; X86-LABEL: rotl32:
199; X86:       # %bb.0:
200; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
201; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
202; X86-NEXT:    roll %cl, %eax
203; X86-NEXT:    retl
204;
205; X64-LABEL: rotl32:
206; X64:       # %bb.0:
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
211; X64-NEXT:    retq
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
217	%D = or i32 %B, %C
218	ret i32 %D
219}
220
221define i32 @rotr32(i32 %A, i8 %Amt) nounwind {
222; X86-LABEL: rotr32:
223; X86:       # %bb.0:
224; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
225; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
226; X86-NEXT:    rorl %cl, %eax
227; X86-NEXT:    retl
228;
229; X64-LABEL: rotr32:
230; X64:       # %bb.0:
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
235; X64-NEXT:    retq
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
241	%D = or i32 %B, %C
242	ret i32 %D
243}
244
245define i32 @rotli32(i32 %A) nounwind {
246; X86-LABEL: rotli32:
247; X86:       # %bb.0:
248; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
249; X86-NEXT:    roll $5, %eax
250; X86-NEXT:    retl
251;
252; X64-LABEL: rotli32:
253; X64:       # %bb.0:
254; X64-NEXT:    movl %edi, %eax
255; X64-NEXT:    roll $5, %eax
256; X64-NEXT:    retq
257	%B = shl i32 %A, 5
258	%C = lshr i32 %A, 27
259	%D = or i32 %B, %C
260	ret i32 %D
261}
262
263define i32 @rotri32(i32 %A) nounwind {
264; X86-LABEL: rotri32:
265; X86:       # %bb.0:
266; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
267; X86-NEXT:    roll $27, %eax
268; X86-NEXT:    retl
269;
270; X64-LABEL: rotri32:
271; X64:       # %bb.0:
272; X64-NEXT:    movl %edi, %eax
273; X64-NEXT:    roll $27, %eax
274; X64-NEXT:    retq
275	%B = lshr i32 %A, 5
276	%C = shl i32 %A, 27
277	%D = or i32 %B, %C
278	ret i32 %D
279}
280
281define i32 @rotl1_32(i32 %A) nounwind {
282; X86-LABEL: rotl1_32:
283; X86:       # %bb.0:
284; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
285; X86-NEXT:    roll %eax
286; X86-NEXT:    retl
287;
288; X64-LABEL: rotl1_32:
289; X64:       # %bb.0:
290; X64-NEXT:    movl %edi, %eax
291; X64-NEXT:    roll %eax
292; X64-NEXT:    retq
293	%B = shl i32 %A, 1
294	%C = lshr i32 %A, 31
295	%D = or i32 %B, %C
296	ret i32 %D
297}
298
299define i32 @rotr1_32(i32 %A) nounwind {
300; X86-LABEL: rotr1_32:
301; X86:       # %bb.0:
302; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
303; X86-NEXT:    rorl %eax
304; X86-NEXT:    retl
305;
306; X64-LABEL: rotr1_32:
307; X64:       # %bb.0:
308; X64-NEXT:    movl %edi, %eax
309; X64-NEXT:    rorl %eax
310; X64-NEXT:    retq
311	%B = shl i32 %A, 31
312	%C = lshr i32 %A, 1
313	%D = or i32 %B, %C
314	ret i32 %D
315}
316
317define i16 @rotl16(i16 %A, i8 %Amt) nounwind {
318; X86-LABEL: rotl16:
319; X86:       # %bb.0:
320; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
321; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
322; X86-NEXT:    rolw %cl, %ax
323; X86-NEXT:    retl
324;
325; X64-LABEL: rotl16:
326; X64:       # %bb.0:
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
332; X64-NEXT:    retq
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
338	%D = or i16 %B, %C
339	ret i16 %D
340}
341
342define i16 @rotr16(i16 %A, i8 %Amt) nounwind {
343; X86-LABEL: rotr16:
344; X86:       # %bb.0:
345; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
346; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
347; X86-NEXT:    rorw %cl, %ax
348; X86-NEXT:    retl
349;
350; X64-LABEL: rotr16:
351; X64:       # %bb.0:
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
357; X64-NEXT:    retq
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
363	%D = or i16 %B, %C
364	ret i16 %D
365}
366
367define i16 @rotli16(i16 %A) nounwind {
368; X86-LABEL: rotli16:
369; X86:       # %bb.0:
370; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
371; X86-NEXT:    rolw $5, %ax
372; X86-NEXT:    retl
373;
374; X64-LABEL: rotli16:
375; X64:       # %bb.0:
376; X64-NEXT:    movl %edi, %eax
377; X64-NEXT:    rolw $5, %ax
378; X64-NEXT:    # kill: def $ax killed $ax killed $eax
379; X64-NEXT:    retq
380	%B = shl i16 %A, 5
381	%C = lshr i16 %A, 11
382	%D = or i16 %B, %C
383	ret i16 %D
384}
385
386define i16 @rotri16(i16 %A) nounwind {
387; X86-LABEL: rotri16:
388; X86:       # %bb.0:
389; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
390; X86-NEXT:    rolw $11, %ax
391; X86-NEXT:    retl
392;
393; X64-LABEL: rotri16:
394; X64:       # %bb.0:
395; X64-NEXT:    movl %edi, %eax
396; X64-NEXT:    rolw $11, %ax
397; X64-NEXT:    # kill: def $ax killed $ax killed $eax
398; X64-NEXT:    retq
399	%B = lshr i16 %A, 5
400	%C = shl i16 %A, 11
401	%D = or i16 %B, %C
402	ret i16 %D
403}
404
405define i16 @rotl1_16(i16 %A) nounwind {
406; X86-LABEL: rotl1_16:
407; X86:       # %bb.0:
408; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
409; X86-NEXT:    rolw %ax
410; X86-NEXT:    retl
411;
412; X64-LABEL: rotl1_16:
413; X64:       # %bb.0:
414; X64-NEXT:    movl %edi, %eax
415; X64-NEXT:    rolw %ax
416; X64-NEXT:    # kill: def $ax killed $ax killed $eax
417; X64-NEXT:    retq
418	%B = shl i16 %A, 1
419	%C = lshr i16 %A, 15
420	%D = or i16 %B, %C
421	ret i16 %D
422}
423
424define i16 @rotr1_16(i16 %A) nounwind {
425; X86-LABEL: rotr1_16:
426; X86:       # %bb.0:
427; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
428; X86-NEXT:    rorw %ax
429; X86-NEXT:    retl
430;
431; X64-LABEL: rotr1_16:
432; X64:       # %bb.0:
433; X64-NEXT:    movl %edi, %eax
434; X64-NEXT:    rorw %ax
435; X64-NEXT:    # kill: def $ax killed $ax killed $eax
436; X64-NEXT:    retq
437	%B = lshr i16 %A, 1
438	%C = shl i16 %A, 15
439	%D = or i16 %B, %C
440	ret i16 %D
441}
442
443define i8 @rotl8(i8 %A, i8 %Amt) nounwind {
444; X86-LABEL: rotl8:
445; X86:       # %bb.0:
446; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
447; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
448; X86-NEXT:    rolb %cl, %al
449; X86-NEXT:    retl
450;
451; X64-LABEL: rotl8:
452; X64:       # %bb.0:
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
458; X64-NEXT:    retq
459	%B = shl i8 %A, %Amt
460	%Amt2 = sub i8 8, %Amt
461	%C = lshr i8 %A, %Amt2
462	%D = or i8 %B, %C
463	ret i8 %D
464}
465
466define i8 @rotr8(i8 %A, i8 %Amt) nounwind {
467; X86-LABEL: rotr8:
468; X86:       # %bb.0:
469; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
470; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
471; X86-NEXT:    rorb %cl, %al
472; X86-NEXT:    retl
473;
474; X64-LABEL: rotr8:
475; X64:       # %bb.0:
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
481; X64-NEXT:    retq
482	%B = lshr i8 %A, %Amt
483	%Amt2 = sub i8 8, %Amt
484	%C = shl i8 %A, %Amt2
485	%D = or i8 %B, %C
486	ret i8 %D
487}
488
489define i8 @rotli8(i8 %A) nounwind {
490; X86-LABEL: rotli8:
491; X86:       # %bb.0:
492; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
493; X86-NEXT:    rolb $5, %al
494; X86-NEXT:    retl
495;
496; X64-LABEL: rotli8:
497; X64:       # %bb.0:
498; X64-NEXT:    movl %edi, %eax
499; X64-NEXT:    rolb $5, %al
500; X64-NEXT:    # kill: def $al killed $al killed $eax
501; X64-NEXT:    retq
502	%B = shl i8 %A, 5
503	%C = lshr i8 %A, 3
504	%D = or i8 %B, %C
505	ret i8 %D
506}
507
508define i8 @rotri8(i8 %A) nounwind {
509; X86-LABEL: rotri8:
510; X86:       # %bb.0:
511; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
512; X86-NEXT:    rolb $3, %al
513; X86-NEXT:    retl
514;
515; X64-LABEL: rotri8:
516; X64:       # %bb.0:
517; X64-NEXT:    movl %edi, %eax
518; X64-NEXT:    rolb $3, %al
519; X64-NEXT:    # kill: def $al killed $al killed $eax
520; X64-NEXT:    retq
521	%B = lshr i8 %A, 5
522	%C = shl i8 %A, 3
523	%D = or i8 %B, %C
524	ret i8 %D
525}
526
527define i8 @rotl1_8(i8 %A) nounwind {
528; X86-LABEL: rotl1_8:
529; X86:       # %bb.0:
530; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
531; X86-NEXT:    rolb %al
532; X86-NEXT:    retl
533;
534; X64-LABEL: rotl1_8:
535; X64:       # %bb.0:
536; X64-NEXT:    movl %edi, %eax
537; X64-NEXT:    rolb %al
538; X64-NEXT:    # kill: def $al killed $al killed $eax
539; X64-NEXT:    retq
540	%B = shl i8 %A, 1
541	%C = lshr i8 %A, 7
542	%D = or i8 %B, %C
543	ret i8 %D
544}
545
546define i8 @rotr1_8(i8 %A) nounwind {
547; X86-LABEL: rotr1_8:
548; X86:       # %bb.0:
549; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
550; X86-NEXT:    rorb %al
551; X86-NEXT:    retl
552;
553; X64-LABEL: rotr1_8:
554; X64:       # %bb.0:
555; X64-NEXT:    movl %edi, %eax
556; X64-NEXT:    rorb %al
557; X64-NEXT:    # kill: def $al killed $al killed $eax
558; X64-NEXT:    retq
559	%B = lshr i8 %A, 1
560	%C = shl i8 %A, 7
561	%D = or i8 %B, %C
562	ret i8 %D
563}
564
565define void @rotr1_64_mem(ptr %Aptr) nounwind {
566; X86-LABEL: rotr1_64_mem:
567; X86:       # %bb.0:
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 %ecx, %esi
573; X86-NEXT:    shldl $31, %edx, %esi
574; X86-NEXT:    shldl $31, %ecx, %edx
575; X86-NEXT:    movl %edx, (%eax)
576; X86-NEXT:    movl %esi, 4(%eax)
577; X86-NEXT:    popl %esi
578; X86-NEXT:    retl
579;
580; X64-LABEL: rotr1_64_mem:
581; X64:       # %bb.0:
582; X64-NEXT:    rorq (%rdi)
583; X64-NEXT:    retq
584
585  %A = load i64, ptr%Aptr
586  %B = shl i64 %A, 63
587  %C = lshr i64 %A, 1
588  %D = or i64 %B, %C
589  store i64 %D, ptr %Aptr
590  ret void
591}
592
593define void @rotr1_32_mem(ptr %Aptr) nounwind {
594; X86-LABEL: rotr1_32_mem:
595; X86:       # %bb.0:
596; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
597; X86-NEXT:    rorl (%eax)
598; X86-NEXT:    retl
599;
600; X64-LABEL: rotr1_32_mem:
601; X64:       # %bb.0:
602; X64-NEXT:    rorl (%rdi)
603; X64-NEXT:    retq
604  %A = load i32, ptr%Aptr
605  %B = shl i32 %A, 31
606  %C = lshr i32 %A, 1
607  %D = or i32 %B, %C
608  store i32 %D, ptr %Aptr
609  ret void
610}
611
612define void @rotr1_16_mem(ptr %Aptr) nounwind {
613; X86-LABEL: rotr1_16_mem:
614; X86:       # %bb.0:
615; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
616; X86-NEXT:    rorw (%eax)
617; X86-NEXT:    retl
618;
619; X64-LABEL: rotr1_16_mem:
620; X64:       # %bb.0:
621; X64-NEXT:    rorw (%rdi)
622; X64-NEXT:    retq
623  %A = load i16, ptr%Aptr
624  %B = shl i16 %A, 15
625  %C = lshr i16 %A, 1
626  %D = or i16 %B, %C
627  store i16 %D, ptr %Aptr
628  ret void
629}
630
631define void @rotr1_8_mem(ptr %Aptr) nounwind {
632; X86-LABEL: rotr1_8_mem:
633; X86:       # %bb.0:
634; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
635; X86-NEXT:    rorb (%eax)
636; X86-NEXT:    retl
637;
638; X64-LABEL: rotr1_8_mem:
639; X64:       # %bb.0:
640; X64-NEXT:    rorb (%rdi)
641; X64-NEXT:    retq
642  %A = load i8, ptr%Aptr
643  %B = shl i8 %A, 7
644  %C = lshr i8 %A, 1
645  %D = or i8 %B, %C
646  store i8 %D, ptr %Aptr
647  ret void
648}
649
650define 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:    movzbl {{[0-9]+}}(%esp), %ecx
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
683; X86-NEXT:    retl
684;
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
691; X64-NEXT:    retq
692entry:
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
700  ret i64 %and
701}
702