blob: fa1679902ecaf8c5a9785b1e1c1722e914d56114 [file] [log] [blame]
Sanjay Patelc71adc82018-07-16 22:59:31 +00001; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=i686-- -mattr=sse2 | FileCheck %s --check-prefixes=ANY,X32-SSE2
3; RUN: llc < %s -mtriple=x86_64-- -mattr=avx2 | FileCheck %s --check-prefixes=ANY,X64-AVX2
4
5declare i8 @llvm.fshl.i8(i8, i8, i8)
6declare i16 @llvm.fshl.i16(i16, i16, i16)
7declare i32 @llvm.fshl.i32(i32, i32, i32)
8declare i64 @llvm.fshl.i64(i64, i64, i64)
9declare <4 x i32> @llvm.fshl.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
10
11declare i8 @llvm.fshr.i8(i8, i8, i8)
12declare i16 @llvm.fshr.i16(i16, i16, i16)
13declare i32 @llvm.fshr.i32(i32, i32, i32)
14declare i64 @llvm.fshr.i64(i64, i64, i64)
15declare <4 x i32> @llvm.fshr.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
16
17; When first 2 operands match, it's a rotate.
18
19define i8 @rotl_i8_const_shift(i8 %x) nounwind {
20; X32-SSE2-LABEL: rotl_i8_const_shift:
21; X32-SSE2: # %bb.0:
22; X32-SSE2-NEXT: movb {{[0-9]+}}(%esp), %al
23; X32-SSE2-NEXT: rolb $3, %al
24; X32-SSE2-NEXT: retl
25;
26; X64-AVX2-LABEL: rotl_i8_const_shift:
27; X64-AVX2: # %bb.0:
Sanjay Patelc71adc82018-07-16 22:59:31 +000028; X64-AVX2-NEXT: movl %edi, %eax
Simon Pilgrim2d0f20c2018-09-19 18:59:08 +000029; X64-AVX2-NEXT: rolb $3, %al
30; X64-AVX2-NEXT: # kill: def $al killed $al killed $eax
Sanjay Patelc71adc82018-07-16 22:59:31 +000031; X64-AVX2-NEXT: retq
32 %f = call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 3)
33 ret i8 %f
34}
35
36define i64 @rotl_i64_const_shift(i64 %x) nounwind {
37; X32-SSE2-LABEL: rotl_i64_const_shift:
38; X32-SSE2: # %bb.0:
39; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %ecx
40; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %edx
41; X32-SSE2-NEXT: movl %ecx, %eax
42; X32-SSE2-NEXT: shldl $3, %edx, %eax
43; X32-SSE2-NEXT: shldl $3, %ecx, %edx
44; X32-SSE2-NEXT: retl
45;
46; X64-AVX2-LABEL: rotl_i64_const_shift:
47; X64-AVX2: # %bb.0:
Sanjay Patelc71adc82018-07-16 22:59:31 +000048; X64-AVX2-NEXT: movq %rdi, %rax
Simon Pilgrim2d0f20c2018-09-19 18:59:08 +000049; X64-AVX2-NEXT: rolq $3, %rax
Sanjay Patelc71adc82018-07-16 22:59:31 +000050; X64-AVX2-NEXT: retq
51 %f = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 3)
52 ret i64 %f
53}
54
55define i16 @rotl_i16(i16 %x, i16 %z) nounwind {
56; X32-SSE2-LABEL: rotl_i16:
57; X32-SSE2: # %bb.0:
58; X32-SSE2-NEXT: movb {{[0-9]+}}(%esp), %cl
59; X32-SSE2-NEXT: movzwl {{[0-9]+}}(%esp), %eax
60; X32-SSE2-NEXT: rolw %cl, %ax
61; X32-SSE2-NEXT: retl
62;
63; X64-AVX2-LABEL: rotl_i16:
64; X64-AVX2: # %bb.0:
65; X64-AVX2-NEXT: movl %esi, %ecx
Sanjay Patelc71adc82018-07-16 22:59:31 +000066; X64-AVX2-NEXT: movl %edi, %eax
Simon Pilgrim2d0f20c2018-09-19 18:59:08 +000067; X64-AVX2-NEXT: # kill: def $cl killed $cl killed $ecx
68; X64-AVX2-NEXT: rolw %cl, %ax
69; X64-AVX2-NEXT: # kill: def $ax killed $ax killed $eax
Sanjay Patelc71adc82018-07-16 22:59:31 +000070; X64-AVX2-NEXT: retq
71 %f = call i16 @llvm.fshl.i16(i16 %x, i16 %x, i16 %z)
72 ret i16 %f
73}
74
75define i32 @rotl_i32(i32 %x, i32 %z) nounwind {
76; X32-SSE2-LABEL: rotl_i32:
77; X32-SSE2: # %bb.0:
78; X32-SSE2-NEXT: movb {{[0-9]+}}(%esp), %cl
79; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax
80; X32-SSE2-NEXT: roll %cl, %eax
81; X32-SSE2-NEXT: retl
82;
83; X64-AVX2-LABEL: rotl_i32:
84; X64-AVX2: # %bb.0:
85; X64-AVX2-NEXT: movl %esi, %ecx
Sanjay Patelc71adc82018-07-16 22:59:31 +000086; X64-AVX2-NEXT: movl %edi, %eax
Simon Pilgrim2d0f20c2018-09-19 18:59:08 +000087; X64-AVX2-NEXT: # kill: def $cl killed $cl killed $ecx
88; X64-AVX2-NEXT: roll %cl, %eax
Sanjay Patelc71adc82018-07-16 22:59:31 +000089; X64-AVX2-NEXT: retq
90 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 %z)
91 ret i32 %f
92}
93
94; Vector rotate.
95
96define <4 x i32> @rotl_v4i32(<4 x i32> %x, <4 x i32> %z) nounwind {
97; X32-SSE2-LABEL: rotl_v4i32:
98; X32-SSE2: # %bb.0:
Simon Pilgrimb2082552018-12-20 14:56:44 +000099; X32-SSE2-NEXT: pand {{\.LCPI.*}}, %xmm1
Sanjay Patelc71adc82018-07-16 22:59:31 +0000100; X32-SSE2-NEXT: pslld $23, %xmm1
101; X32-SSE2-NEXT: paddd {{\.LCPI.*}}, %xmm1
102; X32-SSE2-NEXT: cvttps2dq %xmm1, %xmm1
Simon Pilgrimb2082552018-12-20 14:56:44 +0000103; X32-SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm0[1,1,3,3]
Sanjay Patelc71adc82018-07-16 22:59:31 +0000104; X32-SSE2-NEXT: pmuludq %xmm1, %xmm0
Simon Pilgrimb2082552018-12-20 14:56:44 +0000105; X32-SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm0[1,3,2,3]
Sanjay Patelc71adc82018-07-16 22:59:31 +0000106; X32-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]
Simon Pilgrimb2082552018-12-20 14:56:44 +0000107; X32-SSE2-NEXT: pmuludq %xmm2, %xmm1
108; X32-SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm1[1,3,2,3]
109; X32-SSE2-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]
110; X32-SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
Sanjay Patelc71adc82018-07-16 22:59:31 +0000111; X32-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
112; X32-SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
Simon Pilgrimb2082552018-12-20 14:56:44 +0000113; X32-SSE2-NEXT: por %xmm3, %xmm0
Sanjay Patelc71adc82018-07-16 22:59:31 +0000114; X32-SSE2-NEXT: retl
115;
116; X64-AVX2-LABEL: rotl_v4i32:
117; X64-AVX2: # %bb.0:
118; X64-AVX2-NEXT: vpbroadcastd {{.*#+}} xmm2 = [31,31,31,31]
Sanjay Patelc71adc82018-07-16 22:59:31 +0000119; X64-AVX2-NEXT: vpand %xmm2, %xmm1, %xmm1
Simon Pilgrimb2082552018-12-20 14:56:44 +0000120; X64-AVX2-NEXT: vpsllvd %xmm1, %xmm0, %xmm2
121; X64-AVX2-NEXT: vpbroadcastd {{.*#+}} xmm3 = [32,32,32,32]
122; X64-AVX2-NEXT: vpsubd %xmm1, %xmm3, %xmm1
Sanjay Patelc71adc82018-07-16 22:59:31 +0000123; X64-AVX2-NEXT: vpsrlvd %xmm1, %xmm0, %xmm0
Simon Pilgrimb2082552018-12-20 14:56:44 +0000124; X64-AVX2-NEXT: vpor %xmm0, %xmm2, %xmm0
Sanjay Patelc71adc82018-07-16 22:59:31 +0000125; X64-AVX2-NEXT: retq
126 %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> %z)
127 ret <4 x i32> %f
128}
129
130; Vector rotate by constant splat amount.
131
132define <4 x i32> @rotl_v4i32_const_shift(<4 x i32> %x) nounwind {
133; X32-SSE2-LABEL: rotl_v4i32_const_shift:
134; X32-SSE2: # %bb.0:
135; X32-SSE2-NEXT: movdqa %xmm0, %xmm1
136; X32-SSE2-NEXT: psrld $29, %xmm1
137; X32-SSE2-NEXT: pslld $3, %xmm0
138; X32-SSE2-NEXT: por %xmm1, %xmm0
139; X32-SSE2-NEXT: retl
140;
141; X64-AVX2-LABEL: rotl_v4i32_const_shift:
142; X64-AVX2: # %bb.0:
143; X64-AVX2-NEXT: vpsrld $29, %xmm0, %xmm1
144; X64-AVX2-NEXT: vpslld $3, %xmm0, %xmm0
145; X64-AVX2-NEXT: vpor %xmm1, %xmm0, %xmm0
146; X64-AVX2-NEXT: retq
147 %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> <i32 3, i32 3, i32 3, i32 3>)
148 ret <4 x i32> %f
149}
150
151; Repeat everything for funnel shift right.
152
153define i8 @rotr_i8_const_shift(i8 %x) nounwind {
154; X32-SSE2-LABEL: rotr_i8_const_shift:
155; X32-SSE2: # %bb.0:
156; X32-SSE2-NEXT: movb {{[0-9]+}}(%esp), %al
Sanjay Patel215dcbf2018-07-25 21:38:30 +0000157; X32-SSE2-NEXT: rorb $3, %al
Sanjay Patelc71adc82018-07-16 22:59:31 +0000158; X32-SSE2-NEXT: retl
159;
160; X64-AVX2-LABEL: rotr_i8_const_shift:
161; X64-AVX2: # %bb.0:
Sanjay Patelc71adc82018-07-16 22:59:31 +0000162; X64-AVX2-NEXT: movl %edi, %eax
Simon Pilgrim2d0f20c2018-09-19 18:59:08 +0000163; X64-AVX2-NEXT: rorb $3, %al
164; X64-AVX2-NEXT: # kill: def $al killed $al killed $eax
Sanjay Patelc71adc82018-07-16 22:59:31 +0000165; X64-AVX2-NEXT: retq
166 %f = call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 3)
167 ret i8 %f
168}
169
170define i32 @rotr_i32_const_shift(i32 %x) nounwind {
171; X32-SSE2-LABEL: rotr_i32_const_shift:
172; X32-SSE2: # %bb.0:
173; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax
Sanjay Patel215dcbf2018-07-25 21:38:30 +0000174; X32-SSE2-NEXT: rorl $3, %eax
Sanjay Patelc71adc82018-07-16 22:59:31 +0000175; X32-SSE2-NEXT: retl
176;
177; X64-AVX2-LABEL: rotr_i32_const_shift:
178; X64-AVX2: # %bb.0:
Sanjay Patelc71adc82018-07-16 22:59:31 +0000179; X64-AVX2-NEXT: movl %edi, %eax
Simon Pilgrim2d0f20c2018-09-19 18:59:08 +0000180; X64-AVX2-NEXT: rorl $3, %eax
Sanjay Patelc71adc82018-07-16 22:59:31 +0000181; X64-AVX2-NEXT: retq
182 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 3)
183 ret i32 %f
184}
185
186; When first 2 operands match, it's a rotate (by variable amount).
187
188define i16 @rotr_i16(i16 %x, i16 %z) nounwind {
189; X32-SSE2-LABEL: rotr_i16:
190; X32-SSE2: # %bb.0:
191; X32-SSE2-NEXT: movb {{[0-9]+}}(%esp), %cl
192; X32-SSE2-NEXT: movzwl {{[0-9]+}}(%esp), %eax
193; X32-SSE2-NEXT: rorw %cl, %ax
194; X32-SSE2-NEXT: retl
195;
196; X64-AVX2-LABEL: rotr_i16:
197; X64-AVX2: # %bb.0:
198; X64-AVX2-NEXT: movl %esi, %ecx
Sanjay Patelc71adc82018-07-16 22:59:31 +0000199; X64-AVX2-NEXT: movl %edi, %eax
Simon Pilgrim2d0f20c2018-09-19 18:59:08 +0000200; X64-AVX2-NEXT: # kill: def $cl killed $cl killed $ecx
201; X64-AVX2-NEXT: rorw %cl, %ax
202; X64-AVX2-NEXT: # kill: def $ax killed $ax killed $eax
Sanjay Patelc71adc82018-07-16 22:59:31 +0000203; X64-AVX2-NEXT: retq
204 %f = call i16 @llvm.fshr.i16(i16 %x, i16 %x, i16 %z)
205 ret i16 %f
206}
207
208define i64 @rotr_i64(i64 %x, i64 %z) nounwind {
209; X32-SSE2-LABEL: rotr_i64:
210; X32-SSE2: # %bb.0:
211; X32-SSE2-NEXT: pushl %ebp
212; X32-SSE2-NEXT: pushl %ebx
213; X32-SSE2-NEXT: pushl %edi
214; X32-SSE2-NEXT: pushl %esi
Sanjay Patele767bf42018-12-08 16:07:38 +0000215; X32-SSE2-NEXT: movb {{[0-9]+}}(%esp), %cl
Sanjay Patelc71adc82018-07-16 22:59:31 +0000216; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %esi
217; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %edx
Sanjay Patelc71adc82018-07-16 22:59:31 +0000218; X32-SSE2-NEXT: movl %edx, %edi
219; X32-SSE2-NEXT: shrl %cl, %edi
Sanjay Patele767bf42018-12-08 16:07:38 +0000220; X32-SSE2-NEXT: movl %esi, %ebx
221; X32-SSE2-NEXT: shrdl %cl, %edx, %ebx
222; X32-SSE2-NEXT: xorl %ebp, %ebp
Sanjay Patelc71adc82018-07-16 22:59:31 +0000223; X32-SSE2-NEXT: testb $32, %cl
Sanjay Patele767bf42018-12-08 16:07:38 +0000224; X32-SSE2-NEXT: cmovnel %edi, %ebx
225; X32-SSE2-NEXT: cmovnel %ebp, %edi
226; X32-SSE2-NEXT: negb %cl
Sanjay Patelc71adc82018-07-16 22:59:31 +0000227; X32-SSE2-NEXT: movl %esi, %eax
228; X32-SSE2-NEXT: shll %cl, %eax
229; X32-SSE2-NEXT: shldl %cl, %esi, %edx
Sanjay Patele767bf42018-12-08 16:07:38 +0000230; X32-SSE2-NEXT: testb $32, %cl
Sanjay Patelc71adc82018-07-16 22:59:31 +0000231; X32-SSE2-NEXT: cmovnel %eax, %edx
Sanjay Patele767bf42018-12-08 16:07:38 +0000232; X32-SSE2-NEXT: cmovnel %ebp, %eax
233; X32-SSE2-NEXT: orl %ebx, %eax
Sanjay Patelc71adc82018-07-16 22:59:31 +0000234; X32-SSE2-NEXT: orl %edi, %edx
235; X32-SSE2-NEXT: popl %esi
236; X32-SSE2-NEXT: popl %edi
237; X32-SSE2-NEXT: popl %ebx
238; X32-SSE2-NEXT: popl %ebp
239; X32-SSE2-NEXT: retl
240;
241; X64-AVX2-LABEL: rotr_i64:
242; X64-AVX2: # %bb.0:
Simon Pilgrim2d0f20c2018-09-19 18:59:08 +0000243; X64-AVX2-NEXT: movq %rsi, %rcx
Sanjay Patelc71adc82018-07-16 22:59:31 +0000244; X64-AVX2-NEXT: movq %rdi, %rax
Simon Pilgrim2d0f20c2018-09-19 18:59:08 +0000245; X64-AVX2-NEXT: # kill: def $cl killed $cl killed $rcx
246; X64-AVX2-NEXT: rorq %cl, %rax
Sanjay Patelc71adc82018-07-16 22:59:31 +0000247; X64-AVX2-NEXT: retq
248 %f = call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 %z)
249 ret i64 %f
250}
251
252; Vector rotate.
253
254define <4 x i32> @rotr_v4i32(<4 x i32> %x, <4 x i32> %z) nounwind {
255; X32-SSE2-LABEL: rotr_v4i32:
256; X32-SSE2: # %bb.0:
Simon Pilgrimb2082552018-12-20 14:56:44 +0000257; X32-SSE2-NEXT: pxor %xmm2, %xmm2
258; X32-SSE2-NEXT: psubd %xmm1, %xmm2
259; X32-SSE2-NEXT: pand {{\.LCPI.*}}, %xmm2
260; X32-SSE2-NEXT: pslld $23, %xmm2
261; X32-SSE2-NEXT: paddd {{\.LCPI.*}}, %xmm2
262; X32-SSE2-NEXT: cvttps2dq %xmm2, %xmm1
263; X32-SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm0[1,1,3,3]
264; X32-SSE2-NEXT: pmuludq %xmm1, %xmm0
265; X32-SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm0[1,3,2,3]
266; X32-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]
267; X32-SSE2-NEXT: pmuludq %xmm2, %xmm1
268; X32-SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm1[1,3,2,3]
269; X32-SSE2-NEXT: punpckldq {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]
Sanjay Patelc71adc82018-07-16 22:59:31 +0000270; X32-SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
Simon Pilgrimb2082552018-12-20 14:56:44 +0000271; X32-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
272; X32-SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
273; X32-SSE2-NEXT: por %xmm3, %xmm0
Sanjay Patelc71adc82018-07-16 22:59:31 +0000274; X32-SSE2-NEXT: retl
275;
276; X64-AVX2-LABEL: rotr_v4i32:
277; X64-AVX2: # %bb.0:
Simon Pilgrimb2082552018-12-20 14:56:44 +0000278; X64-AVX2-NEXT: vpxor %xmm2, %xmm2, %xmm2
279; X64-AVX2-NEXT: vpsubd %xmm1, %xmm2, %xmm1
Sanjay Patelc71adc82018-07-16 22:59:31 +0000280; X64-AVX2-NEXT: vpbroadcastd {{.*#+}} xmm2 = [31,31,31,31]
Sanjay Patelc71adc82018-07-16 22:59:31 +0000281; X64-AVX2-NEXT: vpand %xmm2, %xmm1, %xmm1
Simon Pilgrimb2082552018-12-20 14:56:44 +0000282; X64-AVX2-NEXT: vpsllvd %xmm1, %xmm0, %xmm2
283; X64-AVX2-NEXT: vpbroadcastd {{.*#+}} xmm3 = [32,32,32,32]
284; X64-AVX2-NEXT: vpsubd %xmm1, %xmm3, %xmm1
285; X64-AVX2-NEXT: vpsrlvd %xmm1, %xmm0, %xmm0
286; X64-AVX2-NEXT: vpor %xmm0, %xmm2, %xmm0
Sanjay Patelc71adc82018-07-16 22:59:31 +0000287; X64-AVX2-NEXT: retq
288 %f = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> %z)
289 ret <4 x i32> %f
290}
291
292; Vector rotate by constant splat amount.
293
294define <4 x i32> @rotr_v4i32_const_shift(<4 x i32> %x) nounwind {
295; X32-SSE2-LABEL: rotr_v4i32_const_shift:
296; X32-SSE2: # %bb.0:
297; X32-SSE2-NEXT: movdqa %xmm0, %xmm1
298; X32-SSE2-NEXT: psrld $3, %xmm1
299; X32-SSE2-NEXT: pslld $29, %xmm0
300; X32-SSE2-NEXT: por %xmm1, %xmm0
301; X32-SSE2-NEXT: retl
302;
303; X64-AVX2-LABEL: rotr_v4i32_const_shift:
304; X64-AVX2: # %bb.0:
305; X64-AVX2-NEXT: vpsrld $3, %xmm0, %xmm1
306; X64-AVX2-NEXT: vpslld $29, %xmm0, %xmm0
307; X64-AVX2-NEXT: vpor %xmm1, %xmm0, %xmm0
308; X64-AVX2-NEXT: retq
309 %f = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> <i32 3, i32 3, i32 3, i32 3>)
310 ret <4 x i32> %f
311}
312
313define i32 @rotl_i32_shift_by_bitwidth(i32 %x) nounwind {
314; X32-SSE2-LABEL: rotl_i32_shift_by_bitwidth:
315; X32-SSE2: # %bb.0:
316; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax
317; X32-SSE2-NEXT: retl
318;
319; X64-AVX2-LABEL: rotl_i32_shift_by_bitwidth:
320; X64-AVX2: # %bb.0:
321; X64-AVX2-NEXT: movl %edi, %eax
322; X64-AVX2-NEXT: retq
323 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 32)
324 ret i32 %f
325}
326
327define i32 @rotr_i32_shift_by_bitwidth(i32 %x) nounwind {
328; X32-SSE2-LABEL: rotr_i32_shift_by_bitwidth:
329; X32-SSE2: # %bb.0:
330; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax
331; X32-SSE2-NEXT: retl
332;
333; X64-AVX2-LABEL: rotr_i32_shift_by_bitwidth:
334; X64-AVX2: # %bb.0:
335; X64-AVX2-NEXT: movl %edi, %eax
336; X64-AVX2-NEXT: retq
337 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 32)
338 ret i32 %f
339}
340
341define <4 x i32> @rotl_v4i32_shift_by_bitwidth(<4 x i32> %x) nounwind {
342; ANY-LABEL: rotl_v4i32_shift_by_bitwidth:
343; ANY: # %bb.0:
344; ANY-NEXT: ret{{[l|q]}}
345 %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> <i32 32, i32 32, i32 32, i32 32>)
346 ret <4 x i32> %f
347}
348
349define <4 x i32> @rotr_v4i32_shift_by_bitwidth(<4 x i32> %x) nounwind {
350; ANY-LABEL: rotr_v4i32_shift_by_bitwidth:
351; ANY: # %bb.0:
352; ANY-NEXT: ret{{[l|q]}}
353 %f = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> <i32 32, i32 32, i32 32, i32 32>)
354 ret <4 x i32> %f
355}
356
Sanjay Pateld5ae1832018-08-01 17:18:50 +0000357; Non power-of-2 types can't use the negated shift amount to avoid a select.
Sanjay Patel6d302c92018-08-01 16:59:54 +0000358
359declare i7 @llvm.fshl.i7(i7, i7, i7)
360declare i7 @llvm.fshr.i7(i7, i7, i7)
361
362; extract(concat(0b1110000, 0b1110000) << 9) = 0b1000011
363; Try an oversized shift to test modulo functionality.
364
365define i7 @fshl_i7() {
366; ANY-LABEL: fshl_i7:
367; ANY: # %bb.0:
Sanjay Patel8aac22e2018-08-01 17:17:08 +0000368; ANY-NEXT: movb $67, %al
Sanjay Patel6d302c92018-08-01 16:59:54 +0000369; ANY-NEXT: ret{{[l|q]}}
370 %f = call i7 @llvm.fshl.i7(i7 112, i7 112, i7 9)
371 ret i7 %f
372}
373
374; extract(concat(0b1110001, 0b1110001) >> 16) = 0b0111100
375; Try an oversized shift to test modulo functionality.
376
377define i7 @fshr_i7() {
378; ANY-LABEL: fshr_i7:
379; ANY: # %bb.0:
Sanjay Patel8aac22e2018-08-01 17:17:08 +0000380; ANY-NEXT: movb $60, %al
Sanjay Patel6d302c92018-08-01 16:59:54 +0000381; ANY-NEXT: ret{{[l|q]}}
382 %f = call i7 @llvm.fshr.i7(i7 113, i7 113, i7 16)
383 ret i7 %f
384}
385