1; 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; General case - all operands can be variables
18
19define i32 @fshl_i32(i32 %x, i32 %y, i32 %z) nounwind {
20; X32-SSE2-LABEL: fshl_i32:
21; X32-SSE2:       # %bb.0:
22; X32-SSE2-NEXT:    movb {{[0-9]+}}(%esp), %cl
23; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %edx
24; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
25; X32-SSE2-NEXT:    shldl %cl, %edx, %eax
26; X32-SSE2-NEXT:    retl
27;
28; X64-AVX2-LABEL: fshl_i32:
29; X64-AVX2:       # %bb.0:
30; X64-AVX2-NEXT:    movl %edx, %ecx
31; X64-AVX2-NEXT:    movl %edi, %eax
32; X64-AVX2-NEXT:    # kill: def $cl killed $cl killed $ecx
33; X64-AVX2-NEXT:    shldl %cl, %esi, %eax
34; X64-AVX2-NEXT:    retq
35  %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %z)
36  ret i32 %f
37}
38
39; Verify that weird types are minimally supported.
40declare i37 @llvm.fshl.i37(i37, i37, i37)
41define i37 @fshl_i37(i37 %x, i37 %y, i37 %z) nounwind {
42; X32-SSE2-LABEL: fshl_i37:
43; X32-SSE2:       # %bb.0:
44; X32-SSE2-NEXT:    pushl %ebp
45; X32-SSE2-NEXT:    pushl %ebx
46; X32-SSE2-NEXT:    pushl %edi
47; X32-SSE2-NEXT:    pushl %esi
48; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %esi
49; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ebx
50; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %edi
51; X32-SSE2-NEXT:    shldl $27, %ebx, %edi
52; X32-SSE2-NEXT:    shll $27, %ebx
53; X32-SSE2-NEXT:    shrdl $1, %edi, %ebx
54; X32-SSE2-NEXT:    shrl %edi
55; X32-SSE2-NEXT:    pushl $0
56; X32-SSE2-NEXT:    pushl $37
57; X32-SSE2-NEXT:    pushl {{[0-9]+}}(%esp)
58; X32-SSE2-NEXT:    pushl {{[0-9]+}}(%esp)
59; X32-SSE2-NEXT:    calll __umoddi3
60; X32-SSE2-NEXT:    addl $16, %esp
61; X32-SSE2-NEXT:    movl %eax, %edx
62; X32-SSE2-NEXT:    movl %edx, %ecx
63; X32-SSE2-NEXT:    notb %cl
64; X32-SSE2-NEXT:    shrdl %cl, %edi, %ebx
65; X32-SSE2-NEXT:    shrl %cl, %edi
66; X32-SSE2-NEXT:    xorl %eax, %eax
67; X32-SSE2-NEXT:    testb $32, %cl
68; X32-SSE2-NEXT:    cmovnel %edi, %ebx
69; X32-SSE2-NEXT:    cmovnel %eax, %edi
70; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
71; X32-SSE2-NEXT:    movl %edx, %ecx
72; X32-SSE2-NEXT:    shll %cl, %eax
73; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ebp
74; X32-SSE2-NEXT:    shldl %cl, %ebp, %esi
75; X32-SSE2-NEXT:    testb $32, %dl
76; X32-SSE2-NEXT:    cmovnel %eax, %esi
77; X32-SSE2-NEXT:    movl $0, %ecx
78; X32-SSE2-NEXT:    cmovnel %ecx, %eax
79; X32-SSE2-NEXT:    orl %ebx, %eax
80; X32-SSE2-NEXT:    orl %edi, %esi
81; X32-SSE2-NEXT:    movl %esi, %edx
82; X32-SSE2-NEXT:    popl %esi
83; X32-SSE2-NEXT:    popl %edi
84; X32-SSE2-NEXT:    popl %ebx
85; X32-SSE2-NEXT:    popl %ebp
86; X32-SSE2-NEXT:    retl
87;
88; X64-AVX2-LABEL: fshl_i37:
89; X64-AVX2:       # %bb.0:
90; X64-AVX2-NEXT:    movq %rdx, %rcx
91; X64-AVX2-NEXT:    movabsq $-2492803253203993461, %rdx # imm = 0xDD67C8A60DD67C8B
92; X64-AVX2-NEXT:    movq %rcx, %rax
93; X64-AVX2-NEXT:    mulq %rdx
94; X64-AVX2-NEXT:    shrq $5, %rdx
95; X64-AVX2-NEXT:    leal (%rdx,%rdx,8), %eax
96; X64-AVX2-NEXT:    leal (%rdx,%rax,4), %eax
97; X64-AVX2-NEXT:    subl %eax, %ecx
98; X64-AVX2-NEXT:    shlq $27, %rsi
99; X64-AVX2-NEXT:    # kill: def $cl killed $cl killed $rcx
100; X64-AVX2-NEXT:    shldq %cl, %rsi, %rdi
101; X64-AVX2-NEXT:    movq %rdi, %rax
102; X64-AVX2-NEXT:    retq
103  %f = call i37 @llvm.fshl.i37(i37 %x, i37 %y, i37 %z)
104  ret i37 %f
105}
106
107; extract(concat(0b1110000, 0b1111111) << 2) = 0b1000011
108
109declare i7 @llvm.fshl.i7(i7, i7, i7)
110define i7 @fshl_i7_const_fold() {
111; ANY-LABEL: fshl_i7_const_fold:
112; ANY:       # %bb.0:
113; ANY-NEXT:    movb $67, %al
114; ANY-NEXT:    ret{{[l|q]}}
115  %f = call i7 @llvm.fshl.i7(i7 112, i7 127, i7 2)
116  ret i7 %f
117}
118
119; With constant shift amount, this is 'shld' with constant operand.
120
121define i32 @fshl_i32_const_shift(i32 %x, i32 %y) nounwind {
122; X32-SSE2-LABEL: fshl_i32_const_shift:
123; X32-SSE2:       # %bb.0:
124; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
125; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
126; X32-SSE2-NEXT:    shldl $9, %ecx, %eax
127; X32-SSE2-NEXT:    retl
128;
129; X64-AVX2-LABEL: fshl_i32_const_shift:
130; X64-AVX2:       # %bb.0:
131; X64-AVX2-NEXT:    movl %edi, %eax
132; X64-AVX2-NEXT:    shldl $9, %esi, %eax
133; X64-AVX2-NEXT:    retq
134  %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 9)
135  ret i32 %f
136}
137
138; Check modulo math on shift amount.
139
140define i32 @fshl_i32_const_overshift(i32 %x, i32 %y) nounwind {
141; X32-SSE2-LABEL: fshl_i32_const_overshift:
142; X32-SSE2:       # %bb.0:
143; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
144; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
145; X32-SSE2-NEXT:    shldl $9, %ecx, %eax
146; X32-SSE2-NEXT:    retl
147;
148; X64-AVX2-LABEL: fshl_i32_const_overshift:
149; X64-AVX2:       # %bb.0:
150; X64-AVX2-NEXT:    movl %edi, %eax
151; X64-AVX2-NEXT:    shldl $9, %esi, %eax
152; X64-AVX2-NEXT:    retq
153  %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 41)
154  ret i32 %f
155}
156
157; 64-bit should also work.
158
159define i64 @fshl_i64_const_overshift(i64 %x, i64 %y) nounwind {
160; X32-SSE2-LABEL: fshl_i64_const_overshift:
161; X32-SSE2:       # %bb.0:
162; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
163; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
164; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %edx
165; X32-SSE2-NEXT:    shldl $9, %ecx, %edx
166; X32-SSE2-NEXT:    shrdl $23, %ecx, %eax
167; X32-SSE2-NEXT:    retl
168;
169; X64-AVX2-LABEL: fshl_i64_const_overshift:
170; X64-AVX2:       # %bb.0:
171; X64-AVX2-NEXT:    movq %rdi, %rax
172; X64-AVX2-NEXT:    shldq $41, %rsi, %rax
173; X64-AVX2-NEXT:    retq
174  %f = call i64 @llvm.fshl.i64(i64 %x, i64 %y, i64 105)
175  ret i64 %f
176}
177
178; This should work without any node-specific logic.
179
180define i8 @fshl_i8_const_fold() nounwind {
181; ANY-LABEL: fshl_i8_const_fold:
182; ANY:       # %bb.0:
183; ANY-NEXT:    movb $-128, %al
184; ANY-NEXT:    ret{{[l|q]}}
185  %f = call i8 @llvm.fshl.i8(i8 255, i8 0, i8 7)
186  ret i8 %f
187}
188
189; Repeat everything for funnel shift right.
190
191; General case - all operands can be variables
192
193define i32 @fshr_i32(i32 %x, i32 %y, i32 %z) nounwind {
194; X32-SSE2-LABEL: fshr_i32:
195; X32-SSE2:       # %bb.0:
196; X32-SSE2-NEXT:    movb {{[0-9]+}}(%esp), %cl
197; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %edx
198; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
199; X32-SSE2-NEXT:    shrdl %cl, %edx, %eax
200; X32-SSE2-NEXT:    retl
201;
202; X64-AVX2-LABEL: fshr_i32:
203; X64-AVX2:       # %bb.0:
204; X64-AVX2-NEXT:    movl %edx, %ecx
205; X64-AVX2-NEXT:    movl %esi, %eax
206; X64-AVX2-NEXT:    # kill: def $cl killed $cl killed $ecx
207; X64-AVX2-NEXT:    shrdl %cl, %edi, %eax
208; X64-AVX2-NEXT:    retq
209  %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %z)
210  ret i32 %f
211}
212
213; Verify that weird types are minimally supported.
214declare i37 @llvm.fshr.i37(i37, i37, i37)
215define i37 @fshr_i37(i37 %x, i37 %y, i37 %z) nounwind {
216; X32-SSE2-LABEL: fshr_i37:
217; X32-SSE2:       # %bb.0:
218; X32-SSE2-NEXT:    pushl %ebp
219; X32-SSE2-NEXT:    pushl %ebx
220; X32-SSE2-NEXT:    pushl %edi
221; X32-SSE2-NEXT:    pushl %esi
222; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ebp
223; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ebx
224; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %edi
225; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %esi
226; X32-SSE2-NEXT:    shldl $1, %edi, %esi
227; X32-SSE2-NEXT:    addl %edi, %edi
228; X32-SSE2-NEXT:    pushl $0
229; X32-SSE2-NEXT:    pushl $37
230; X32-SSE2-NEXT:    pushl {{[0-9]+}}(%esp)
231; X32-SSE2-NEXT:    pushl {{[0-9]+}}(%esp)
232; X32-SSE2-NEXT:    calll __umoddi3
233; X32-SSE2-NEXT:    addl $16, %esp
234; X32-SSE2-NEXT:    addb $27, %al
235; X32-SSE2-NEXT:    movl %eax, %edx
236; X32-SSE2-NEXT:    notb %dl
237; X32-SSE2-NEXT:    movl %edx, %ecx
238; X32-SSE2-NEXT:    shldl %cl, %edi, %esi
239; X32-SSE2-NEXT:    shldl $27, %ebp, %ebx
240; X32-SSE2-NEXT:    shll $27, %ebp
241; X32-SSE2-NEXT:    movl %eax, %ecx
242; X32-SSE2-NEXT:    shrdl %cl, %ebx, %ebp
243; X32-SSE2-NEXT:    shrl %cl, %ebx
244; X32-SSE2-NEXT:    xorl %ecx, %ecx
245; X32-SSE2-NEXT:    testb $32, %al
246; X32-SSE2-NEXT:    cmovnel %ebx, %ebp
247; X32-SSE2-NEXT:    cmovnel %ecx, %ebx
248; X32-SSE2-NEXT:    xorl %eax, %eax
249; X32-SSE2-NEXT:    movl %edx, %ecx
250; X32-SSE2-NEXT:    shll %cl, %edi
251; X32-SSE2-NEXT:    testb $32, %dl
252; X32-SSE2-NEXT:    cmovnel %edi, %esi
253; X32-SSE2-NEXT:    cmovnel %eax, %edi
254; X32-SSE2-NEXT:    orl %ebp, %edi
255; X32-SSE2-NEXT:    orl %ebx, %esi
256; X32-SSE2-NEXT:    movl %edi, %eax
257; X32-SSE2-NEXT:    movl %esi, %edx
258; X32-SSE2-NEXT:    popl %esi
259; X32-SSE2-NEXT:    popl %edi
260; X32-SSE2-NEXT:    popl %ebx
261; X32-SSE2-NEXT:    popl %ebp
262; X32-SSE2-NEXT:    retl
263;
264; X64-AVX2-LABEL: fshr_i37:
265; X64-AVX2:       # %bb.0:
266; X64-AVX2-NEXT:    movq %rdx, %rcx
267; X64-AVX2-NEXT:    movabsq $-2492803253203993461, %rdx # imm = 0xDD67C8A60DD67C8B
268; X64-AVX2-NEXT:    movq %rcx, %rax
269; X64-AVX2-NEXT:    mulq %rdx
270; X64-AVX2-NEXT:    shrq $5, %rdx
271; X64-AVX2-NEXT:    leal (%rdx,%rdx,8), %eax
272; X64-AVX2-NEXT:    leal (%rdx,%rax,4), %eax
273; X64-AVX2-NEXT:    subl %eax, %ecx
274; X64-AVX2-NEXT:    addl $27, %ecx
275; X64-AVX2-NEXT:    shlq $27, %rsi
276; X64-AVX2-NEXT:    # kill: def $cl killed $cl killed $rcx
277; X64-AVX2-NEXT:    shrdq %cl, %rdi, %rsi
278; X64-AVX2-NEXT:    movq %rsi, %rax
279; X64-AVX2-NEXT:    retq
280  %f = call i37 @llvm.fshr.i37(i37 %x, i37 %y, i37 %z)
281  ret i37 %f
282}
283
284; extract(concat(0b1110000, 0b1111111) >> 2) = 0b0011111
285
286declare i7 @llvm.fshr.i7(i7, i7, i7)
287define i7 @fshr_i7_const_fold() nounwind {
288; ANY-LABEL: fshr_i7_const_fold:
289; ANY:       # %bb.0:
290; ANY-NEXT:    movb $31, %al
291; ANY-NEXT:    ret{{[l|q]}}
292  %f = call i7 @llvm.fshr.i7(i7 112, i7 127, i7 2)
293  ret i7 %f
294}
295
296; demanded bits tests
297
298define i32 @fshl_i32_demandedbits(i32 %a0, i32 %a1) nounwind {
299; X32-SSE2-LABEL: fshl_i32_demandedbits:
300; X32-SSE2:       # %bb.0:
301; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
302; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
303; X32-SSE2-NEXT:    shldl $9, %ecx, %eax
304; X32-SSE2-NEXT:    retl
305;
306; X64-AVX2-LABEL: fshl_i32_demandedbits:
307; X64-AVX2:       # %bb.0:
308; X64-AVX2-NEXT:    movl %edi, %eax
309; X64-AVX2-NEXT:    shldl $9, %esi, %eax
310; X64-AVX2-NEXT:    retq
311  %x = or i32 %a0, 2147483648
312  %y = or i32 %a1, 1
313  %res = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 9)
314  ret i32 %res
315}
316
317define i32 @fshr_i32_demandedbits(i32 %a0, i32 %a1) nounwind {
318; X32-SSE2-LABEL: fshr_i32_demandedbits:
319; X32-SSE2:       # %bb.0:
320; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
321; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
322; X32-SSE2-NEXT:    shrdl $9, %ecx, %eax
323; X32-SSE2-NEXT:    retl
324;
325; X64-AVX2-LABEL: fshr_i32_demandedbits:
326; X64-AVX2:       # %bb.0:
327; X64-AVX2-NEXT:    movl %edi, %eax
328; X64-AVX2-NEXT:    shldl $23, %esi, %eax
329; X64-AVX2-NEXT:    retq
330  %x = or i32 %a0, 2147483648
331  %y = or i32 %a1, 1
332  %res = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 9)
333  ret i32 %res
334}
335
336; undef handling
337
338define i32 @fshl_i32_undef0(i32 %a0, i32 %a1) nounwind {
339; X32-SSE2-LABEL: fshl_i32_undef0:
340; X32-SSE2:       # %bb.0:
341; X32-SSE2-NEXT:    movb {{[0-9]+}}(%esp), %cl
342; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
343; X32-SSE2-NEXT:    shldl %cl, %eax, %eax
344; X32-SSE2-NEXT:    retl
345;
346; X64-AVX2-LABEL: fshl_i32_undef0:
347; X64-AVX2:       # %bb.0:
348; X64-AVX2-NEXT:    movl %esi, %ecx
349; X64-AVX2-NEXT:    # kill: def $cl killed $cl killed $ecx
350; X64-AVX2-NEXT:    shldl %cl, %edi, %eax
351; X64-AVX2-NEXT:    retq
352  %res = call i32 @llvm.fshl.i32(i32 undef, i32 %a0, i32 %a1)
353  ret i32 %res
354}
355
356define i32 @fshl_i32_undef0_msk(i32 %a0, i32 %a1) nounwind {
357; X32-SSE2-LABEL: fshl_i32_undef0_msk:
358; X32-SSE2:       # %bb.0:
359; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
360; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
361; X32-SSE2-NEXT:    andl $7, %ecx
362; X32-SSE2-NEXT:    # kill: def $cl killed $cl killed $ecx
363; X32-SSE2-NEXT:    shldl %cl, %eax, %eax
364; X32-SSE2-NEXT:    retl
365;
366; X64-AVX2-LABEL: fshl_i32_undef0_msk:
367; X64-AVX2:       # %bb.0:
368; X64-AVX2-NEXT:    movl %esi, %ecx
369; X64-AVX2-NEXT:    andl $7, %ecx
370; X64-AVX2-NEXT:    # kill: def $cl killed $cl killed $ecx
371; X64-AVX2-NEXT:    shldl %cl, %edi, %eax
372; X64-AVX2-NEXT:    retq
373  %m = and i32 %a1, 7
374  %res = call i32 @llvm.fshl.i32(i32 undef, i32 %a0, i32 %m)
375  ret i32 %res
376}
377
378define i32 @fshl_i32_undef0_cst(i32 %a0) nounwind {
379; X32-SSE2-LABEL: fshl_i32_undef0_cst:
380; X32-SSE2:       # %bb.0:
381; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
382; X32-SSE2-NEXT:    shrl $23, %eax
383; X32-SSE2-NEXT:    retl
384;
385; X64-AVX2-LABEL: fshl_i32_undef0_cst:
386; X64-AVX2:       # %bb.0:
387; X64-AVX2-NEXT:    movl %edi, %eax
388; X64-AVX2-NEXT:    shrl $23, %eax
389; X64-AVX2-NEXT:    retq
390  %res = call i32 @llvm.fshl.i32(i32 undef, i32 %a0, i32 9)
391  ret i32 %res
392}
393
394define i32 @fshl_i32_undef1(i32 %a0, i32 %a1) nounwind {
395; X32-SSE2-LABEL: fshl_i32_undef1:
396; X32-SSE2:       # %bb.0:
397; X32-SSE2-NEXT:    movb {{[0-9]+}}(%esp), %cl
398; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
399; X32-SSE2-NEXT:    shldl %cl, %eax, %eax
400; X32-SSE2-NEXT:    retl
401;
402; X64-AVX2-LABEL: fshl_i32_undef1:
403; X64-AVX2:       # %bb.0:
404; X64-AVX2-NEXT:    movl %esi, %ecx
405; X64-AVX2-NEXT:    movl %edi, %eax
406; X64-AVX2-NEXT:    # kill: def $cl killed $cl killed $ecx
407; X64-AVX2-NEXT:    shldl %cl, %eax, %eax
408; X64-AVX2-NEXT:    retq
409  %res = call i32 @llvm.fshl.i32(i32 %a0, i32 undef, i32 %a1)
410  ret i32 %res
411}
412
413define i32 @fshl_i32_undef1_msk(i32 %a0, i32 %a1) nounwind {
414; X32-SSE2-LABEL: fshl_i32_undef1_msk:
415; X32-SSE2:       # %bb.0:
416; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
417; X32-SSE2-NEXT:    movb {{[0-9]+}}(%esp), %cl
418; X32-SSE2-NEXT:    andb $7, %cl
419; X32-SSE2-NEXT:    shll %cl, %eax
420; X32-SSE2-NEXT:    retl
421;
422; X64-AVX2-LABEL: fshl_i32_undef1_msk:
423; X64-AVX2:       # %bb.0:
424; X64-AVX2-NEXT:    movl %esi, %ecx
425; X64-AVX2-NEXT:    movl %edi, %eax
426; X64-AVX2-NEXT:    andb $7, %cl
427; X64-AVX2-NEXT:    # kill: def $cl killed $cl killed $ecx
428; X64-AVX2-NEXT:    shll %cl, %eax
429; X64-AVX2-NEXT:    retq
430  %m = and i32 %a1, 7
431  %res = call i32 @llvm.fshl.i32(i32 %a0, i32 undef, i32 %m)
432  ret i32 %res
433}
434
435define i32 @fshl_i32_undef1_cst(i32 %a0) nounwind {
436; X32-SSE2-LABEL: fshl_i32_undef1_cst:
437; X32-SSE2:       # %bb.0:
438; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
439; X32-SSE2-NEXT:    shll $9, %eax
440; X32-SSE2-NEXT:    retl
441;
442; X64-AVX2-LABEL: fshl_i32_undef1_cst:
443; X64-AVX2:       # %bb.0:
444; X64-AVX2-NEXT:    movl %edi, %eax
445; X64-AVX2-NEXT:    shll $9, %eax
446; X64-AVX2-NEXT:    retq
447  %res = call i32 @llvm.fshl.i32(i32 %a0, i32 undef, i32 9)
448  ret i32 %res
449}
450
451define i32 @fshl_i32_undef2(i32 %a0, i32 %a1) nounwind {
452; X32-SSE2-LABEL: fshl_i32_undef2:
453; X32-SSE2:       # %bb.0:
454; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
455; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
456; X32-SSE2-NEXT:    shldl %cl, %ecx, %eax
457; X32-SSE2-NEXT:    retl
458;
459; X64-AVX2-LABEL: fshl_i32_undef2:
460; X64-AVX2:       # %bb.0:
461; X64-AVX2-NEXT:    movl %edi, %eax
462; X64-AVX2-NEXT:    shldl %cl, %esi, %eax
463; X64-AVX2-NEXT:    retq
464  %res = call i32 @llvm.fshl.i32(i32 %a0, i32 %a1, i32 undef)
465  ret i32 %res
466}
467
468define i32 @fshr_i32_undef0(i32 %a0, i32 %a1) nounwind {
469; X32-SSE2-LABEL: fshr_i32_undef0:
470; X32-SSE2:       # %bb.0:
471; X32-SSE2-NEXT:    movb {{[0-9]+}}(%esp), %cl
472; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
473; X32-SSE2-NEXT:    shrdl %cl, %eax, %eax
474; X32-SSE2-NEXT:    retl
475;
476; X64-AVX2-LABEL: fshr_i32_undef0:
477; X64-AVX2:       # %bb.0:
478; X64-AVX2-NEXT:    movl %esi, %ecx
479; X64-AVX2-NEXT:    movl %edi, %eax
480; X64-AVX2-NEXT:    # kill: def $cl killed $cl killed $ecx
481; X64-AVX2-NEXT:    shrdl %cl, %eax, %eax
482; X64-AVX2-NEXT:    retq
483  %res = call i32 @llvm.fshr.i32(i32 undef, i32 %a0, i32 %a1)
484  ret i32 %res
485}
486
487define i32 @fshr_i32_undef0_msk(i32 %a0, i32 %a1) nounwind {
488; X32-SSE2-LABEL: fshr_i32_undef0_msk:
489; X32-SSE2:       # %bb.0:
490; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
491; X32-SSE2-NEXT:    movb {{[0-9]+}}(%esp), %cl
492; X32-SSE2-NEXT:    andb $7, %cl
493; X32-SSE2-NEXT:    shrl %cl, %eax
494; X32-SSE2-NEXT:    retl
495;
496; X64-AVX2-LABEL: fshr_i32_undef0_msk:
497; X64-AVX2:       # %bb.0:
498; X64-AVX2-NEXT:    movl %esi, %ecx
499; X64-AVX2-NEXT:    movl %edi, %eax
500; X64-AVX2-NEXT:    andb $7, %cl
501; X64-AVX2-NEXT:    # kill: def $cl killed $cl killed $ecx
502; X64-AVX2-NEXT:    shrl %cl, %eax
503; X64-AVX2-NEXT:    retq
504  %m = and i32 %a1, 7
505  %res = call i32 @llvm.fshr.i32(i32 undef, i32 %a0, i32 %m)
506  ret i32 %res
507}
508
509define i32 @fshr_i32_undef0_cst(i32 %a0) nounwind {
510; X32-SSE2-LABEL: fshr_i32_undef0_cst:
511; X32-SSE2:       # %bb.0:
512; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
513; X32-SSE2-NEXT:    shrl $9, %eax
514; X32-SSE2-NEXT:    retl
515;
516; X64-AVX2-LABEL: fshr_i32_undef0_cst:
517; X64-AVX2:       # %bb.0:
518; X64-AVX2-NEXT:    movl %edi, %eax
519; X64-AVX2-NEXT:    shrl $9, %eax
520; X64-AVX2-NEXT:    retq
521  %res = call i32 @llvm.fshr.i32(i32 undef, i32 %a0, i32 9)
522  ret i32 %res
523}
524
525define i32 @fshr_i32_undef1(i32 %a0, i32 %a1) nounwind {
526; X32-SSE2-LABEL: fshr_i32_undef1:
527; X32-SSE2:       # %bb.0:
528; X32-SSE2-NEXT:    movb {{[0-9]+}}(%esp), %cl
529; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
530; X32-SSE2-NEXT:    shrdl %cl, %eax, %eax
531; X32-SSE2-NEXT:    retl
532;
533; X64-AVX2-LABEL: fshr_i32_undef1:
534; X64-AVX2:       # %bb.0:
535; X64-AVX2-NEXT:    movl %esi, %ecx
536; X64-AVX2-NEXT:    # kill: def $cl killed $cl killed $ecx
537; X64-AVX2-NEXT:    shrdl %cl, %edi, %eax
538; X64-AVX2-NEXT:    retq
539  %res = call i32 @llvm.fshr.i32(i32 %a0, i32 undef, i32 %a1)
540  ret i32 %res
541}
542
543define i32 @fshr_i32_undef1_msk(i32 %a0, i32 %a1) nounwind {
544; X32-SSE2-LABEL: fshr_i32_undef1_msk:
545; X32-SSE2:       # %bb.0:
546; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
547; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
548; X32-SSE2-NEXT:    andl $7, %ecx
549; X32-SSE2-NEXT:    # kill: def $cl killed $cl killed $ecx
550; X32-SSE2-NEXT:    shrdl %cl, %eax, %eax
551; X32-SSE2-NEXT:    retl
552;
553; X64-AVX2-LABEL: fshr_i32_undef1_msk:
554; X64-AVX2:       # %bb.0:
555; X64-AVX2-NEXT:    movl %esi, %ecx
556; X64-AVX2-NEXT:    andl $7, %ecx
557; X64-AVX2-NEXT:    # kill: def $cl killed $cl killed $ecx
558; X64-AVX2-NEXT:    shrdl %cl, %edi, %eax
559; X64-AVX2-NEXT:    retq
560  %m = and i32 %a1, 7
561  %res = call i32 @llvm.fshr.i32(i32 %a0, i32 undef, i32 %m)
562  ret i32 %res
563}
564
565define i32 @fshr_i32_undef1_cst(i32 %a0) nounwind {
566; X32-SSE2-LABEL: fshr_i32_undef1_cst:
567; X32-SSE2:       # %bb.0:
568; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
569; X32-SSE2-NEXT:    shll $23, %eax
570; X32-SSE2-NEXT:    retl
571;
572; X64-AVX2-LABEL: fshr_i32_undef1_cst:
573; X64-AVX2:       # %bb.0:
574; X64-AVX2-NEXT:    movl %edi, %eax
575; X64-AVX2-NEXT:    shll $23, %eax
576; X64-AVX2-NEXT:    retq
577  %res = call i32 @llvm.fshr.i32(i32 %a0, i32 undef, i32 9)
578  ret i32 %res
579}
580
581define i32 @fshr_i32_undef2(i32 %a0, i32 %a1) nounwind {
582; X32-SSE2-LABEL: fshr_i32_undef2:
583; X32-SSE2:       # %bb.0:
584; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
585; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
586; X32-SSE2-NEXT:    shrdl %cl, %ecx, %eax
587; X32-SSE2-NEXT:    retl
588;
589; X64-AVX2-LABEL: fshr_i32_undef2:
590; X64-AVX2:       # %bb.0:
591; X64-AVX2-NEXT:    movl %esi, %eax
592; X64-AVX2-NEXT:    shrdl %cl, %edi, %eax
593; X64-AVX2-NEXT:    retq
594  %res = call i32 @llvm.fshr.i32(i32 %a0, i32 %a1, i32 undef)
595  ret i32 %res
596}
597
598; shift zero args
599
600define i32 @fshl_i32_zero0(i32 %a0, i32 %a1) nounwind {
601; X32-SSE2-LABEL: fshl_i32_zero0:
602; X32-SSE2:       # %bb.0:
603; X32-SSE2-NEXT:    movb {{[0-9]+}}(%esp), %cl
604; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %edx
605; X32-SSE2-NEXT:    xorl %eax, %eax
606; X32-SSE2-NEXT:    shldl %cl, %edx, %eax
607; X32-SSE2-NEXT:    retl
608;
609; X64-AVX2-LABEL: fshl_i32_zero0:
610; X64-AVX2:       # %bb.0:
611; X64-AVX2-NEXT:    movl %esi, %ecx
612; X64-AVX2-NEXT:    xorl %eax, %eax
613; X64-AVX2-NEXT:    # kill: def $cl killed $cl killed $ecx
614; X64-AVX2-NEXT:    shldl %cl, %edi, %eax
615; X64-AVX2-NEXT:    retq
616  %res = call i32 @llvm.fshl.i32(i32 0, i32 %a0, i32 %a1)
617  ret i32 %res
618}
619
620define i32 @fshl_i32_zero0_cst(i32 %a0) nounwind {
621; X32-SSE2-LABEL: fshl_i32_zero0_cst:
622; X32-SSE2:       # %bb.0:
623; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
624; X32-SSE2-NEXT:    shrl $23, %eax
625; X32-SSE2-NEXT:    retl
626;
627; X64-AVX2-LABEL: fshl_i32_zero0_cst:
628; X64-AVX2:       # %bb.0:
629; X64-AVX2-NEXT:    movl %edi, %eax
630; X64-AVX2-NEXT:    shrl $23, %eax
631; X64-AVX2-NEXT:    retq
632  %res = call i32 @llvm.fshl.i32(i32 0, i32 %a0, i32 9)
633  ret i32 %res
634}
635
636define i32 @fshl_i32_zero1(i32 %a0, i32 %a1) nounwind {
637; X32-SSE2-LABEL: fshl_i32_zero1:
638; X32-SSE2:       # %bb.0:
639; X32-SSE2-NEXT:    movb {{[0-9]+}}(%esp), %cl
640; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
641; X32-SSE2-NEXT:    xorl %edx, %edx
642; X32-SSE2-NEXT:    shldl %cl, %edx, %eax
643; X32-SSE2-NEXT:    retl
644;
645; X64-AVX2-LABEL: fshl_i32_zero1:
646; X64-AVX2:       # %bb.0:
647; X64-AVX2-NEXT:    movl %esi, %ecx
648; X64-AVX2-NEXT:    movl %edi, %eax
649; X64-AVX2-NEXT:    xorl %edx, %edx
650; X64-AVX2-NEXT:    # kill: def $cl killed $cl killed $ecx
651; X64-AVX2-NEXT:    shldl %cl, %edx, %eax
652; X64-AVX2-NEXT:    retq
653  %res = call i32 @llvm.fshl.i32(i32 %a0, i32 0, i32 %a1)
654  ret i32 %res
655}
656
657define i32 @fshl_i32_zero1_cst(i32 %a0) nounwind {
658; X32-SSE2-LABEL: fshl_i32_zero1_cst:
659; X32-SSE2:       # %bb.0:
660; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
661; X32-SSE2-NEXT:    shll $9, %eax
662; X32-SSE2-NEXT:    retl
663;
664; X64-AVX2-LABEL: fshl_i32_zero1_cst:
665; X64-AVX2:       # %bb.0:
666; X64-AVX2-NEXT:    movl %edi, %eax
667; X64-AVX2-NEXT:    shll $9, %eax
668; X64-AVX2-NEXT:    retq
669  %res = call i32 @llvm.fshl.i32(i32 %a0, i32 0, i32 9)
670  ret i32 %res
671}
672
673define i32 @fshr_i32_zero0(i32 %a0, i32 %a1) nounwind {
674; X32-SSE2-LABEL: fshr_i32_zero0:
675; X32-SSE2:       # %bb.0:
676; X32-SSE2-NEXT:    movb {{[0-9]+}}(%esp), %cl
677; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
678; X32-SSE2-NEXT:    xorl %edx, %edx
679; X32-SSE2-NEXT:    shrdl %cl, %edx, %eax
680; X32-SSE2-NEXT:    retl
681;
682; X64-AVX2-LABEL: fshr_i32_zero0:
683; X64-AVX2:       # %bb.0:
684; X64-AVX2-NEXT:    movl %esi, %ecx
685; X64-AVX2-NEXT:    movl %edi, %eax
686; X64-AVX2-NEXT:    xorl %edx, %edx
687; X64-AVX2-NEXT:    # kill: def $cl killed $cl killed $ecx
688; X64-AVX2-NEXT:    shrdl %cl, %edx, %eax
689; X64-AVX2-NEXT:    retq
690  %res = call i32 @llvm.fshr.i32(i32 0, i32 %a0, i32 %a1)
691  ret i32 %res
692}
693
694define i32 @fshr_i32_zero0_cst(i32 %a0) nounwind {
695; X32-SSE2-LABEL: fshr_i32_zero0_cst:
696; X32-SSE2:       # %bb.0:
697; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
698; X32-SSE2-NEXT:    shrl $9, %eax
699; X32-SSE2-NEXT:    retl
700;
701; X64-AVX2-LABEL: fshr_i32_zero0_cst:
702; X64-AVX2:       # %bb.0:
703; X64-AVX2-NEXT:    movl %edi, %eax
704; X64-AVX2-NEXT:    shrl $9, %eax
705; X64-AVX2-NEXT:    retq
706  %res = call i32 @llvm.fshr.i32(i32 0, i32 %a0, i32 9)
707  ret i32 %res
708}
709
710define i32 @fshr_i32_zero1(i32 %a0, i32 %a1) nounwind {
711; X32-SSE2-LABEL: fshr_i32_zero1:
712; X32-SSE2:       # %bb.0:
713; X32-SSE2-NEXT:    movb {{[0-9]+}}(%esp), %cl
714; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %edx
715; X32-SSE2-NEXT:    xorl %eax, %eax
716; X32-SSE2-NEXT:    shrdl %cl, %edx, %eax
717; X32-SSE2-NEXT:    retl
718;
719; X64-AVX2-LABEL: fshr_i32_zero1:
720; X64-AVX2:       # %bb.0:
721; X64-AVX2-NEXT:    movl %esi, %ecx
722; X64-AVX2-NEXT:    xorl %eax, %eax
723; X64-AVX2-NEXT:    # kill: def $cl killed $cl killed $ecx
724; X64-AVX2-NEXT:    shrdl %cl, %edi, %eax
725; X64-AVX2-NEXT:    retq
726  %res = call i32 @llvm.fshr.i32(i32 %a0, i32 0, i32 %a1)
727  ret i32 %res
728}
729
730define i32 @fshr_i32_zero1_cst(i32 %a0) nounwind {
731; X32-SSE2-LABEL: fshr_i32_zero1_cst:
732; X32-SSE2:       # %bb.0:
733; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
734; X32-SSE2-NEXT:    shll $23, %eax
735; X32-SSE2-NEXT:    retl
736;
737; X64-AVX2-LABEL: fshr_i32_zero1_cst:
738; X64-AVX2:       # %bb.0:
739; X64-AVX2-NEXT:    movl %edi, %eax
740; X64-AVX2-NEXT:    shll $23, %eax
741; X64-AVX2-NEXT:    retq
742  %res = call i32 @llvm.fshr.i32(i32 %a0, i32 0, i32 9)
743  ret i32 %res
744}
745
746; shift by zero
747
748define i32 @fshl_i32_zero2(i32 %a0, i32 %a1) nounwind {
749; X32-SSE2-LABEL: fshl_i32_zero2:
750; X32-SSE2:       # %bb.0:
751; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
752; X32-SSE2-NEXT:    retl
753;
754; X64-AVX2-LABEL: fshl_i32_zero2:
755; X64-AVX2:       # %bb.0:
756; X64-AVX2-NEXT:    movl %edi, %eax
757; X64-AVX2-NEXT:    retq
758  %res = call i32 @llvm.fshl.i32(i32 %a0, i32 %a1, i32 0)
759  ret i32 %res
760}
761
762define i32 @fshr_i32_zero2(i32 %a0, i32 %a1) nounwind {
763; X32-SSE2-LABEL: fshr_i32_zero2:
764; X32-SSE2:       # %bb.0:
765; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
766; X32-SSE2-NEXT:    retl
767;
768; X64-AVX2-LABEL: fshr_i32_zero2:
769; X64-AVX2:       # %bb.0:
770; X64-AVX2-NEXT:    movl %esi, %eax
771; X64-AVX2-NEXT:    retq
772  %res = call i32 @llvm.fshr.i32(i32 %a0, i32 %a1, i32 0)
773  ret i32 %res
774}
775
776; With constant shift amount, this is 'shrd' or 'shld'.
777
778define i32 @fshr_i32_const_shift(i32 %x, i32 %y) nounwind {
779; X32-SSE2-LABEL: fshr_i32_const_shift:
780; X32-SSE2:       # %bb.0:
781; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
782; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
783; X32-SSE2-NEXT:    shrdl $9, %ecx, %eax
784; X32-SSE2-NEXT:    retl
785;
786; X64-AVX2-LABEL: fshr_i32_const_shift:
787; X64-AVX2:       # %bb.0:
788; X64-AVX2-NEXT:    movl %edi, %eax
789; X64-AVX2-NEXT:    shldl $23, %esi, %eax
790; X64-AVX2-NEXT:    retq
791  %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 9)
792  ret i32 %f
793}
794
795; Check modulo math on shift amount. 41-32=9, but right-shift may became left, so 32-9=23.
796
797define i32 @fshr_i32_const_overshift(i32 %x, i32 %y) nounwind {
798; X32-SSE2-LABEL: fshr_i32_const_overshift:
799; X32-SSE2:       # %bb.0:
800; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
801; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
802; X32-SSE2-NEXT:    shrdl $9, %ecx, %eax
803; X32-SSE2-NEXT:    retl
804;
805; X64-AVX2-LABEL: fshr_i32_const_overshift:
806; X64-AVX2:       # %bb.0:
807; X64-AVX2-NEXT:    movl %edi, %eax
808; X64-AVX2-NEXT:    shldl $23, %esi, %eax
809; X64-AVX2-NEXT:    retq
810  %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 41)
811  ret i32 %f
812}
813
814; 64-bit should also work. 105-64 = 41, but right-shift became left, so 64-41=23.
815
816define i64 @fshr_i64_const_overshift(i64 %x, i64 %y) nounwind {
817; X32-SSE2-LABEL: fshr_i64_const_overshift:
818; X32-SSE2:       # %bb.0:
819; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
820; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
821; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %edx
822; X32-SSE2-NEXT:    shrdl $9, %ecx, %eax
823; X32-SSE2-NEXT:    shldl $23, %ecx, %edx
824; X32-SSE2-NEXT:    retl
825;
826; X64-AVX2-LABEL: fshr_i64_const_overshift:
827; X64-AVX2:       # %bb.0:
828; X64-AVX2-NEXT:    movq %rdi, %rax
829; X64-AVX2-NEXT:    shldq $23, %rsi, %rax
830; X64-AVX2-NEXT:    retq
831  %f = call i64 @llvm.fshr.i64(i64 %x, i64 %y, i64 105)
832  ret i64 %f
833}
834
835; This should work without any node-specific logic.
836
837define i8 @fshr_i8_const_fold() nounwind {
838; ANY-LABEL: fshr_i8_const_fold:
839; ANY:       # %bb.0:
840; ANY-NEXT:    movb $-2, %al
841; ANY-NEXT:    ret{{[l|q]}}
842  %f = call i8 @llvm.fshr.i8(i8 255, i8 0, i8 7)
843  ret i8 %f
844}
845
846define i32 @fshl_i32_shift_by_bitwidth(i32 %x, i32 %y) nounwind {
847; X32-SSE2-LABEL: fshl_i32_shift_by_bitwidth:
848; X32-SSE2:       # %bb.0:
849; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
850; X32-SSE2-NEXT:    retl
851;
852; X64-AVX2-LABEL: fshl_i32_shift_by_bitwidth:
853; X64-AVX2:       # %bb.0:
854; X64-AVX2-NEXT:    movl %edi, %eax
855; X64-AVX2-NEXT:    retq
856  %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 32)
857  ret i32 %f
858}
859
860define i32 @fshr_i32_shift_by_bitwidth(i32 %x, i32 %y) nounwind {
861; X32-SSE2-LABEL: fshr_i32_shift_by_bitwidth:
862; X32-SSE2:       # %bb.0:
863; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
864; X32-SSE2-NEXT:    retl
865;
866; X64-AVX2-LABEL: fshr_i32_shift_by_bitwidth:
867; X64-AVX2:       # %bb.0:
868; X64-AVX2-NEXT:    movl %esi, %eax
869; X64-AVX2-NEXT:    retq
870  %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 32)
871  ret i32 %f
872}
873
874define <4 x i32> @fshl_v4i32_shift_by_bitwidth(<4 x i32> %x, <4 x i32> %y) nounwind {
875; ANY-LABEL: fshl_v4i32_shift_by_bitwidth:
876; ANY:       # %bb.0:
877; ANY-NEXT:    ret{{[l|q]}}
878  %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 32, i32 32, i32 32, i32 32>)
879  ret <4 x i32> %f
880}
881
882define <4 x i32> @fshr_v4i32_shift_by_bitwidth(<4 x i32> %x, <4 x i32> %y) nounwind {
883; X32-SSE2-LABEL: fshr_v4i32_shift_by_bitwidth:
884; X32-SSE2:       # %bb.0:
885; X32-SSE2-NEXT:    movaps %xmm1, %xmm0
886; X32-SSE2-NEXT:    retl
887;
888; X64-AVX2-LABEL: fshr_v4i32_shift_by_bitwidth:
889; X64-AVX2:       # %bb.0:
890; X64-AVX2-NEXT:    vmovaps %xmm1, %xmm0
891; X64-AVX2-NEXT:    retq
892  %f = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 32, i32 32, i32 32, i32 32>)
893  ret <4 x i32> %f
894}
895
896%struct.S = type { [11 x i8], i8 }
897define void @PR45265(i32 %0, %struct.S* nocapture readonly %1) nounwind {
898; X32-SSE2-LABEL: PR45265:
899; X32-SSE2:       # %bb.0:
900; X32-SSE2-NEXT:    pushl %ebx
901; X32-SSE2-NEXT:    pushl %edi
902; X32-SSE2-NEXT:    pushl %esi
903; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
904; X32-SSE2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
905; X32-SSE2-NEXT:    leal (%eax,%eax,2), %edx
906; X32-SSE2-NEXT:    movzwl 8(%ecx,%edx,4), %esi
907; X32-SSE2-NEXT:    movsbl 10(%ecx,%edx,4), %edi
908; X32-SSE2-NEXT:    movl %edi, %ebx
909; X32-SSE2-NEXT:    shll $16, %ebx
910; X32-SSE2-NEXT:    orl %esi, %ebx
911; X32-SSE2-NEXT:    movl 4(%ecx,%edx,4), %ecx
912; X32-SSE2-NEXT:    shrdl $8, %ebx, %ecx
913; X32-SSE2-NEXT:    xorl %eax, %ecx
914; X32-SSE2-NEXT:    sarl $31, %eax
915; X32-SSE2-NEXT:    sarl $31, %edi
916; X32-SSE2-NEXT:    shldl $24, %ebx, %edi
917; X32-SSE2-NEXT:    xorl %eax, %edi
918; X32-SSE2-NEXT:    orl %edi, %ecx
919; X32-SSE2-NEXT:    jne .LBB44_1
920; X32-SSE2-NEXT:  # %bb.2:
921; X32-SSE2-NEXT:    popl %esi
922; X32-SSE2-NEXT:    popl %edi
923; X32-SSE2-NEXT:    popl %ebx
924; X32-SSE2-NEXT:    jmp _Z3foov # TAILCALL
925; X32-SSE2-NEXT:  .LBB44_1:
926; X32-SSE2-NEXT:    popl %esi
927; X32-SSE2-NEXT:    popl %edi
928; X32-SSE2-NEXT:    popl %ebx
929; X32-SSE2-NEXT:    retl
930;
931; X64-AVX2-LABEL: PR45265:
932; X64-AVX2:       # %bb.0:
933; X64-AVX2-NEXT:    movslq %edi, %rax
934; X64-AVX2-NEXT:    leaq (%rax,%rax,2), %rcx
935; X64-AVX2-NEXT:    movsbq 10(%rsi,%rcx,4), %rdx
936; X64-AVX2-NEXT:    shlq $16, %rdx
937; X64-AVX2-NEXT:    movzwl 8(%rsi,%rcx,4), %edi
938; X64-AVX2-NEXT:    orq %rdx, %rdi
939; X64-AVX2-NEXT:    movq (%rsi,%rcx,4), %rcx
940; X64-AVX2-NEXT:    shrdq $40, %rdi, %rcx
941; X64-AVX2-NEXT:    cmpq %rax, %rcx
942; X64-AVX2-NEXT:    jne .LBB44_1
943; X64-AVX2-NEXT:  # %bb.2:
944; X64-AVX2-NEXT:    jmp _Z3foov # TAILCALL
945; X64-AVX2-NEXT:  .LBB44_1:
946; X64-AVX2-NEXT:    retq
947  %3 = sext i32 %0 to i64
948  %4 = getelementptr inbounds %struct.S, %struct.S* %1, i64 %3
949  %5 = bitcast %struct.S* %4 to i88*
950  %6 = load i88, i88* %5, align 1
951  %7 = ashr i88 %6, 40
952  %8 = trunc i88 %7 to i64
953  %9 = icmp eq i64 %8, %3
954  br i1 %9, label %10, label %11
955
95610:
957  tail call void @_Z3foov()
958  br label %11
959
96011:
961  ret void
962}
963declare dso_local void @_Z3foov()
964