1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-- -mcpu=corei7 | FileCheck %s --check-prefix=ALL --check-prefix=X64
3; RUN: llc < %s -mtriple=x86_64-- -mcpu=corei7-avx | FileCheck %s --check-prefix=ALL --check-prefix=SHLD
4; RUN: llc < %s -mtriple=x86_64-- -mcpu=core-avx2 | FileCheck %s --check-prefix=ALL --check-prefix=BMI2
5
6define i64 @foo(i64 %x, i64 %y, i64 %z) nounwind readnone {
7; ALL-LABEL: foo:
8; ALL:       # %bb.0: # %entry
9; ALL-NEXT:    movq %rdx, %rcx
10; ALL-NEXT:    movq %rdi, %rax
11; ALL-NEXT:    # kill: def $cl killed $cl killed $rcx
12; ALL-NEXT:    rolq %cl, %rax
13; ALL-NEXT:    retq
14entry:
15	%0 = shl i64 %x, %z
16	%1 = sub i64 64, %z
17	%2 = lshr i64 %x, %1
18	%3 = or i64 %2, %0
19	ret i64 %3
20}
21
22define i64 @bar(i64 %x, i64 %y, i64 %z) nounwind readnone {
23; ALL-LABEL: bar:
24; ALL:       # %bb.0: # %entry
25; ALL-NEXT:    movq %rdx, %rcx
26; ALL-NEXT:    movq %rsi, %rax
27; ALL-NEXT:    # kill: def $cl killed $cl killed $rcx
28; ALL-NEXT:    shldq %cl, %rdi, %rax
29; ALL-NEXT:    retq
30entry:
31	%0 = shl i64 %y, %z
32	%1 = sub i64 64, %z
33	%2 = lshr i64 %x, %1
34	%3 = or i64 %2, %0
35	ret i64 %3
36}
37
38define i64 @un(i64 %x, i64 %y, i64 %z) nounwind readnone {
39; ALL-LABEL: un:
40; ALL:       # %bb.0: # %entry
41; ALL-NEXT:    movq %rdx, %rcx
42; ALL-NEXT:    movq %rdi, %rax
43; ALL-NEXT:    # kill: def $cl killed $cl killed $rcx
44; ALL-NEXT:    rorq %cl, %rax
45; ALL-NEXT:    retq
46entry:
47	%0 = lshr i64 %x, %z
48	%1 = sub i64 64, %z
49	%2 = shl i64 %x, %1
50	%3 = or i64 %2, %0
51	ret i64 %3
52}
53
54define i64 @bu(i64 %x, i64 %y, i64 %z) nounwind readnone {
55; ALL-LABEL: bu:
56; ALL:       # %bb.0: # %entry
57; ALL-NEXT:    movq %rdx, %rcx
58; ALL-NEXT:    movq %rsi, %rax
59; ALL-NEXT:    # kill: def $cl killed $cl killed $rcx
60; ALL-NEXT:    shrdq %cl, %rdi, %rax
61; ALL-NEXT:    retq
62entry:
63	%0 = lshr i64 %y, %z
64	%1 = sub i64 64, %z
65	%2 = shl i64 %x, %1
66	%3 = or i64 %2, %0
67	ret i64 %3
68}
69
70define i64 @xfoo(i64 %x, i64 %y, i64 %z) nounwind readnone {
71; X64-LABEL: xfoo:
72; X64:       # %bb.0: # %entry
73; X64-NEXT:    movq %rdi, %rax
74; X64-NEXT:    rolq $7, %rax
75; X64-NEXT:    retq
76;
77; SHLD-LABEL: xfoo:
78; SHLD:       # %bb.0: # %entry
79; SHLD-NEXT:    movq %rdi, %rax
80; SHLD-NEXT:    shldq $7, %rax, %rax
81; SHLD-NEXT:    retq
82;
83; BMI2-LABEL: xfoo:
84; BMI2:       # %bb.0: # %entry
85; BMI2-NEXT:    rorxq $57, %rdi, %rax
86; BMI2-NEXT:    retq
87entry:
88	%0 = lshr i64 %x, 57
89	%1 = shl i64 %x, 7
90	%2 = or i64 %0, %1
91	ret i64 %2
92}
93
94define i64 @xfoop(i64* %p) nounwind readnone {
95; X64-LABEL: xfoop:
96; X64:       # %bb.0: # %entry
97; X64-NEXT:    movq (%rdi), %rax
98; X64-NEXT:    rolq $7, %rax
99; X64-NEXT:    retq
100;
101; SHLD-LABEL: xfoop:
102; SHLD:       # %bb.0: # %entry
103; SHLD-NEXT:    movq (%rdi), %rax
104; SHLD-NEXT:    shldq $7, %rax, %rax
105; SHLD-NEXT:    retq
106;
107; BMI2-LABEL: xfoop:
108; BMI2:       # %bb.0: # %entry
109; BMI2-NEXT:    rorxq $57, (%rdi), %rax
110; BMI2-NEXT:    retq
111entry:
112	%x = load i64, i64* %p
113	%a = lshr i64 %x, 57
114	%b = shl i64 %x, 7
115	%c = or i64 %a, %b
116	ret i64 %c
117}
118
119define i64 @xbar(i64 %x, i64 %y, i64 %z) nounwind readnone {
120; ALL-LABEL: xbar:
121; ALL:       # %bb.0: # %entry
122; ALL-NEXT:    movq %rdi, %rax
123; ALL-NEXT:    shrdq $57, %rsi, %rax
124; ALL-NEXT:    retq
125entry:
126	%0 = shl i64 %y, 7
127	%1 = lshr i64 %x, 57
128	%2 = or i64 %0, %1
129	ret i64 %2
130}
131
132define i64 @xun(i64 %x, i64 %y, i64 %z) nounwind readnone {
133; X64-LABEL: xun:
134; X64:       # %bb.0: # %entry
135; X64-NEXT:    movq %rdi, %rax
136; X64-NEXT:    rolq $57, %rax
137; X64-NEXT:    retq
138;
139; SHLD-LABEL: xun:
140; SHLD:       # %bb.0: # %entry
141; SHLD-NEXT:    movq %rdi, %rax
142; SHLD-NEXT:    shldq $57, %rax, %rax
143; SHLD-NEXT:    retq
144;
145; BMI2-LABEL: xun:
146; BMI2:       # %bb.0: # %entry
147; BMI2-NEXT:    rorxq $7, %rdi, %rax
148; BMI2-NEXT:    retq
149entry:
150	%0 = lshr i64 %x, 7
151	%1 = shl i64 %x, 57
152	%2 = or i64 %0, %1
153	ret i64 %2
154}
155
156define i64 @xunp(i64* %p) nounwind readnone {
157; X64-LABEL: xunp:
158; X64:       # %bb.0: # %entry
159; X64-NEXT:    movq (%rdi), %rax
160; X64-NEXT:    rolq $57, %rax
161; X64-NEXT:    retq
162;
163; SHLD-LABEL: xunp:
164; SHLD:       # %bb.0: # %entry
165; SHLD-NEXT:    movq (%rdi), %rax
166; SHLD-NEXT:    shldq $57, %rax, %rax
167; SHLD-NEXT:    retq
168;
169; BMI2-LABEL: xunp:
170; BMI2:       # %bb.0: # %entry
171; BMI2-NEXT:    rorxq $7, (%rdi), %rax
172; BMI2-NEXT:    retq
173entry:
174	%x = load i64, i64* %p
175	%a = lshr i64 %x, 7
176	%b = shl i64 %x, 57
177	%c = or i64 %a, %b
178	ret i64 %c
179}
180
181define i64 @xbu(i64 %x, i64 %y, i64 %z) nounwind readnone {
182; ALL-LABEL: xbu:
183; ALL:       # %bb.0: # %entry
184; ALL-NEXT:    movq %rdi, %rax
185; ALL-NEXT:    shldq $57, %rsi, %rax
186; ALL-NEXT:    retq
187entry:
188	%0 = lshr i64 %y, 7
189	%1 = shl i64 %x, 57
190	%2 = or i64 %0, %1
191	ret i64 %2
192}
193
194define i64 @fshl(i64 %x) nounwind {
195; X64-LABEL: fshl:
196; X64:       # %bb.0:
197; X64-NEXT:    movq %rdi, %rax
198; X64-NEXT:    rolq $7, %rax
199; X64-NEXT:    retq
200;
201; SHLD-LABEL: fshl:
202; SHLD:       # %bb.0:
203; SHLD-NEXT:    movq %rdi, %rax
204; SHLD-NEXT:    shldq $7, %rax, %rax
205; SHLD-NEXT:    retq
206;
207; BMI2-LABEL: fshl:
208; BMI2:       # %bb.0:
209; BMI2-NEXT:    rorxq $57, %rdi, %rax
210; BMI2-NEXT:    retq
211  %f = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 7)
212  ret i64 %f
213}
214declare i64 @llvm.fshl.i64(i64, i64, i64)
215
216define i64 @fshl1(i64 %x) nounwind {
217; X64-LABEL: fshl1:
218; X64:       # %bb.0:
219; X64-NEXT:    movq %rdi, %rax
220; X64-NEXT:    rolq %rax
221; X64-NEXT:    retq
222;
223; SHLD-LABEL: fshl1:
224; SHLD:       # %bb.0:
225; SHLD-NEXT:    movq %rdi, %rax
226; SHLD-NEXT:    shldq $1, %rax, %rax
227; SHLD-NEXT:    retq
228;
229; BMI2-LABEL: fshl1:
230; BMI2:       # %bb.0:
231; BMI2-NEXT:    rorxq $63, %rdi, %rax
232; BMI2-NEXT:    retq
233  %f = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 1)
234  ret i64 %f
235}
236
237define i64 @fshl63(i64 %x) nounwind {
238; X64-LABEL: fshl63:
239; X64:       # %bb.0:
240; X64-NEXT:    movq %rdi, %rax
241; X64-NEXT:    rorq %rax
242; X64-NEXT:    retq
243;
244; SHLD-LABEL: fshl63:
245; SHLD:       # %bb.0:
246; SHLD-NEXT:    movq %rdi, %rax
247; SHLD-NEXT:    shldq $63, %rax, %rax
248; SHLD-NEXT:    retq
249;
250; BMI2-LABEL: fshl63:
251; BMI2:       # %bb.0:
252; BMI2-NEXT:    rorxq $1, %rdi, %rax
253; BMI2-NEXT:    retq
254  %f = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 63)
255  ret i64 %f
256}
257
258define i64 @fshl_load(i64* %p) nounwind {
259; X64-LABEL: fshl_load:
260; X64:       # %bb.0:
261; X64-NEXT:    movq (%rdi), %rax
262; X64-NEXT:    rolq $7, %rax
263; X64-NEXT:    retq
264;
265; SHLD-LABEL: fshl_load:
266; SHLD:       # %bb.0:
267; SHLD-NEXT:    movq (%rdi), %rax
268; SHLD-NEXT:    shldq $7, %rax, %rax
269; SHLD-NEXT:    retq
270;
271; BMI2-LABEL: fshl_load:
272; BMI2:       # %bb.0:
273; BMI2-NEXT:    rorxq $57, (%rdi), %rax
274; BMI2-NEXT:    retq
275  %x = load i64, i64* %p
276  %f = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 7)
277  ret i64 %f
278}
279
280define i64 @fshr(i64 %x) nounwind {
281; X64-LABEL: fshr:
282; X64:       # %bb.0:
283; X64-NEXT:    movq %rdi, %rax
284; X64-NEXT:    rorq $7, %rax
285; X64-NEXT:    retq
286;
287; SHLD-LABEL: fshr:
288; SHLD:       # %bb.0:
289; SHLD-NEXT:    movq %rdi, %rax
290; SHLD-NEXT:    shrdq $7, %rax, %rax
291; SHLD-NEXT:    retq
292;
293; BMI2-LABEL: fshr:
294; BMI2:       # %bb.0:
295; BMI2-NEXT:    rorxq $7, %rdi, %rax
296; BMI2-NEXT:    retq
297  %f = call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 7)
298  ret i64 %f
299}
300declare i64 @llvm.fshr.i64(i64, i64, i64)
301
302define i64 @fshr1(i64 %x) nounwind {
303; X64-LABEL: fshr1:
304; X64:       # %bb.0:
305; X64-NEXT:    movq %rdi, %rax
306; X64-NEXT:    rorq %rax
307; X64-NEXT:    retq
308;
309; SHLD-LABEL: fshr1:
310; SHLD:       # %bb.0:
311; SHLD-NEXT:    movq %rdi, %rax
312; SHLD-NEXT:    shrdq $1, %rax, %rax
313; SHLD-NEXT:    retq
314;
315; BMI2-LABEL: fshr1:
316; BMI2:       # %bb.0:
317; BMI2-NEXT:    rorxq $1, %rdi, %rax
318; BMI2-NEXT:    retq
319  %f = call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 1)
320  ret i64 %f
321}
322
323define i64 @fshr63(i64 %x) nounwind {
324; X64-LABEL: fshr63:
325; X64:       # %bb.0:
326; X64-NEXT:    movq %rdi, %rax
327; X64-NEXT:    rolq %rax
328; X64-NEXT:    retq
329;
330; SHLD-LABEL: fshr63:
331; SHLD:       # %bb.0:
332; SHLD-NEXT:    movq %rdi, %rax
333; SHLD-NEXT:    shrdq $63, %rax, %rax
334; SHLD-NEXT:    retq
335;
336; BMI2-LABEL: fshr63:
337; BMI2:       # %bb.0:
338; BMI2-NEXT:    rorxq $63, %rdi, %rax
339; BMI2-NEXT:    retq
340  %f = call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 63)
341  ret i64 %f
342}
343
344define i64 @fshr_load(i64* %p) nounwind {
345; X64-LABEL: fshr_load:
346; X64:       # %bb.0:
347; X64-NEXT:    movq (%rdi), %rax
348; X64-NEXT:    rorq $7, %rax
349; X64-NEXT:    retq
350;
351; SHLD-LABEL: fshr_load:
352; SHLD:       # %bb.0:
353; SHLD-NEXT:    movq (%rdi), %rax
354; SHLD-NEXT:    shrdq $7, %rax, %rax
355; SHLD-NEXT:    retq
356;
357; BMI2-LABEL: fshr_load:
358; BMI2:       # %bb.0:
359; BMI2-NEXT:    rorxq $7, (%rdi), %rax
360; BMI2-NEXT:    retq
361  %x = load i64, i64* %p
362  %f = call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 7)
363  ret i64 %f
364}
365