1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=SSE --check-prefix=SSE2
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX1
4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=AVX --check-prefix=AVX2
5
6;
7; PR6455 'Clear Upper Bits' Patterns
8;
9
10define <2 x i64> @_clearupper2xi64a(<2 x i64>) nounwind {
11; SSE-LABEL: _clearupper2xi64a:
12; SSE:       # BB#0:
13; SSE-NEXT:    andps {{.*}}(%rip), %xmm0
14; SSE-NEXT:    retq
15;
16; AVX1-LABEL: _clearupper2xi64a:
17; AVX1:       # BB#0:
18; AVX1-NEXT:    vpxor %xmm1, %xmm1, %xmm1
19; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7]
20; AVX1-NEXT:    retq
21;
22; AVX2-LABEL: _clearupper2xi64a:
23; AVX2:       # BB#0:
24; AVX2-NEXT:    vpxor %xmm1, %xmm1, %xmm1
25; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
26; AVX2-NEXT:    retq
27  %x0 = extractelement <2 x i64> %0, i32 0
28  %x1 = extractelement <2 x i64> %0, i32 1
29  %trunc0 = trunc i64 %x0 to i32
30  %trunc1 = trunc i64 %x1 to i32
31  %ext0 = zext i32 %trunc0 to i64
32  %ext1 = zext i32 %trunc1 to i64
33  %v0 = insertelement <2 x i64> undef, i64 %ext0, i32 0
34  %v1 = insertelement <2 x i64> %v0,   i64 %ext1, i32 1
35  ret <2 x i64> %v1
36}
37
38define <4 x i32> @_clearupper4xi32a(<4 x i32>) nounwind {
39; SSE-LABEL: _clearupper4xi32a:
40; SSE:       # BB#0:
41; SSE-NEXT:    andps {{.*}}(%rip), %xmm0
42; SSE-NEXT:    retq
43;
44; AVX-LABEL: _clearupper4xi32a:
45; AVX:       # BB#0:
46; AVX-NEXT:    vpxor %xmm1, %xmm1, %xmm1
47; AVX-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3],xmm0[4],xmm1[5],xmm0[6],xmm1[7]
48; AVX-NEXT:    retq
49  %x0 = extractelement <4 x i32> %0, i32 0
50  %x1 = extractelement <4 x i32> %0, i32 1
51  %x2 = extractelement <4 x i32> %0, i32 2
52  %x3 = extractelement <4 x i32> %0, i32 3
53  %trunc0 = trunc i32 %x0 to i16
54  %trunc1 = trunc i32 %x1 to i16
55  %trunc2 = trunc i32 %x2 to i16
56  %trunc3 = trunc i32 %x3 to i16
57  %ext0 = zext i16 %trunc0 to i32
58  %ext1 = zext i16 %trunc1 to i32
59  %ext2 = zext i16 %trunc2 to i32
60  %ext3 = zext i16 %trunc3 to i32
61  %v0 = insertelement <4 x i32> undef, i32 %ext0, i32 0
62  %v1 = insertelement <4 x i32> %v0,   i32 %ext1, i32 1
63  %v2 = insertelement <4 x i32> %v1,   i32 %ext2, i32 2
64  %v3 = insertelement <4 x i32> %v2,   i32 %ext3, i32 3
65  ret <4 x i32> %v3
66}
67
68define <8 x i16> @_clearupper8xi16a(<8 x i16>) nounwind {
69; SSE-LABEL: _clearupper8xi16a:
70; SSE:       # BB#0:
71; SSE-NEXT:    pextrw $1, %xmm0, %eax
72; SSE-NEXT:    pextrw $2, %xmm0, %r9d
73; SSE-NEXT:    pextrw $3, %xmm0, %edx
74; SSE-NEXT:    pextrw $4, %xmm0, %r8d
75; SSE-NEXT:    pextrw $5, %xmm0, %edi
76; SSE-NEXT:    pextrw $6, %xmm0, %esi
77; SSE-NEXT:    pextrw $7, %xmm0, %ecx
78; SSE-NEXT:    movd %ecx, %xmm1
79; SSE-NEXT:    movd %edx, %xmm2
80; SSE-NEXT:    punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1],xmm2[2],xmm1[2],xmm2[3],xmm1[3]
81; SSE-NEXT:    movd %edi, %xmm1
82; SSE-NEXT:    movd %eax, %xmm3
83; SSE-NEXT:    punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm1[0],xmm3[1],xmm1[1],xmm3[2],xmm1[2],xmm3[3],xmm1[3]
84; SSE-NEXT:    punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1],xmm3[2],xmm2[2],xmm3[3],xmm2[3]
85; SSE-NEXT:    movd %esi, %xmm1
86; SSE-NEXT:    movd %r9d, %xmm2
87; SSE-NEXT:    punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1],xmm2[2],xmm1[2],xmm2[3],xmm1[3]
88; SSE-NEXT:    movd %r8d, %xmm1
89; SSE-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
90; SSE-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3]
91; SSE-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1],xmm0[2],xmm3[2],xmm0[3],xmm3[3]
92; SSE-NEXT:    pand {{.*}}(%rip), %xmm0
93; SSE-NEXT:    retq
94;
95; AVX-LABEL: _clearupper8xi16a:
96; AVX:       # BB#0:
97; AVX-NEXT:    vandps {{.*}}(%rip), %xmm0, %xmm0
98; AVX-NEXT:    retq
99  %x0 = extractelement <8 x i16> %0, i32 0
100  %x1 = extractelement <8 x i16> %0, i32 1
101  %x2 = extractelement <8 x i16> %0, i32 2
102  %x3 = extractelement <8 x i16> %0, i32 3
103  %x4 = extractelement <8 x i16> %0, i32 4
104  %x5 = extractelement <8 x i16> %0, i32 5
105  %x6 = extractelement <8 x i16> %0, i32 6
106  %x7 = extractelement <8 x i16> %0, i32 7
107  %trunc0 = trunc i16 %x0 to i8
108  %trunc1 = trunc i16 %x1 to i8
109  %trunc2 = trunc i16 %x2 to i8
110  %trunc3 = trunc i16 %x3 to i8
111  %trunc4 = trunc i16 %x4 to i8
112  %trunc5 = trunc i16 %x5 to i8
113  %trunc6 = trunc i16 %x6 to i8
114  %trunc7 = trunc i16 %x7 to i8
115  %ext0 = zext i8 %trunc0 to i16
116  %ext1 = zext i8 %trunc1 to i16
117  %ext2 = zext i8 %trunc2 to i16
118  %ext3 = zext i8 %trunc3 to i16
119  %ext4 = zext i8 %trunc4 to i16
120  %ext5 = zext i8 %trunc5 to i16
121  %ext6 = zext i8 %trunc6 to i16
122  %ext7 = zext i8 %trunc7 to i16
123  %v0 = insertelement <8 x i16> undef, i16 %ext0, i32 0
124  %v1 = insertelement <8 x i16> %v0,   i16 %ext1, i32 1
125  %v2 = insertelement <8 x i16> %v1,   i16 %ext2, i32 2
126  %v3 = insertelement <8 x i16> %v2,   i16 %ext3, i32 3
127  %v4 = insertelement <8 x i16> %v3,   i16 %ext4, i32 4
128  %v5 = insertelement <8 x i16> %v4,   i16 %ext5, i32 5
129  %v6 = insertelement <8 x i16> %v5,   i16 %ext6, i32 6
130  %v7 = insertelement <8 x i16> %v6,   i16 %ext7, i32 7
131  ret <8 x i16> %v7
132}
133
134define <16 x i8> @_clearupper16xi8a(<16 x i8>) nounwind {
135; SSE-LABEL: _clearupper16xi8a:
136; SSE:       # BB#0:
137; SSE-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
138; SSE-NEXT:    movzbl -{{[0-9]+}}(%rsp), %eax
139; SSE-NEXT:    movd %eax, %xmm0
140; SSE-NEXT:    movzbl -{{[0-9]+}}(%rsp), %r9d
141; SSE-NEXT:    movzbl -{{[0-9]+}}(%rsp), %edx
142; SSE-NEXT:    movzbl -{{[0-9]+}}(%rsp), %esi
143; SSE-NEXT:    movzbl -{{[0-9]+}}(%rsp), %r8d
144; SSE-NEXT:    movzbl -{{[0-9]+}}(%rsp), %edi
145; SSE-NEXT:    movzbl -{{[0-9]+}}(%rsp), %eax
146; SSE-NEXT:    movd %eax, %xmm1
147; SSE-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
148; SSE-NEXT:    movd %esi, %xmm0
149; SSE-NEXT:    movzbl -{{[0-9]+}}(%rsp), %eax
150; SSE-NEXT:    movzbl -{{[0-9]+}}(%rsp), %esi
151; SSE-NEXT:    movzbl -{{[0-9]+}}(%rsp), %ecx
152; SSE-NEXT:    movd %ecx, %xmm2
153; SSE-NEXT:    punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3],xmm2[4],xmm0[4],xmm2[5],xmm0[5],xmm2[6],xmm0[6],xmm2[7],xmm0[7]
154; SSE-NEXT:    punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1],xmm2[2],xmm1[2],xmm2[3],xmm1[3],xmm2[4],xmm1[4],xmm2[5],xmm1[5],xmm2[6],xmm1[6],xmm2[7],xmm1[7]
155; SSE-NEXT:    movd %edx, %xmm0
156; SSE-NEXT:    movd %esi, %xmm1
157; SSE-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
158; SSE-NEXT:    movd %edi, %xmm0
159; SSE-NEXT:    movzbl -{{[0-9]+}}(%rsp), %ecx
160; SSE-NEXT:    movzbl -{{[0-9]+}}(%rsp), %edx
161; SSE-NEXT:    movd %edx, %xmm3
162; SSE-NEXT:    punpcklbw {{.*#+}} xmm3 = xmm3[0],xmm0[0],xmm3[1],xmm0[1],xmm3[2],xmm0[2],xmm3[3],xmm0[3],xmm3[4],xmm0[4],xmm3[5],xmm0[5],xmm3[6],xmm0[6],xmm3[7],xmm0[7]
163; SSE-NEXT:    punpcklbw {{.*#+}} xmm3 = xmm3[0],xmm1[0],xmm3[1],xmm1[1],xmm3[2],xmm1[2],xmm3[3],xmm1[3],xmm3[4],xmm1[4],xmm3[5],xmm1[5],xmm3[6],xmm1[6],xmm3[7],xmm1[7]
164; SSE-NEXT:    punpcklbw {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1],xmm3[2],xmm2[2],xmm3[3],xmm2[3],xmm3[4],xmm2[4],xmm3[5],xmm2[5],xmm3[6],xmm2[6],xmm3[7],xmm2[7]
165; SSE-NEXT:    movd %r9d, %xmm0
166; SSE-NEXT:    movd %eax, %xmm1
167; SSE-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
168; SSE-NEXT:    movd %r8d, %xmm0
169; SSE-NEXT:    movd %ecx, %xmm2
170; SSE-NEXT:    punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3],xmm2[4],xmm0[4],xmm2[5],xmm0[5],xmm2[6],xmm0[6],xmm2[7],xmm0[7]
171; SSE-NEXT:    punpcklbw {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1],xmm2[2],xmm1[2],xmm2[3],xmm1[3],xmm2[4],xmm1[4],xmm2[5],xmm1[5],xmm2[6],xmm1[6],xmm2[7],xmm1[7]
172; SSE-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
173; SSE-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
174; SSE-NEXT:    punpcklbw {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
175; SSE-NEXT:    movd {{.*#+}} xmm4 = mem[0],zero,zero,zero
176; SSE-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
177; SSE-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm4[0],xmm0[1],xmm4[1],xmm0[2],xmm4[2],xmm0[3],xmm4[3],xmm0[4],xmm4[4],xmm0[5],xmm4[5],xmm0[6],xmm4[6],xmm0[7],xmm4[7]
178; SSE-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3],xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
179; SSE-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3],xmm0[4],xmm2[4],xmm0[5],xmm2[5],xmm0[6],xmm2[6],xmm0[7],xmm2[7]
180; SSE-NEXT:    punpcklbw {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1],xmm0[2],xmm3[2],xmm0[3],xmm3[3],xmm0[4],xmm3[4],xmm0[5],xmm3[5],xmm0[6],xmm3[6],xmm0[7],xmm3[7]
181; SSE-NEXT:    pand {{.*}}(%rip), %xmm0
182; SSE-NEXT:    retq
183;
184; AVX-LABEL: _clearupper16xi8a:
185; AVX:       # BB#0:
186; AVX-NEXT:    vpextrb $0, %xmm0, %eax
187; AVX-NEXT:    vpextrb $1, %xmm0, %ecx
188; AVX-NEXT:    vmovd %eax, %xmm1
189; AVX-NEXT:    vpinsrb $1, %ecx, %xmm1, %xmm1
190; AVX-NEXT:    vpblendw {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3,4,5,6,7]
191; AVX-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
192; AVX-NEXT:    retq
193  %x0  = extractelement <16 x i8> %0, i32 0
194  %x1  = extractelement <16 x i8> %0, i32 1
195  %x2  = extractelement <16 x i8> %0, i32 2
196  %x3  = extractelement <16 x i8> %0, i32 3
197  %x4  = extractelement <16 x i8> %0, i32 4
198  %x5  = extractelement <16 x i8> %0, i32 5
199  %x6  = extractelement <16 x i8> %0, i32 6
200  %x7  = extractelement <16 x i8> %0, i32 7
201  %x8  = extractelement <16 x i8> %0, i32 8
202  %x9  = extractelement <16 x i8> %0, i32 9
203  %x10 = extractelement <16 x i8> %0, i32 10
204  %x11 = extractelement <16 x i8> %0, i32 11
205  %x12 = extractelement <16 x i8> %0, i32 12
206  %x13 = extractelement <16 x i8> %0, i32 13
207  %x14 = extractelement <16 x i8> %0, i32 14
208  %x15 = extractelement <16 x i8> %0, i32 15
209  %trunc0  = trunc i8 %x0  to i4
210  %trunc1  = trunc i8 %x1  to i4
211  %trunc2  = trunc i8 %x2  to i4
212  %trunc3  = trunc i8 %x3  to i4
213  %trunc4  = trunc i8 %x4  to i4
214  %trunc5  = trunc i8 %x5  to i4
215  %trunc6  = trunc i8 %x6  to i4
216  %trunc7  = trunc i8 %x7  to i4
217  %trunc8  = trunc i8 %x8  to i4
218  %trunc9  = trunc i8 %x9  to i4
219  %trunc10 = trunc i8 %x10 to i4
220  %trunc11 = trunc i8 %x11 to i4
221  %trunc12 = trunc i8 %x12 to i4
222  %trunc13 = trunc i8 %x13 to i4
223  %trunc14 = trunc i8 %x14 to i4
224  %trunc15 = trunc i8 %x15 to i4
225  %ext0  = zext i4 %trunc0  to i8
226  %ext1  = zext i4 %trunc1  to i8
227  %ext2  = zext i4 %trunc2  to i8
228  %ext3  = zext i4 %trunc3  to i8
229  %ext4  = zext i4 %trunc4  to i8
230  %ext5  = zext i4 %trunc5  to i8
231  %ext6  = zext i4 %trunc6  to i8
232  %ext7  = zext i4 %trunc7  to i8
233  %ext8  = zext i4 %trunc8  to i8
234  %ext9  = zext i4 %trunc9  to i8
235  %ext10 = zext i4 %trunc10 to i8
236  %ext11 = zext i4 %trunc11 to i8
237  %ext12 = zext i4 %trunc12 to i8
238  %ext13 = zext i4 %trunc13 to i8
239  %ext14 = zext i4 %trunc14 to i8
240  %ext15 = zext i4 %trunc15 to i8
241  %v0  = insertelement <16 x i8> undef, i8 %ext0,  i32 0
242  %v1  = insertelement <16 x i8> %v0,   i8 %ext1,  i32 1
243  %v2  = insertelement <16 x i8> %v1,   i8 %ext2,  i32 2
244  %v3  = insertelement <16 x i8> %v2,   i8 %ext3,  i32 3
245  %v4  = insertelement <16 x i8> %v3,   i8 %ext4,  i32 4
246  %v5  = insertelement <16 x i8> %v4,   i8 %ext5,  i32 5
247  %v6  = insertelement <16 x i8> %v5,   i8 %ext6,  i32 6
248  %v7  = insertelement <16 x i8> %v6,   i8 %ext7,  i32 7
249  %v8  = insertelement <16 x i8> %v7,   i8 %ext8,  i32 8
250  %v9  = insertelement <16 x i8> %v8,   i8 %ext9,  i32 9
251  %v10 = insertelement <16 x i8> %v9,   i8 %ext10, i32 10
252  %v11 = insertelement <16 x i8> %v10,  i8 %ext11, i32 11
253  %v12 = insertelement <16 x i8> %v11,  i8 %ext12, i32 12
254  %v13 = insertelement <16 x i8> %v12,  i8 %ext13, i32 13
255  %v14 = insertelement <16 x i8> %v13,  i8 %ext14, i32 14
256  %v15 = insertelement <16 x i8> %v14,  i8 %ext15, i32 15
257  ret <16 x i8> %v15
258}
259
260define <2 x i64> @_clearupper2xi64b(<2 x i64>) nounwind {
261; SSE-LABEL: _clearupper2xi64b:
262; SSE:       # BB#0:
263; SSE-NEXT:    xorps %xmm2, %xmm2
264; SSE-NEXT:    xorps %xmm1, %xmm1
265; SSE-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[0,0]
266; SSE-NEXT:    shufps {{.*#+}} xmm1 = xmm1[2,0],xmm0[2,3]
267; SSE-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,0],xmm1[2,0]
268; SSE-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,1],xmm2[2,0]
269; SSE-NEXT:    movaps %xmm1, %xmm0
270; SSE-NEXT:    retq
271;
272; AVX1-LABEL: _clearupper2xi64b:
273; AVX1:       # BB#0:
274; AVX1-NEXT:    vpxor %xmm1, %xmm1, %xmm1
275; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7]
276; AVX1-NEXT:    retq
277;
278; AVX2-LABEL: _clearupper2xi64b:
279; AVX2:       # BB#0:
280; AVX2-NEXT:    vpxor %xmm1, %xmm1, %xmm1
281; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
282; AVX2-NEXT:    retq
283  %x32 = bitcast <2 x i64> %0 to <4 x i32>
284  %r0 = insertelement <4 x i32> %x32, i32 zeroinitializer, i32 1
285  %r1 = insertelement <4 x i32> %r0,  i32 zeroinitializer, i32 3
286  %r = bitcast <4 x i32> %r1 to <2 x i64>
287  ret <2 x i64> %r
288}
289
290define <4 x i32> @_clearupper4xi32b(<4 x i32>) nounwind {
291; SSE-LABEL: _clearupper4xi32b:
292; SSE:       # BB#0:
293; SSE-NEXT:    andps {{.*}}(%rip), %xmm0
294; SSE-NEXT:    retq
295;
296; AVX-LABEL: _clearupper4xi32b:
297; AVX:       # BB#0:
298; AVX-NEXT:    vpxor %xmm1, %xmm1, %xmm1
299; AVX-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3],xmm0[4],xmm1[5],xmm0[6],xmm1[7]
300; AVX-NEXT:    retq
301  %x16 = bitcast <4 x i32> %0 to <8 x i16>
302  %r0 = insertelement <8 x i16> %x16, i16 zeroinitializer, i32 1
303  %r1 = insertelement <8 x i16> %r0,  i16 zeroinitializer, i32 3
304  %r2 = insertelement <8 x i16> %r1,  i16 zeroinitializer, i32 5
305  %r3 = insertelement <8 x i16> %r2,  i16 zeroinitializer, i32 7
306  %r = bitcast <8 x i16> %r3 to <4 x i32>
307  ret <4 x i32> %r
308}
309
310define <8 x i16> @_clearupper8xi16b(<8 x i16>) nounwind {
311; SSE-LABEL: _clearupper8xi16b:
312; SSE:       # BB#0:
313; SSE-NEXT:    andps {{.*}}(%rip), %xmm0
314; SSE-NEXT:    retq
315;
316; AVX-LABEL: _clearupper8xi16b:
317; AVX:       # BB#0:
318; AVX-NEXT:    vandps {{.*}}(%rip), %xmm0, %xmm0
319; AVX-NEXT:    retq
320  %x8 = bitcast <8 x i16> %0 to <16 x i8>
321  %r0 = insertelement <16 x i8> %x8, i8 zeroinitializer, i32 1
322  %r1 = insertelement <16 x i8> %r0, i8 zeroinitializer, i32 3
323  %r2 = insertelement <16 x i8> %r1, i8 zeroinitializer, i32 5
324  %r3 = insertelement <16 x i8> %r2, i8 zeroinitializer, i32 7
325  %r4 = insertelement <16 x i8> %r3, i8 zeroinitializer, i32 9
326  %r5 = insertelement <16 x i8> %r4, i8 zeroinitializer, i32 11
327  %r6 = insertelement <16 x i8> %r5, i8 zeroinitializer, i32 13
328  %r7 = insertelement <16 x i8> %r6, i8 zeroinitializer, i32 15
329  %r = bitcast <16 x i8> %r7 to <8 x i16>
330  ret <8 x i16> %r
331}
332
333define <16 x i8> @_clearupper16xi8b(<16 x i8>) nounwind {
334; SSE-LABEL: _clearupper16xi8b:
335; SSE:       # BB#0:
336; SSE-NEXT:    pushq %r14
337; SSE-NEXT:    pushq %rbx
338; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
339; SSE-NEXT:    movd %xmm0, %rcx
340; SSE-NEXT:    movq %rcx, %r8
341; SSE-NEXT:    movq %rcx, %r9
342; SSE-NEXT:    movq %rcx, %r10
343; SSE-NEXT:    movq %rcx, %rax
344; SSE-NEXT:    movq %rcx, %rdx
345; SSE-NEXT:    movq %rcx, %rsi
346; SSE-NEXT:    movq %rcx, %rdi
347; SSE-NEXT:    andb $15, %cl
348; SSE-NEXT:    movb %cl, -{{[0-9]+}}(%rsp)
349; SSE-NEXT:    movd %xmm1, %rcx
350; SSE-NEXT:    shrq $56, %rdi
351; SSE-NEXT:    andb $15, %dil
352; SSE-NEXT:    movb %dil, -{{[0-9]+}}(%rsp)
353; SSE-NEXT:    movq %rcx, %r11
354; SSE-NEXT:    shrq $48, %rsi
355; SSE-NEXT:    andb $15, %sil
356; SSE-NEXT:    movb %sil, -{{[0-9]+}}(%rsp)
357; SSE-NEXT:    movq %rcx, %r14
358; SSE-NEXT:    shrq $40, %rdx
359; SSE-NEXT:    andb $15, %dl
360; SSE-NEXT:    movb %dl, -{{[0-9]+}}(%rsp)
361; SSE-NEXT:    movq %rcx, %rdx
362; SSE-NEXT:    shrq $32, %rax
363; SSE-NEXT:    andb $15, %al
364; SSE-NEXT:    movb %al, -{{[0-9]+}}(%rsp)
365; SSE-NEXT:    movq %rcx, %rax
366; SSE-NEXT:    shrq $24, %r10
367; SSE-NEXT:    andb $15, %r10b
368; SSE-NEXT:    movb %r10b, -{{[0-9]+}}(%rsp)
369; SSE-NEXT:    movq %rcx, %rdi
370; SSE-NEXT:    shrq $16, %r9
371; SSE-NEXT:    andb $15, %r9b
372; SSE-NEXT:    movb %r9b, -{{[0-9]+}}(%rsp)
373; SSE-NEXT:    movq %rcx, %rsi
374; SSE-NEXT:    shrq $8, %r8
375; SSE-NEXT:    andb $15, %r8b
376; SSE-NEXT:    movb %r8b, -{{[0-9]+}}(%rsp)
377; SSE-NEXT:    movq %rcx, %rbx
378; SSE-NEXT:    movb $0, -{{[0-9]+}}(%rsp)
379; SSE-NEXT:    andb $15, %cl
380; SSE-NEXT:    movb %cl, -{{[0-9]+}}(%rsp)
381; SSE-NEXT:    shrq $56, %rbx
382; SSE-NEXT:    andb $15, %bl
383; SSE-NEXT:    movb %bl, -{{[0-9]+}}(%rsp)
384; SSE-NEXT:    shrq $48, %rsi
385; SSE-NEXT:    andb $15, %sil
386; SSE-NEXT:    movb %sil, -{{[0-9]+}}(%rsp)
387; SSE-NEXT:    shrq $40, %rdi
388; SSE-NEXT:    andb $15, %dil
389; SSE-NEXT:    movb %dil, -{{[0-9]+}}(%rsp)
390; SSE-NEXT:    shrq $32, %rax
391; SSE-NEXT:    andb $15, %al
392; SSE-NEXT:    movb %al, -{{[0-9]+}}(%rsp)
393; SSE-NEXT:    shrq $24, %rdx
394; SSE-NEXT:    andb $15, %dl
395; SSE-NEXT:    movb %dl, -{{[0-9]+}}(%rsp)
396; SSE-NEXT:    shrq $16, %r14
397; SSE-NEXT:    andb $15, %r14b
398; SSE-NEXT:    movb %r14b, -{{[0-9]+}}(%rsp)
399; SSE-NEXT:    shrq $8, %r11
400; SSE-NEXT:    andb $15, %r11b
401; SSE-NEXT:    movb %r11b, -{{[0-9]+}}(%rsp)
402; SSE-NEXT:    movb $0, -{{[0-9]+}}(%rsp)
403; SSE-NEXT:    movq {{.*#+}} xmm0 = mem[0],zero
404; SSE-NEXT:    movq {{.*#+}} xmm1 = mem[0],zero
405; SSE-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
406; SSE-NEXT:    popq %rbx
407; SSE-NEXT:    popq %r14
408; SSE-NEXT:    retq
409;
410; AVX-LABEL: _clearupper16xi8b:
411; AVX:       # BB#0:
412; AVX-NEXT:    pushq %rbp
413; AVX-NEXT:    pushq %r15
414; AVX-NEXT:    pushq %r14
415; AVX-NEXT:    pushq %r13
416; AVX-NEXT:    pushq %r12
417; AVX-NEXT:    pushq %rbx
418; AVX-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
419; AVX-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx
420; AVX-NEXT:    movq -{{[0-9]+}}(%rsp), %rdx
421; AVX-NEXT:    movq %rcx, %r8
422; AVX-NEXT:    movq %rcx, %r9
423; AVX-NEXT:    movq %rcx, %r10
424; AVX-NEXT:    movq %rcx, %r11
425; AVX-NEXT:    movq %rcx, %r14
426; AVX-NEXT:    movq %rcx, %r15
427; AVX-NEXT:    movq %rdx, %r12
428; AVX-NEXT:    movq %rdx, %r13
429; AVX-NEXT:    movq %rdx, %rdi
430; AVX-NEXT:    movq %rdx, %rax
431; AVX-NEXT:    movq %rdx, %rsi
432; AVX-NEXT:    movq %rdx, %rbx
433; AVX-NEXT:    movq %rdx, %rbp
434; AVX-NEXT:    andb $15, %dl
435; AVX-NEXT:    movb %dl, -{{[0-9]+}}(%rsp)
436; AVX-NEXT:    movq %rcx, %rdx
437; AVX-NEXT:    andb $15, %cl
438; AVX-NEXT:    movb %cl, -{{[0-9]+}}(%rsp)
439; AVX-NEXT:    shrq $56, %rbp
440; AVX-NEXT:    andb $15, %bpl
441; AVX-NEXT:    movb %bpl, -{{[0-9]+}}(%rsp)
442; AVX-NEXT:    shrq $48, %rbx
443; AVX-NEXT:    andb $15, %bl
444; AVX-NEXT:    movb %bl, -{{[0-9]+}}(%rsp)
445; AVX-NEXT:    shrq $40, %rsi
446; AVX-NEXT:    andb $15, %sil
447; AVX-NEXT:    movb %sil, -{{[0-9]+}}(%rsp)
448; AVX-NEXT:    shrq $32, %rax
449; AVX-NEXT:    andb $15, %al
450; AVX-NEXT:    movb %al, -{{[0-9]+}}(%rsp)
451; AVX-NEXT:    shrq $24, %rdi
452; AVX-NEXT:    andb $15, %dil
453; AVX-NEXT:    movb %dil, -{{[0-9]+}}(%rsp)
454; AVX-NEXT:    shrq $16, %r13
455; AVX-NEXT:    andb $15, %r13b
456; AVX-NEXT:    movb %r13b, -{{[0-9]+}}(%rsp)
457; AVX-NEXT:    shrq $8, %r12
458; AVX-NEXT:    andb $15, %r12b
459; AVX-NEXT:    movb %r12b, -{{[0-9]+}}(%rsp)
460; AVX-NEXT:    shrq $56, %rdx
461; AVX-NEXT:    andb $15, %dl
462; AVX-NEXT:    movb %dl, -{{[0-9]+}}(%rsp)
463; AVX-NEXT:    shrq $48, %r15
464; AVX-NEXT:    andb $15, %r15b
465; AVX-NEXT:    movb %r15b, -{{[0-9]+}}(%rsp)
466; AVX-NEXT:    shrq $40, %r14
467; AVX-NEXT:    andb $15, %r14b
468; AVX-NEXT:    movb %r14b, -{{[0-9]+}}(%rsp)
469; AVX-NEXT:    shrq $32, %r11
470; AVX-NEXT:    andb $15, %r11b
471; AVX-NEXT:    movb %r11b, -{{[0-9]+}}(%rsp)
472; AVX-NEXT:    shrq $24, %r10
473; AVX-NEXT:    andb $15, %r10b
474; AVX-NEXT:    movb %r10b, -{{[0-9]+}}(%rsp)
475; AVX-NEXT:    shrq $16, %r9
476; AVX-NEXT:    andb $15, %r9b
477; AVX-NEXT:    movb %r9b, -{{[0-9]+}}(%rsp)
478; AVX-NEXT:    shrq $8, %r8
479; AVX-NEXT:    andb $15, %r8b
480; AVX-NEXT:    movb %r8b, -{{[0-9]+}}(%rsp)
481; AVX-NEXT:    movb $0, -{{[0-9]+}}(%rsp)
482; AVX-NEXT:    vmovaps -{{[0-9]+}}(%rsp), %xmm0
483; AVX-NEXT:    popq %rbx
484; AVX-NEXT:    popq %r12
485; AVX-NEXT:    popq %r13
486; AVX-NEXT:    popq %r14
487; AVX-NEXT:    popq %r15
488; AVX-NEXT:    popq %rbp
489; AVX-NEXT:    retq
490  %x4  = bitcast <16 x i8> %0 to <32 x i4>
491  %r0  = insertelement <32 x i4> %x4,  i4 zeroinitializer, i32 1
492  %r1  = insertelement <32 x i4> %r0,  i4 zeroinitializer, i32 3
493  %r2  = insertelement <32 x i4> %r1,  i4 zeroinitializer, i32 5
494  %r3  = insertelement <32 x i4> %r2,  i4 zeroinitializer, i32 7
495  %r4  = insertelement <32 x i4> %r3,  i4 zeroinitializer, i32 9
496  %r5  = insertelement <32 x i4> %r4,  i4 zeroinitializer, i32 11
497  %r6  = insertelement <32 x i4> %r5,  i4 zeroinitializer, i32 13
498  %r7  = insertelement <32 x i4> %r6,  i4 zeroinitializer, i32 15
499  %r8  = insertelement <32 x i4> %r7,  i4 zeroinitializer, i32 17
500  %r9  = insertelement <32 x i4> %r8,  i4 zeroinitializer, i32 19
501  %r10 = insertelement <32 x i4> %r9,  i4 zeroinitializer, i32 21
502  %r11 = insertelement <32 x i4> %r10, i4 zeroinitializer, i32 23
503  %r12 = insertelement <32 x i4> %r11, i4 zeroinitializer, i32 25
504  %r13 = insertelement <32 x i4> %r12, i4 zeroinitializer, i32 27
505  %r14 = insertelement <32 x i4> %r13, i4 zeroinitializer, i32 29
506  %r15 = insertelement <32 x i4> %r14, i4 zeroinitializer, i32 31
507  %r = bitcast <32 x i4> %r15 to <16 x i8>
508  ret <16 x i8> %r
509}
510
511define <2 x i64> @_clearupper2xi64c(<2 x i64>) nounwind {
512; SSE-LABEL: _clearupper2xi64c:
513; SSE:       # BB#0:
514; SSE-NEXT:    andps {{.*}}(%rip), %xmm0
515; SSE-NEXT:    retq
516;
517; AVX1-LABEL: _clearupper2xi64c:
518; AVX1:       # BB#0:
519; AVX1-NEXT:    vpxor %xmm1, %xmm1, %xmm1
520; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,3],xmm0[4,5],xmm1[6,7]
521; AVX1-NEXT:    retq
522;
523; AVX2-LABEL: _clearupper2xi64c:
524; AVX2:       # BB#0:
525; AVX2-NEXT:    vpxor %xmm1, %xmm1, %xmm1
526; AVX2-NEXT:    vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3]
527; AVX2-NEXT:    retq
528  %r = and <2 x i64> <i64 4294967295, i64 4294967295>, %0
529  ret <2 x i64> %r
530}
531
532define <4 x i32> @_clearupper4xi32c(<4 x i32>) nounwind {
533; SSE-LABEL: _clearupper4xi32c:
534; SSE:       # BB#0:
535; SSE-NEXT:    andps {{.*}}(%rip), %xmm0
536; SSE-NEXT:    retq
537;
538; AVX-LABEL: _clearupper4xi32c:
539; AVX:       # BB#0:
540; AVX-NEXT:    vpxor %xmm1, %xmm1, %xmm1
541; AVX-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2],xmm1[3],xmm0[4],xmm1[5],xmm0[6],xmm1[7]
542; AVX-NEXT:    retq
543  %r = and <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>, %0
544  ret <4 x i32> %r
545}
546
547define <8 x i16> @_clearupper8xi16c(<8 x i16>) nounwind {
548; SSE-LABEL: _clearupper8xi16c:
549; SSE:       # BB#0:
550; SSE-NEXT:    andps {{.*}}(%rip), %xmm0
551; SSE-NEXT:    retq
552;
553; AVX-LABEL: _clearupper8xi16c:
554; AVX:       # BB#0:
555; AVX-NEXT:    vandps {{.*}}(%rip), %xmm0, %xmm0
556; AVX-NEXT:    retq
557  %r = and <8 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>, %0
558  ret <8 x i16> %r
559}
560
561define <16 x i8> @_clearupper16xi8c(<16 x i8>) nounwind {
562; SSE-LABEL: _clearupper16xi8c:
563; SSE:       # BB#0:
564; SSE-NEXT:    andps {{.*}}(%rip), %xmm0
565; SSE-NEXT:    retq
566;
567; AVX-LABEL: _clearupper16xi8c:
568; AVX:       # BB#0:
569; AVX-NEXT:    vandps {{.*}}(%rip), %xmm0, %xmm0
570; AVX-NEXT:    retq
571  %r = and <16 x i8> <i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15>, %0
572  ret <16 x i8> %r
573}
574