1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE2
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE41
4
5define void @foo(<3 x float> %in, <4 x i8>* nocapture %out) nounwind {
6; SSE2-LABEL: foo:
7; SSE2:       # %bb.0:
8; SSE2-NEXT:    cvttps2dq %xmm0, %xmm0
9; SSE2-NEXT:    movl $255, %eax
10; SSE2-NEXT:    movd %eax, %xmm1
11; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[0,0],xmm0[2,0]
12; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[2,0]
13; SSE2-NEXT:    andps {{.*}}(%rip), %xmm0
14; SSE2-NEXT:    packuswb %xmm0, %xmm0
15; SSE2-NEXT:    packuswb %xmm0, %xmm0
16; SSE2-NEXT:    movd %xmm0, (%rdi)
17; SSE2-NEXT:    retq
18;
19; SSE41-LABEL: foo:
20; SSE41:       # %bb.0:
21; SSE41-NEXT:    cvttps2dq %xmm0, %xmm0
22; SSE41-NEXT:    movl $255, %eax
23; SSE41-NEXT:    pinsrd $3, %eax, %xmm0
24; SSE41-NEXT:    pshufb {{.*#+}} xmm0 = xmm0[0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u]
25; SSE41-NEXT:    movd %xmm0, (%rdi)
26; SSE41-NEXT:    retq
27  %t0 = fptoui <3 x float> %in to <3 x i8>
28  %t1 = shufflevector <3 x i8> %t0, <3 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef>
29  %t2 = insertelement <4 x i8> %t1, i8 -1, i32 3
30  store <4 x i8> %t2, <4 x i8>* %out, align 4
31  ret void
32}
33
34; Verify that the DAGCombiner doesn't wrongly fold a build_vector into a
35; blend with a zero vector if the build_vector contains negative zero.
36
37define <4 x float> @test_negative_zero_1(<4 x float> %A) {
38; SSE2-LABEL: test_negative_zero_1:
39; SSE2:       # %bb.0: # %entry
40; SSE2-NEXT:    movaps %xmm0, %xmm1
41; SSE2-NEXT:    unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1]
42; SSE2-NEXT:    movss {{.*#+}} xmm2 = mem[0],zero,zero,zero
43; SSE2-NEXT:    unpcklps {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
44; SSE2-NEXT:    xorps %xmm2, %xmm2
45; SSE2-NEXT:    movss {{.*#+}} xmm2 = xmm1[0],xmm2[1,2,3]
46; SSE2-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0],xmm2[0]
47; SSE2-NEXT:    retq
48;
49; SSE41-LABEL: test_negative_zero_1:
50; SSE41:       # %bb.0: # %entry
51; SSE41-NEXT:    insertps {{.*#+}} xmm0 = xmm0[0],mem[0],xmm0[2],zero
52; SSE41-NEXT:    retq
53entry:
54  %0 = extractelement <4 x float> %A, i32 0
55  %1 = insertelement <4 x float> undef, float %0, i32 0
56  %2 = insertelement <4 x float> %1, float -0.0, i32 1
57  %3 = extractelement <4 x float> %A, i32 2
58  %4 = insertelement <4 x float> %2, float %3, i32 2
59  %5 = insertelement <4 x float> %4, float 0.0, i32 3
60  ret <4 x float> %5
61}
62
63; FIXME: This could be 'movhpd {{.*#+}} xmm0 = xmm0[0],mem[0]'.
64
65define <2 x double> @test_negative_zero_2(<2 x double> %A) {
66; SSE2-LABEL: test_negative_zero_2:
67; SSE2:       # %bb.0: # %entry
68; SSE2-NEXT:    shufpd {{.*#+}} xmm0 = xmm0[0],mem[1]
69; SSE2-NEXT:    retq
70;
71; SSE41-LABEL: test_negative_zero_2:
72; SSE41:       # %bb.0: # %entry
73; SSE41-NEXT:    blendps {{.*#+}} xmm0 = xmm0[0,1],mem[2,3]
74; SSE41-NEXT:    retq
75entry:
76  %0 = extractelement <2 x double> %A, i32 0
77  %1 = insertelement <2 x double> undef, double %0, i32 0
78  %2 = insertelement <2 x double> %1, double -0.0, i32 1
79  ret <2 x double> %2
80}
81
82define <4 x float> @test_buildvector_v4f32_register(float %f0, float %f1, float %f2, float %f3) {
83; SSE2-LABEL: test_buildvector_v4f32_register:
84; SSE2:       # %bb.0:
85; SSE2-NEXT:    unpcklps {{.*#+}} xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1]
86; SSE2-NEXT:    unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
87; SSE2-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0],xmm2[0]
88; SSE2-NEXT:    retq
89;
90; SSE41-LABEL: test_buildvector_v4f32_register:
91; SSE41:       # %bb.0:
92; SSE41-NEXT:    insertps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[2,3]
93; SSE41-NEXT:    insertps {{.*#+}} xmm0 = xmm0[0,1],xmm2[0],xmm0[3]
94; SSE41-NEXT:    insertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm3[0]
95; SSE41-NEXT:    retq
96  %ins0 = insertelement <4 x float> undef, float %f0, i32 0
97  %ins1 = insertelement <4 x float> %ins0, float %f1, i32 1
98  %ins2 = insertelement <4 x float> %ins1, float %f2, i32 2
99  %ins3 = insertelement <4 x float> %ins2, float %f3, i32 3
100  ret <4 x float> %ins3
101}
102
103define <4 x float> @test_buildvector_v4f32_load(float* %p0, float* %p1, float* %p2, float* %p3) {
104; SSE2-LABEL: test_buildvector_v4f32_load:
105; SSE2:       # %bb.0:
106; SSE2-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
107; SSE2-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
108; SSE2-NEXT:    unpcklps {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
109; SSE2-NEXT:    movss {{.*#+}} xmm2 = mem[0],zero,zero,zero
110; SSE2-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
111; SSE2-NEXT:    unpcklps {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
112; SSE2-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
113; SSE2-NEXT:    retq
114;
115; SSE41-LABEL: test_buildvector_v4f32_load:
116; SSE41:       # %bb.0:
117; SSE41-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
118; SSE41-NEXT:    insertps {{.*#+}} xmm0 = xmm0[0],mem[0],xmm0[2,3]
119; SSE41-NEXT:    insertps {{.*#+}} xmm0 = xmm0[0,1],mem[0],xmm0[3]
120; SSE41-NEXT:    insertps {{.*#+}} xmm0 = xmm0[0,1,2],mem[0]
121; SSE41-NEXT:    retq
122  %f0 = load float, float* %p0, align 4
123  %f1 = load float, float* %p1, align 4
124  %f2 = load float, float* %p2, align 4
125  %f3 = load float, float* %p3, align 4
126  %ins0 = insertelement <4 x float> undef, float %f0, i32 0
127  %ins1 = insertelement <4 x float> %ins0, float %f1, i32 1
128  %ins2 = insertelement <4 x float> %ins1, float %f2, i32 2
129  %ins3 = insertelement <4 x float> %ins2, float %f3, i32 3
130  ret <4 x float> %ins3
131}
132
133define <4 x float> @test_buildvector_v4f32_partial_load(float %f0, float %f1, float %f2, float* %p3) {
134; SSE2-LABEL: test_buildvector_v4f32_partial_load:
135; SSE2:       # %bb.0:
136; SSE2-NEXT:    movss {{.*#+}} xmm3 = mem[0],zero,zero,zero
137; SSE2-NEXT:    unpcklps {{.*#+}} xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1]
138; SSE2-NEXT:    unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
139; SSE2-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0],xmm2[0]
140; SSE2-NEXT:    retq
141;
142; SSE41-LABEL: test_buildvector_v4f32_partial_load:
143; SSE41:       # %bb.0:
144; SSE41-NEXT:    insertps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[2,3]
145; SSE41-NEXT:    insertps {{.*#+}} xmm0 = xmm0[0,1],xmm2[0],xmm0[3]
146; SSE41-NEXT:    insertps {{.*#+}} xmm0 = xmm0[0,1,2],mem[0]
147; SSE41-NEXT:    retq
148  %f3 = load float, float* %p3, align 4
149  %ins0 = insertelement <4 x float> undef, float %f0, i32 0
150  %ins1 = insertelement <4 x float> %ins0, float %f1, i32 1
151  %ins2 = insertelement <4 x float> %ins1, float %f2, i32 2
152  %ins3 = insertelement <4 x float> %ins2, float %f3, i32 3
153  ret <4 x float> %ins3
154}
155
156define <4 x i32> @test_buildvector_v4i32_register(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
157; SSE2-LABEL: test_buildvector_v4i32_register:
158; SSE2:       # %bb.0:
159; SSE2-NEXT:    movd %ecx, %xmm0
160; SSE2-NEXT:    movd %edx, %xmm1
161; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
162; SSE2-NEXT:    movd %esi, %xmm2
163; SSE2-NEXT:    movd %edi, %xmm0
164; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
165; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
166; SSE2-NEXT:    retq
167;
168; SSE41-LABEL: test_buildvector_v4i32_register:
169; SSE41:       # %bb.0:
170; SSE41-NEXT:    movd %edi, %xmm0
171; SSE41-NEXT:    pinsrd $1, %esi, %xmm0
172; SSE41-NEXT:    pinsrd $2, %edx, %xmm0
173; SSE41-NEXT:    pinsrd $3, %ecx, %xmm0
174; SSE41-NEXT:    retq
175  %ins0 = insertelement <4 x i32> undef, i32 %a0, i32 0
176  %ins1 = insertelement <4 x i32> %ins0, i32 %a1, i32 1
177  %ins2 = insertelement <4 x i32> %ins1, i32 %a2, i32 2
178  %ins3 = insertelement <4 x i32> %ins2, i32 %a3, i32 3
179  ret <4 x i32> %ins3
180}
181
182define <4 x i32> @test_buildvector_v4i32_partial(i32 %a0, i32 %a3) {
183; SSE2-LABEL: test_buildvector_v4i32_partial:
184; SSE2:       # %bb.0:
185; SSE2-NEXT:    movd %edi, %xmm0
186; SSE2-NEXT:    movd %esi, %xmm1
187; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,0,1,1]
188; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
189; SSE2-NEXT:    retq
190;
191; SSE41-LABEL: test_buildvector_v4i32_partial:
192; SSE41:       # %bb.0:
193; SSE41-NEXT:    movd %edi, %xmm0
194; SSE41-NEXT:    pinsrd $3, %esi, %xmm0
195; SSE41-NEXT:    retq
196  %ins0 = insertelement <4 x i32> undef, i32   %a0, i32 0
197  %ins1 = insertelement <4 x i32> %ins0, i32 undef, i32 1
198  %ins2 = insertelement <4 x i32> %ins1, i32 undef, i32 2
199  %ins3 = insertelement <4 x i32> %ins2, i32   %a3, i32 3
200  ret <4 x i32> %ins3
201}
202
203define <4 x i32> @test_buildvector_v4i32_register_zero(i32 %a0, i32 %a2, i32 %a3) {
204; CHECK-LABEL: test_buildvector_v4i32_register_zero:
205; CHECK:       # %bb.0:
206; CHECK-NEXT:    movd %edx, %xmm0
207; CHECK-NEXT:    movd %esi, %xmm1
208; CHECK-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
209; CHECK-NEXT:    movd %edi, %xmm0
210; CHECK-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
211; CHECK-NEXT:    retq
212  %ins0 = insertelement <4 x i32> undef, i32 %a0, i32 0
213  %ins1 = insertelement <4 x i32> %ins0, i32   0, i32 1
214  %ins2 = insertelement <4 x i32> %ins1, i32 %a2, i32 2
215  %ins3 = insertelement <4 x i32> %ins2, i32 %a3, i32 3
216  ret <4 x i32> %ins3
217}
218
219define <4 x i32> @test_buildvector_v4i32_register_zero_2(i32 %a1, i32 %a2, i32 %a3) {
220; CHECK-LABEL: test_buildvector_v4i32_register_zero_2:
221; CHECK:       # %bb.0:
222; CHECK-NEXT:    movd %edx, %xmm0
223; CHECK-NEXT:    movd %esi, %xmm1
224; CHECK-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
225; CHECK-NEXT:    movd %edi, %xmm0
226; CHECK-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,0],xmm1[0,1]
227; CHECK-NEXT:    retq
228  %ins0 = insertelement <4 x i32> undef, i32   0, i32 0
229  %ins1 = insertelement <4 x i32> %ins0, i32 %a1, i32 1
230  %ins2 = insertelement <4 x i32> %ins1, i32 %a2, i32 2
231  %ins3 = insertelement <4 x i32> %ins2, i32 %a3, i32 3
232  ret <4 x i32> %ins3
233}
234
235define <8 x i16> @test_buildvector_v8i16_register(i16 %a0, i16 %a1, i16 %a2, i16 %a3, i16 %a4, i16 %a5, i16 %a6, i16 %a7) {
236; SSE2-LABEL: test_buildvector_v8i16_register:
237; SSE2:       # %bb.0:
238; SSE2-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
239; SSE2-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
240; SSE2-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
241; SSE2-NEXT:    movd %r9d, %xmm0
242; SSE2-NEXT:    movd %r8d, %xmm2
243; SSE2-NEXT:    punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3]
244; SSE2-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
245; SSE2-NEXT:    movd %ecx, %xmm0
246; SSE2-NEXT:    movd %edx, %xmm1
247; SSE2-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
248; SSE2-NEXT:    movd %esi, %xmm3
249; SSE2-NEXT:    movd %edi, %xmm0
250; SSE2-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1],xmm0[2],xmm3[2],xmm0[3],xmm3[3]
251; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
252; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0]
253; SSE2-NEXT:    retq
254;
255; SSE41-LABEL: test_buildvector_v8i16_register:
256; SSE41:       # %bb.0:
257; SSE41-NEXT:    movd %edi, %xmm0
258; SSE41-NEXT:    pinsrw $1, %esi, %xmm0
259; SSE41-NEXT:    pinsrw $2, %edx, %xmm0
260; SSE41-NEXT:    pinsrw $3, %ecx, %xmm0
261; SSE41-NEXT:    pinsrw $4, %r8d, %xmm0
262; SSE41-NEXT:    pinsrw $5, %r9d, %xmm0
263; SSE41-NEXT:    pinsrw $6, {{[0-9]+}}(%rsp), %xmm0
264; SSE41-NEXT:    pinsrw $7, {{[0-9]+}}(%rsp), %xmm0
265; SSE41-NEXT:    retq
266  %ins0 = insertelement <8 x i16> undef, i16 %a0, i32 0
267  %ins1 = insertelement <8 x i16> %ins0, i16 %a1, i32 1
268  %ins2 = insertelement <8 x i16> %ins1, i16 %a2, i32 2
269  %ins3 = insertelement <8 x i16> %ins2, i16 %a3, i32 3
270  %ins4 = insertelement <8 x i16> %ins3, i16 %a4, i32 4
271  %ins5 = insertelement <8 x i16> %ins4, i16 %a5, i32 5
272  %ins6 = insertelement <8 x i16> %ins5, i16 %a6, i32 6
273  %ins7 = insertelement <8 x i16> %ins6, i16 %a7, i32 7
274  ret <8 x i16> %ins7
275}
276
277define <8 x i16> @test_buildvector_v8i16_partial(i16 %a1, i16 %a3, i16 %a4, i16 %a5) {
278; CHECK-LABEL: test_buildvector_v8i16_partial:
279; CHECK:       # %bb.0:
280; CHECK-NEXT:    pxor %xmm0, %xmm0
281; CHECK-NEXT:    pinsrw $1, %edi, %xmm0
282; CHECK-NEXT:    pinsrw $3, %esi, %xmm0
283; CHECK-NEXT:    pinsrw $4, %edx, %xmm0
284; CHECK-NEXT:    pinsrw $5, %ecx, %xmm0
285; CHECK-NEXT:    retq
286  %ins0 = insertelement <8 x i16> undef, i16 undef, i32 0
287  %ins1 = insertelement <8 x i16> %ins0, i16   %a1, i32 1
288  %ins2 = insertelement <8 x i16> %ins1, i16 undef, i32 2
289  %ins3 = insertelement <8 x i16> %ins2, i16   %a3, i32 3
290  %ins4 = insertelement <8 x i16> %ins3, i16   %a4, i32 4
291  %ins5 = insertelement <8 x i16> %ins4, i16   %a5, i32 5
292  %ins6 = insertelement <8 x i16> %ins5, i16 undef, i32 6
293  %ins7 = insertelement <8 x i16> %ins6, i16 undef, i32 7
294  ret <8 x i16> %ins7
295}
296
297define <8 x i16> @test_buildvector_v8i16_register_zero(i16 %a0, i16 %a3, i16 %a4, i16 %a5) {
298; CHECK-LABEL: test_buildvector_v8i16_register_zero:
299; CHECK:       # %bb.0:
300; CHECK-NEXT:    pxor %xmm0, %xmm0
301; CHECK-NEXT:    pinsrw $0, %edi, %xmm0
302; CHECK-NEXT:    pinsrw $3, %esi, %xmm0
303; CHECK-NEXT:    pinsrw $4, %edx, %xmm0
304; CHECK-NEXT:    pinsrw $5, %ecx, %xmm0
305; CHECK-NEXT:    retq
306  %ins0 = insertelement <8 x i16> undef, i16   %a0, i32 0
307  %ins1 = insertelement <8 x i16> %ins0, i16     0, i32 1
308  %ins2 = insertelement <8 x i16> %ins1, i16     0, i32 2
309  %ins3 = insertelement <8 x i16> %ins2, i16   %a3, i32 3
310  %ins4 = insertelement <8 x i16> %ins3, i16   %a4, i32 4
311  %ins5 = insertelement <8 x i16> %ins4, i16   %a5, i32 5
312  %ins6 = insertelement <8 x i16> %ins5, i16     0, i32 6
313  %ins7 = insertelement <8 x i16> %ins6, i16     0, i32 7
314  ret <8 x i16> %ins7
315}
316
317define <8 x i16> @test_buildvector_v8i16_register_zero_2(i16 %a1, i16 %a3, i16 %a4, i16 %a5) {
318; CHECK-LABEL: test_buildvector_v8i16_register_zero_2:
319; CHECK:       # %bb.0:
320; CHECK-NEXT:    pxor %xmm0, %xmm0
321; CHECK-NEXT:    pinsrw $1, %edi, %xmm0
322; CHECK-NEXT:    pinsrw $3, %esi, %xmm0
323; CHECK-NEXT:    pinsrw $4, %edx, %xmm0
324; CHECK-NEXT:    pinsrw $5, %ecx, %xmm0
325; CHECK-NEXT:    retq
326  %ins0 = insertelement <8 x i16> undef, i16     0, i32 0
327  %ins1 = insertelement <8 x i16> %ins0, i16   %a1, i32 1
328  %ins2 = insertelement <8 x i16> %ins1, i16     0, i32 2
329  %ins3 = insertelement <8 x i16> %ins2, i16   %a3, i32 3
330  %ins4 = insertelement <8 x i16> %ins3, i16   %a4, i32 4
331  %ins5 = insertelement <8 x i16> %ins4, i16   %a5, i32 5
332  %ins6 = insertelement <8 x i16> %ins5, i16     0, i32 6
333  %ins7 = insertelement <8 x i16> %ins6, i16     0, i32 7
334  ret <8 x i16> %ins7
335}
336
337define <16 x i8> @test_buildvector_v16i8_register(i8 %a0, i8 %a1, i8 %a2, i8 %a3, i8 %a4, i8 %a5, i8 %a6, i8 %a7, i8 %a8, i8 %a9, i8 %a10, i8 %a11, i8 %a12, i8 %a13, i8 %a14, i8 %a15) {
338; SSE2-LABEL: test_buildvector_v16i8_register:
339; SSE2:       # %bb.0:
340; SSE2-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
341; SSE2-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
342; SSE2-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]
343; SSE2-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
344; SSE2-NEXT:    movd {{.*#+}} xmm2 = mem[0],zero,zero,zero
345; SSE2-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]
346; SSE2-NEXT:    punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1],xmm2[2],xmm1[2],xmm2[3],xmm1[3]
347; SSE2-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
348; SSE2-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
349; SSE2-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]
350; SSE2-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
351; SSE2-NEXT:    movd {{.*#+}} xmm3 = mem[0],zero,zero,zero
352; SSE2-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]
353; SSE2-NEXT:    punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm1[0],xmm3[1],xmm1[1],xmm3[2],xmm1[2],xmm3[3],xmm1[3]
354; SSE2-NEXT:    punpckldq {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]
355; SSE2-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
356; SSE2-NEXT:    movd {{.*#+}} xmm1 = mem[0],zero,zero,zero
357; SSE2-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]
358; SSE2-NEXT:    movd %r9d, %xmm0
359; SSE2-NEXT:    movd %r8d, %xmm2
360; SSE2-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]
361; SSE2-NEXT:    punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1],xmm2[2],xmm1[2],xmm2[3],xmm1[3]
362; SSE2-NEXT:    movd %ecx, %xmm0
363; SSE2-NEXT:    movd %edx, %xmm1
364; SSE2-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]
365; SSE2-NEXT:    movd %esi, %xmm4
366; SSE2-NEXT:    movd %edi, %xmm0
367; SSE2-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]
368; SSE2-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1],xmm0[2],xmm1[2],xmm0[3],xmm1[3]
369; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
370; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm3[0]
371; SSE2-NEXT:    retq
372;
373; SSE41-LABEL: test_buildvector_v16i8_register:
374; SSE41:       # %bb.0:
375; SSE41-NEXT:    movd %edi, %xmm0
376; SSE41-NEXT:    pinsrb $1, %esi, %xmm0
377; SSE41-NEXT:    pinsrb $2, %edx, %xmm0
378; SSE41-NEXT:    pinsrb $3, %ecx, %xmm0
379; SSE41-NEXT:    pinsrb $4, %r8d, %xmm0
380; SSE41-NEXT:    pinsrb $5, %r9d, %xmm0
381; SSE41-NEXT:    pinsrb $6, {{[0-9]+}}(%rsp), %xmm0
382; SSE41-NEXT:    pinsrb $7, {{[0-9]+}}(%rsp), %xmm0
383; SSE41-NEXT:    pinsrb $8, {{[0-9]+}}(%rsp), %xmm0
384; SSE41-NEXT:    pinsrb $9, {{[0-9]+}}(%rsp), %xmm0
385; SSE41-NEXT:    pinsrb $10, {{[0-9]+}}(%rsp), %xmm0
386; SSE41-NEXT:    pinsrb $11, {{[0-9]+}}(%rsp), %xmm0
387; SSE41-NEXT:    pinsrb $12, {{[0-9]+}}(%rsp), %xmm0
388; SSE41-NEXT:    pinsrb $13, {{[0-9]+}}(%rsp), %xmm0
389; SSE41-NEXT:    pinsrb $14, {{[0-9]+}}(%rsp), %xmm0
390; SSE41-NEXT:    pinsrb $15, {{[0-9]+}}(%rsp), %xmm0
391; SSE41-NEXT:    retq
392  %ins0  = insertelement <16 x i8> undef,  i8 %a0,  i32 0
393  %ins1  = insertelement <16 x i8> %ins0,  i8 %a1,  i32 1
394  %ins2  = insertelement <16 x i8> %ins1,  i8 %a2,  i32 2
395  %ins3  = insertelement <16 x i8> %ins2,  i8 %a3,  i32 3
396  %ins4  = insertelement <16 x i8> %ins3,  i8 %a4,  i32 4
397  %ins5  = insertelement <16 x i8> %ins4,  i8 %a5,  i32 5
398  %ins6  = insertelement <16 x i8> %ins5,  i8 %a6,  i32 6
399  %ins7  = insertelement <16 x i8> %ins6,  i8 %a7,  i32 7
400  %ins8  = insertelement <16 x i8> %ins7,  i8 %a8,  i32 8
401  %ins9  = insertelement <16 x i8> %ins8,  i8 %a9,  i32 9
402  %ins10 = insertelement <16 x i8> %ins9,  i8 %a10, i32 10
403  %ins11 = insertelement <16 x i8> %ins10, i8 %a11, i32 11
404  %ins12 = insertelement <16 x i8> %ins11, i8 %a12, i32 12
405  %ins13 = insertelement <16 x i8> %ins12, i8 %a13, i32 13
406  %ins14 = insertelement <16 x i8> %ins13, i8 %a14, i32 14
407  %ins15 = insertelement <16 x i8> %ins14, i8 %a15, i32 15
408  ret <16 x i8> %ins15
409}
410
411define <16 x i8> @test_buildvector_v16i8_partial(i8 %a2, i8 %a6, i8 %a8, i8 %a11, i8 %a12, i8 %a15) {
412; SSE2-LABEL: test_buildvector_v16i8_partial:
413; SSE2:       # %bb.0:
414; SSE2-NEXT:    pxor %xmm0, %xmm0
415; SSE2-NEXT:    pinsrw $1, %edi, %xmm0
416; SSE2-NEXT:    pinsrw $3, %esi, %xmm0
417; SSE2-NEXT:    pinsrw $4, %edx, %xmm0
418; SSE2-NEXT:    shll $8, %ecx
419; SSE2-NEXT:    pinsrw $5, %ecx, %xmm0
420; SSE2-NEXT:    pinsrw $6, %r8d, %xmm0
421; SSE2-NEXT:    shll $8, %r9d
422; SSE2-NEXT:    pinsrw $7, %r9d, %xmm0
423; SSE2-NEXT:    retq
424;
425; SSE41-LABEL: test_buildvector_v16i8_partial:
426; SSE41:       # %bb.0:
427; SSE41-NEXT:    pxor %xmm0, %xmm0
428; SSE41-NEXT:    pinsrb $2, %edi, %xmm0
429; SSE41-NEXT:    pinsrb $6, %esi, %xmm0
430; SSE41-NEXT:    pinsrb $8, %edx, %xmm0
431; SSE41-NEXT:    pinsrb $11, %ecx, %xmm0
432; SSE41-NEXT:    pinsrb $12, %r8d, %xmm0
433; SSE41-NEXT:    pinsrb $15, %r9d, %xmm0
434; SSE41-NEXT:    retq
435  %ins0  = insertelement <16 x i8> undef,  i8 undef, i32 0
436  %ins1  = insertelement <16 x i8> %ins0,  i8 undef, i32 1
437  %ins2  = insertelement <16 x i8> %ins1,  i8   %a2, i32 2
438  %ins3  = insertelement <16 x i8> %ins2,  i8 undef, i32 3
439  %ins4  = insertelement <16 x i8> %ins3,  i8 undef, i32 4
440  %ins5  = insertelement <16 x i8> %ins4,  i8 undef, i32 5
441  %ins6  = insertelement <16 x i8> %ins5,  i8   %a6, i32 6
442  %ins7  = insertelement <16 x i8> %ins6,  i8 undef, i32 7
443  %ins8  = insertelement <16 x i8> %ins7,  i8   %a8, i32 8
444  %ins9  = insertelement <16 x i8> %ins8,  i8 undef, i32 9
445  %ins10 = insertelement <16 x i8> %ins9,  i8 undef, i32 10
446  %ins11 = insertelement <16 x i8> %ins10, i8  %a11, i32 11
447  %ins12 = insertelement <16 x i8> %ins11, i8  %a12, i32 12
448  %ins13 = insertelement <16 x i8> %ins12, i8 undef, i32 13
449  %ins14 = insertelement <16 x i8> %ins13, i8 undef, i32 14
450  %ins15 = insertelement <16 x i8> %ins14, i8  %a15, i32 15
451  ret <16 x i8> %ins15
452}
453
454define <16 x i8> @test_buildvector_v16i8_register_zero(i8 %a0, i8 %a4, i8 %a6, i8 %a8, i8 %a11, i8 %a12, i8 %a15) {
455; SSE2-LABEL: test_buildvector_v16i8_register_zero:
456; SSE2:       # %bb.0:
457; SSE2-NEXT:    movzbl %sil, %eax
458; SSE2-NEXT:    movzbl %dil, %esi
459; SSE2-NEXT:    movd %esi, %xmm0
460; SSE2-NEXT:    pinsrw $2, %eax, %xmm0
461; SSE2-NEXT:    movzbl %dl, %eax
462; SSE2-NEXT:    pinsrw $3, %eax, %xmm0
463; SSE2-NEXT:    movzbl %cl, %eax
464; SSE2-NEXT:    pinsrw $4, %eax, %xmm0
465; SSE2-NEXT:    shll $8, %r8d
466; SSE2-NEXT:    pinsrw $5, %r8d, %xmm0
467; SSE2-NEXT:    movzbl %r9b, %eax
468; SSE2-NEXT:    pinsrw $6, %eax, %xmm0
469; SSE2-NEXT:    movl {{[0-9]+}}(%rsp), %eax
470; SSE2-NEXT:    shll $8, %eax
471; SSE2-NEXT:    pinsrw $7, %eax, %xmm0
472; SSE2-NEXT:    retq
473;
474; SSE41-LABEL: test_buildvector_v16i8_register_zero:
475; SSE41:       # %bb.0:
476; SSE41-NEXT:    pxor %xmm0, %xmm0
477; SSE41-NEXT:    pinsrb $0, %edi, %xmm0
478; SSE41-NEXT:    pinsrb $4, %esi, %xmm0
479; SSE41-NEXT:    pinsrb $6, %edx, %xmm0
480; SSE41-NEXT:    pinsrb $8, %ecx, %xmm0
481; SSE41-NEXT:    pinsrb $11, %r8d, %xmm0
482; SSE41-NEXT:    pinsrb $12, %r9d, %xmm0
483; SSE41-NEXT:    pinsrb $15, {{[0-9]+}}(%rsp), %xmm0
484; SSE41-NEXT:    retq
485  %ins0  = insertelement <16 x i8> undef,  i8   %a0, i32 0
486  %ins1  = insertelement <16 x i8> %ins0,  i8     0, i32 1
487  %ins2  = insertelement <16 x i8> %ins1,  i8     0, i32 2
488  %ins3  = insertelement <16 x i8> %ins2,  i8     0, i32 3
489  %ins4  = insertelement <16 x i8> %ins3,  i8   %a4, i32 4
490  %ins5  = insertelement <16 x i8> %ins4,  i8     0, i32 5
491  %ins6  = insertelement <16 x i8> %ins5,  i8   %a6, i32 6
492  %ins7  = insertelement <16 x i8> %ins6,  i8     0, i32 7
493  %ins8  = insertelement <16 x i8> %ins7,  i8   %a8, i32 8
494  %ins9  = insertelement <16 x i8> %ins8,  i8     0, i32 9
495  %ins10 = insertelement <16 x i8> %ins9,  i8     0, i32 10
496  %ins11 = insertelement <16 x i8> %ins10, i8  %a11, i32 11
497  %ins12 = insertelement <16 x i8> %ins11, i8  %a12, i32 12
498  %ins13 = insertelement <16 x i8> %ins12, i8     0, i32 13
499  %ins14 = insertelement <16 x i8> %ins13, i8     0, i32 14
500  %ins15 = insertelement <16 x i8> %ins14, i8  %a15, i32 15
501  ret <16 x i8> %ins15
502}
503
504define <16 x i8> @test_buildvector_v16i8_register_zero_2(i8 %a2, i8 %a3, i8 %a6, i8 %a8, i8 %a11, i8 %a12, i8 %a15) {
505; SSE2-LABEL: test_buildvector_v16i8_register_zero_2:
506; SSE2:       # %bb.0:
507; SSE2-NEXT:    shll $8, %esi
508; SSE2-NEXT:    movzbl %dil, %eax
509; SSE2-NEXT:    orl %esi, %eax
510; SSE2-NEXT:    pxor %xmm0, %xmm0
511; SSE2-NEXT:    pinsrw $1, %eax, %xmm0
512; SSE2-NEXT:    movzbl %dl, %eax
513; SSE2-NEXT:    pinsrw $3, %eax, %xmm0
514; SSE2-NEXT:    movzbl %cl, %eax
515; SSE2-NEXT:    pinsrw $4, %eax, %xmm0
516; SSE2-NEXT:    shll $8, %r8d
517; SSE2-NEXT:    pinsrw $5, %r8d, %xmm0
518; SSE2-NEXT:    movzbl %r9b, %eax
519; SSE2-NEXT:    pinsrw $6, %eax, %xmm0
520; SSE2-NEXT:    movl {{[0-9]+}}(%rsp), %eax
521; SSE2-NEXT:    shll $8, %eax
522; SSE2-NEXT:    pinsrw $7, %eax, %xmm0
523; SSE2-NEXT:    retq
524;
525; SSE41-LABEL: test_buildvector_v16i8_register_zero_2:
526; SSE41:       # %bb.0:
527; SSE41-NEXT:    pxor %xmm0, %xmm0
528; SSE41-NEXT:    pinsrb $2, %edi, %xmm0
529; SSE41-NEXT:    pinsrb $3, %esi, %xmm0
530; SSE41-NEXT:    pinsrb $6, %edx, %xmm0
531; SSE41-NEXT:    pinsrb $8, %ecx, %xmm0
532; SSE41-NEXT:    pinsrb $11, %r8d, %xmm0
533; SSE41-NEXT:    pinsrb $12, %r9d, %xmm0
534; SSE41-NEXT:    pinsrb $15, {{[0-9]+}}(%rsp), %xmm0
535; SSE41-NEXT:    retq
536  %ins0  = insertelement <16 x i8> undef,  i8     0, i32 0
537  %ins1  = insertelement <16 x i8> %ins0,  i8     0, i32 1
538  %ins2  = insertelement <16 x i8> %ins1,  i8   %a2, i32 2
539  %ins3  = insertelement <16 x i8> %ins2,  i8   %a3, i32 3
540  %ins4  = insertelement <16 x i8> %ins3,  i8     0, i32 4
541  %ins5  = insertelement <16 x i8> %ins4,  i8     0, i32 5
542  %ins6  = insertelement <16 x i8> %ins5,  i8   %a6, i32 6
543  %ins7  = insertelement <16 x i8> %ins6,  i8     0, i32 7
544  %ins8  = insertelement <16 x i8> %ins7,  i8   %a8, i32 8
545  %ins9  = insertelement <16 x i8> %ins8,  i8     0, i32 9
546  %ins10 = insertelement <16 x i8> %ins9,  i8     0, i32 10
547  %ins11 = insertelement <16 x i8> %ins10, i8  %a11, i32 11
548  %ins12 = insertelement <16 x i8> %ins11, i8  %a12, i32 12
549  %ins13 = insertelement <16 x i8> %ins12, i8     0, i32 13
550  %ins14 = insertelement <16 x i8> %ins13, i8     0, i32 14
551  %ins15 = insertelement <16 x i8> %ins14, i8  %a15, i32 15
552  ret <16 x i8> %ins15
553}
554
555; OSS-Fuzz #5688
556; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=5688
557define <4 x i32> @ossfuzz5688(i32 %a0) {
558; CHECK-LABEL: ossfuzz5688:
559; CHECK:       # %bb.0:
560; CHECK-NEXT:    retq
561  %1 = insertelement <4 x i32> zeroinitializer, i32 -2147483648, i32 %a0
562  %2 = extractelement <4 x i32> %1, i32 %a0
563  %3 = extractelement <4 x i32> <i32 30, i32 53, i32 42, i32 12>, i32 %2
564  %4 = extractelement <4 x i32> zeroinitializer, i32 %2
565  %5 = insertelement <4 x i32> undef, i32 %3, i32 undef
566  store i32 %4, i32* undef
567  ret <4 x i32> %5
568}
569