[ARM] Adjust how NEON shifts are lowered
[llvm-core.git] / test / CodeGen / X86 / haddsub-2.ll
blobc4d470a6cd69ef975eb86fc35840f227317a5296
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+sse2,+sse3 | FileCheck %s --check-prefix=SSE --check-prefix=SSE3
3 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+sse2,+sse3,+ssse3 | FileCheck %s --check-prefix=SSE --check-prefix=SSSE3
4 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX1
5 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx2 | FileCheck %s --check-prefix=AVX --check-prefix=AVX2
7 define <4 x float> @hadd_ps_test1(<4 x float> %A, <4 x float> %B) {
8 ; SSE-LABEL: hadd_ps_test1:
9 ; SSE:       # %bb.0:
10 ; SSE-NEXT:    haddps %xmm1, %xmm0
11 ; SSE-NEXT:    retq
13 ; AVX-LABEL: hadd_ps_test1:
14 ; AVX:       # %bb.0:
15 ; AVX-NEXT:    vhaddps %xmm1, %xmm0, %xmm0
16 ; AVX-NEXT:    retq
17   %vecext = extractelement <4 x float> %A, i32 0
18   %vecext1 = extractelement <4 x float> %A, i32 1
19   %add = fadd float %vecext, %vecext1
20   %vecinit = insertelement <4 x float> undef, float %add, i32 0
21   %vecext2 = extractelement <4 x float> %A, i32 2
22   %vecext3 = extractelement <4 x float> %A, i32 3
23   %add4 = fadd float %vecext2, %vecext3
24   %vecinit5 = insertelement <4 x float> %vecinit, float %add4, i32 1
25   %vecext6 = extractelement <4 x float> %B, i32 0
26   %vecext7 = extractelement <4 x float> %B, i32 1
27   %add8 = fadd float %vecext6, %vecext7
28   %vecinit9 = insertelement <4 x float> %vecinit5, float %add8, i32 2
29   %vecext10 = extractelement <4 x float> %B, i32 2
30   %vecext11 = extractelement <4 x float> %B, i32 3
31   %add12 = fadd float %vecext10, %vecext11
32   %vecinit13 = insertelement <4 x float> %vecinit9, float %add12, i32 3
33   ret <4 x float> %vecinit13
36 define <4 x float> @hadd_ps_test2(<4 x float> %A, <4 x float> %B) {
37 ; SSE-LABEL: hadd_ps_test2:
38 ; SSE:       # %bb.0:
39 ; SSE-NEXT:    haddps %xmm1, %xmm0
40 ; SSE-NEXT:    retq
42 ; AVX-LABEL: hadd_ps_test2:
43 ; AVX:       # %bb.0:
44 ; AVX-NEXT:    vhaddps %xmm1, %xmm0, %xmm0
45 ; AVX-NEXT:    retq
46   %vecext = extractelement <4 x float> %A, i32 2
47   %vecext1 = extractelement <4 x float> %A, i32 3
48   %add = fadd float %vecext, %vecext1
49   %vecinit = insertelement <4 x float> undef, float %add, i32 1
50   %vecext2 = extractelement <4 x float> %A, i32 0
51   %vecext3 = extractelement <4 x float> %A, i32 1
52   %add4 = fadd float %vecext2, %vecext3
53   %vecinit5 = insertelement <4 x float> %vecinit, float %add4, i32 0
54   %vecext6 = extractelement <4 x float> %B, i32 2
55   %vecext7 = extractelement <4 x float> %B, i32 3
56   %add8 = fadd float %vecext6, %vecext7
57   %vecinit9 = insertelement <4 x float> %vecinit5, float %add8, i32 3
58   %vecext10 = extractelement <4 x float> %B, i32 0
59   %vecext11 = extractelement <4 x float> %B, i32 1
60   %add12 = fadd float %vecext10, %vecext11
61   %vecinit13 = insertelement <4 x float> %vecinit9, float %add12, i32 2
62   ret <4 x float> %vecinit13
65 define <4 x float> @hsub_ps_test1(<4 x float> %A, <4 x float> %B) {
66 ; SSE-LABEL: hsub_ps_test1:
67 ; SSE:       # %bb.0:
68 ; SSE-NEXT:    hsubps %xmm1, %xmm0
69 ; SSE-NEXT:    retq
71 ; AVX-LABEL: hsub_ps_test1:
72 ; AVX:       # %bb.0:
73 ; AVX-NEXT:    vhsubps %xmm1, %xmm0, %xmm0
74 ; AVX-NEXT:    retq
75   %vecext = extractelement <4 x float> %A, i32 0
76   %vecext1 = extractelement <4 x float> %A, i32 1
77   %sub = fsub float %vecext, %vecext1
78   %vecinit = insertelement <4 x float> undef, float %sub, i32 0
79   %vecext2 = extractelement <4 x float> %A, i32 2
80   %vecext3 = extractelement <4 x float> %A, i32 3
81   %sub4 = fsub float %vecext2, %vecext3
82   %vecinit5 = insertelement <4 x float> %vecinit, float %sub4, i32 1
83   %vecext6 = extractelement <4 x float> %B, i32 0
84   %vecext7 = extractelement <4 x float> %B, i32 1
85   %sub8 = fsub float %vecext6, %vecext7
86   %vecinit9 = insertelement <4 x float> %vecinit5, float %sub8, i32 2
87   %vecext10 = extractelement <4 x float> %B, i32 2
88   %vecext11 = extractelement <4 x float> %B, i32 3
89   %sub12 = fsub float %vecext10, %vecext11
90   %vecinit13 = insertelement <4 x float> %vecinit9, float %sub12, i32 3
91   ret <4 x float> %vecinit13
94 define <4 x float> @hsub_ps_test2(<4 x float> %A, <4 x float> %B) {
95 ; SSE-LABEL: hsub_ps_test2:
96 ; SSE:       # %bb.0:
97 ; SSE-NEXT:    hsubps %xmm1, %xmm0
98 ; SSE-NEXT:    retq
100 ; AVX-LABEL: hsub_ps_test2:
101 ; AVX:       # %bb.0:
102 ; AVX-NEXT:    vhsubps %xmm1, %xmm0, %xmm0
103 ; AVX-NEXT:    retq
104   %vecext = extractelement <4 x float> %A, i32 2
105   %vecext1 = extractelement <4 x float> %A, i32 3
106   %sub = fsub float %vecext, %vecext1
107   %vecinit = insertelement <4 x float> undef, float %sub, i32 1
108   %vecext2 = extractelement <4 x float> %A, i32 0
109   %vecext3 = extractelement <4 x float> %A, i32 1
110   %sub4 = fsub float %vecext2, %vecext3
111   %vecinit5 = insertelement <4 x float> %vecinit, float %sub4, i32 0
112   %vecext6 = extractelement <4 x float> %B, i32 2
113   %vecext7 = extractelement <4 x float> %B, i32 3
114   %sub8 = fsub float %vecext6, %vecext7
115   %vecinit9 = insertelement <4 x float> %vecinit5, float %sub8, i32 3
116   %vecext10 = extractelement <4 x float> %B, i32 0
117   %vecext11 = extractelement <4 x float> %B, i32 1
118   %sub12 = fsub float %vecext10, %vecext11
119   %vecinit13 = insertelement <4 x float> %vecinit9, float %sub12, i32 2
120   ret <4 x float> %vecinit13
123 define <4 x i32> @phadd_d_test1(<4 x i32> %A, <4 x i32> %B) {
124 ; SSE3-LABEL: phadd_d_test1:
125 ; SSE3:       # %bb.0:
126 ; SSE3-NEXT:    movd %xmm0, %eax
127 ; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[1,1,2,3]
128 ; SSE3-NEXT:    movd %xmm2, %ecx
129 ; SSE3-NEXT:    addl %eax, %ecx
130 ; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,0,1]
131 ; SSE3-NEXT:    movd %xmm2, %eax
132 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[3,1,2,3]
133 ; SSE3-NEXT:    movd %xmm0, %edx
134 ; SSE3-NEXT:    addl %eax, %edx
135 ; SSE3-NEXT:    movd %xmm1, %eax
136 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,2,3]
137 ; SSE3-NEXT:    movd %xmm0, %esi
138 ; SSE3-NEXT:    addl %eax, %esi
139 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[2,3,0,1]
140 ; SSE3-NEXT:    movd %xmm0, %eax
141 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[3,1,2,3]
142 ; SSE3-NEXT:    movd %xmm0, %edi
143 ; SSE3-NEXT:    addl %eax, %edi
144 ; SSE3-NEXT:    movd %edi, %xmm0
145 ; SSE3-NEXT:    movd %esi, %xmm1
146 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
147 ; SSE3-NEXT:    movd %edx, %xmm2
148 ; SSE3-NEXT:    movd %ecx, %xmm0
149 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
150 ; SSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
151 ; SSE3-NEXT:    retq
153 ; SSSE3-LABEL: phadd_d_test1:
154 ; SSSE3:       # %bb.0:
155 ; SSSE3-NEXT:    phaddd %xmm1, %xmm0
156 ; SSSE3-NEXT:    retq
158 ; AVX-LABEL: phadd_d_test1:
159 ; AVX:       # %bb.0:
160 ; AVX-NEXT:    vphaddd %xmm1, %xmm0, %xmm0
161 ; AVX-NEXT:    retq
162   %vecext = extractelement <4 x i32> %A, i32 0
163   %vecext1 = extractelement <4 x i32> %A, i32 1
164   %add = add i32 %vecext, %vecext1
165   %vecinit = insertelement <4 x i32> undef, i32 %add, i32 0
166   %vecext2 = extractelement <4 x i32> %A, i32 2
167   %vecext3 = extractelement <4 x i32> %A, i32 3
168   %add4 = add i32 %vecext2, %vecext3
169   %vecinit5 = insertelement <4 x i32> %vecinit, i32 %add4, i32 1
170   %vecext6 = extractelement <4 x i32> %B, i32 0
171   %vecext7 = extractelement <4 x i32> %B, i32 1
172   %add8 = add i32 %vecext6, %vecext7
173   %vecinit9 = insertelement <4 x i32> %vecinit5, i32 %add8, i32 2
174   %vecext10 = extractelement <4 x i32> %B, i32 2
175   %vecext11 = extractelement <4 x i32> %B, i32 3
176   %add12 = add i32 %vecext10, %vecext11
177   %vecinit13 = insertelement <4 x i32> %vecinit9, i32 %add12, i32 3
178   ret <4 x i32> %vecinit13
181 define <4 x i32> @phadd_d_test2(<4 x i32> %A, <4 x i32> %B) {
182 ; SSE3-LABEL: phadd_d_test2:
183 ; SSE3:       # %bb.0:
184 ; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,0,1]
185 ; SSE3-NEXT:    movd %xmm2, %eax
186 ; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[3,1,2,3]
187 ; SSE3-NEXT:    movd %xmm2, %ecx
188 ; SSE3-NEXT:    addl %eax, %ecx
189 ; SSE3-NEXT:    movd %xmm0, %eax
190 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
191 ; SSE3-NEXT:    movd %xmm0, %edx
192 ; SSE3-NEXT:    addl %eax, %edx
193 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[3,1,2,3]
194 ; SSE3-NEXT:    movd %xmm0, %eax
195 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[2,3,0,1]
196 ; SSE3-NEXT:    movd %xmm0, %esi
197 ; SSE3-NEXT:    addl %eax, %esi
198 ; SSE3-NEXT:    movd %esi, %xmm0
199 ; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[1,1,2,3]
200 ; SSE3-NEXT:    movd %xmm2, %eax
201 ; SSE3-NEXT:    movd %xmm1, %esi
202 ; SSE3-NEXT:    addl %eax, %esi
203 ; SSE3-NEXT:    movd %esi, %xmm1
204 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
205 ; SSE3-NEXT:    movd %ecx, %xmm2
206 ; SSE3-NEXT:    movd %edx, %xmm0
207 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
208 ; SSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
209 ; SSE3-NEXT:    retq
211 ; SSSE3-LABEL: phadd_d_test2:
212 ; SSSE3:       # %bb.0:
213 ; SSSE3-NEXT:    phaddd %xmm1, %xmm0
214 ; SSSE3-NEXT:    retq
216 ; AVX-LABEL: phadd_d_test2:
217 ; AVX:       # %bb.0:
218 ; AVX-NEXT:    vphaddd %xmm1, %xmm0, %xmm0
219 ; AVX-NEXT:    retq
220   %vecext = extractelement <4 x i32> %A, i32 2
221   %vecext1 = extractelement <4 x i32> %A, i32 3
222   %add = add i32 %vecext, %vecext1
223   %vecinit = insertelement <4 x i32> undef, i32 %add, i32 1
224   %vecext2 = extractelement <4 x i32> %A, i32 0
225   %vecext3 = extractelement <4 x i32> %A, i32 1
226   %add4 = add i32 %vecext2, %vecext3
227   %vecinit5 = insertelement <4 x i32> %vecinit, i32 %add4, i32 0
228   %vecext6 = extractelement <4 x i32> %B, i32 3
229   %vecext7 = extractelement <4 x i32> %B, i32 2
230   %add8 = add i32 %vecext6, %vecext7
231   %vecinit9 = insertelement <4 x i32> %vecinit5, i32 %add8, i32 3
232   %vecext10 = extractelement <4 x i32> %B, i32 1
233   %vecext11 = extractelement <4 x i32> %B, i32 0
234   %add12 = add i32 %vecext10, %vecext11
235   %vecinit13 = insertelement <4 x i32> %vecinit9, i32 %add12, i32 2
236   ret <4 x i32> %vecinit13
239 define <4 x i32> @phsub_d_test1(<4 x i32> %A, <4 x i32> %B) {
240 ; SSE3-LABEL: phsub_d_test1:
241 ; SSE3:       # %bb.0:
242 ; SSE3-NEXT:    movd %xmm0, %eax
243 ; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[1,1,2,3]
244 ; SSE3-NEXT:    movd %xmm2, %ecx
245 ; SSE3-NEXT:    subl %ecx, %eax
246 ; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,0,1]
247 ; SSE3-NEXT:    movd %xmm2, %ecx
248 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[3,1,2,3]
249 ; SSE3-NEXT:    movd %xmm0, %edx
250 ; SSE3-NEXT:    subl %edx, %ecx
251 ; SSE3-NEXT:    movd %xmm1, %edx
252 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,2,3]
253 ; SSE3-NEXT:    movd %xmm0, %esi
254 ; SSE3-NEXT:    subl %esi, %edx
255 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[2,3,0,1]
256 ; SSE3-NEXT:    movd %xmm0, %esi
257 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[3,1,2,3]
258 ; SSE3-NEXT:    movd %xmm0, %edi
259 ; SSE3-NEXT:    subl %edi, %esi
260 ; SSE3-NEXT:    movd %esi, %xmm0
261 ; SSE3-NEXT:    movd %edx, %xmm1
262 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
263 ; SSE3-NEXT:    movd %ecx, %xmm2
264 ; SSE3-NEXT:    movd %eax, %xmm0
265 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
266 ; SSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
267 ; SSE3-NEXT:    retq
269 ; SSSE3-LABEL: phsub_d_test1:
270 ; SSSE3:       # %bb.0:
271 ; SSSE3-NEXT:    phsubd %xmm1, %xmm0
272 ; SSSE3-NEXT:    retq
274 ; AVX-LABEL: phsub_d_test1:
275 ; AVX:       # %bb.0:
276 ; AVX-NEXT:    vphsubd %xmm1, %xmm0, %xmm0
277 ; AVX-NEXT:    retq
278   %vecext = extractelement <4 x i32> %A, i32 0
279   %vecext1 = extractelement <4 x i32> %A, i32 1
280   %sub = sub i32 %vecext, %vecext1
281   %vecinit = insertelement <4 x i32> undef, i32 %sub, i32 0
282   %vecext2 = extractelement <4 x i32> %A, i32 2
283   %vecext3 = extractelement <4 x i32> %A, i32 3
284   %sub4 = sub i32 %vecext2, %vecext3
285   %vecinit5 = insertelement <4 x i32> %vecinit, i32 %sub4, i32 1
286   %vecext6 = extractelement <4 x i32> %B, i32 0
287   %vecext7 = extractelement <4 x i32> %B, i32 1
288   %sub8 = sub i32 %vecext6, %vecext7
289   %vecinit9 = insertelement <4 x i32> %vecinit5, i32 %sub8, i32 2
290   %vecext10 = extractelement <4 x i32> %B, i32 2
291   %vecext11 = extractelement <4 x i32> %B, i32 3
292   %sub12 = sub i32 %vecext10, %vecext11
293   %vecinit13 = insertelement <4 x i32> %vecinit9, i32 %sub12, i32 3
294   ret <4 x i32> %vecinit13
297 define <4 x i32> @phsub_d_test2(<4 x i32> %A, <4 x i32> %B) {
298 ; SSE3-LABEL: phsub_d_test2:
299 ; SSE3:       # %bb.0:
300 ; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,0,1]
301 ; SSE3-NEXT:    movd %xmm2, %eax
302 ; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[3,1,2,3]
303 ; SSE3-NEXT:    movd %xmm2, %ecx
304 ; SSE3-NEXT:    subl %ecx, %eax
305 ; SSE3-NEXT:    movd %xmm0, %ecx
306 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
307 ; SSE3-NEXT:    movd %xmm0, %edx
308 ; SSE3-NEXT:    subl %edx, %ecx
309 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[2,3,0,1]
310 ; SSE3-NEXT:    movd %xmm0, %edx
311 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[3,1,2,3]
312 ; SSE3-NEXT:    movd %xmm0, %esi
313 ; SSE3-NEXT:    subl %esi, %edx
314 ; SSE3-NEXT:    movd %edx, %xmm0
315 ; SSE3-NEXT:    movd %xmm1, %edx
316 ; SSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,1,2,3]
317 ; SSE3-NEXT:    movd %xmm1, %esi
318 ; SSE3-NEXT:    subl %esi, %edx
319 ; SSE3-NEXT:    movd %edx, %xmm1
320 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
321 ; SSE3-NEXT:    movd %eax, %xmm2
322 ; SSE3-NEXT:    movd %ecx, %xmm0
323 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
324 ; SSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
325 ; SSE3-NEXT:    retq
327 ; SSSE3-LABEL: phsub_d_test2:
328 ; SSSE3:       # %bb.0:
329 ; SSSE3-NEXT:    phsubd %xmm1, %xmm0
330 ; SSSE3-NEXT:    retq
332 ; AVX-LABEL: phsub_d_test2:
333 ; AVX:       # %bb.0:
334 ; AVX-NEXT:    vphsubd %xmm1, %xmm0, %xmm0
335 ; AVX-NEXT:    retq
336   %vecext = extractelement <4 x i32> %A, i32 2
337   %vecext1 = extractelement <4 x i32> %A, i32 3
338   %sub = sub i32 %vecext, %vecext1
339   %vecinit = insertelement <4 x i32> undef, i32 %sub, i32 1
340   %vecext2 = extractelement <4 x i32> %A, i32 0
341   %vecext3 = extractelement <4 x i32> %A, i32 1
342   %sub4 = sub i32 %vecext2, %vecext3
343   %vecinit5 = insertelement <4 x i32> %vecinit, i32 %sub4, i32 0
344   %vecext6 = extractelement <4 x i32> %B, i32 2
345   %vecext7 = extractelement <4 x i32> %B, i32 3
346   %sub8 = sub i32 %vecext6, %vecext7
347   %vecinit9 = insertelement <4 x i32> %vecinit5, i32 %sub8, i32 3
348   %vecext10 = extractelement <4 x i32> %B, i32 0
349   %vecext11 = extractelement <4 x i32> %B, i32 1
350   %sub12 = sub i32 %vecext10, %vecext11
351   %vecinit13 = insertelement <4 x i32> %vecinit9, i32 %sub12, i32 2
352   ret <4 x i32> %vecinit13
355 define <2 x double> @hadd_pd_test1(<2 x double> %A, <2 x double> %B) {
356 ; SSE-LABEL: hadd_pd_test1:
357 ; SSE:       # %bb.0:
358 ; SSE-NEXT:    haddpd %xmm1, %xmm0
359 ; SSE-NEXT:    retq
361 ; AVX-LABEL: hadd_pd_test1:
362 ; AVX:       # %bb.0:
363 ; AVX-NEXT:    vhaddpd %xmm1, %xmm0, %xmm0
364 ; AVX-NEXT:    retq
365   %vecext = extractelement <2 x double> %A, i32 0
366   %vecext1 = extractelement <2 x double> %A, i32 1
367   %add = fadd double %vecext, %vecext1
368   %vecinit = insertelement <2 x double> undef, double %add, i32 0
369   %vecext2 = extractelement <2 x double> %B, i32 0
370   %vecext3 = extractelement <2 x double> %B, i32 1
371   %add2 = fadd double %vecext2, %vecext3
372   %vecinit2 = insertelement <2 x double> %vecinit, double %add2, i32 1
373   ret <2 x double> %vecinit2
376 define <2 x double> @hadd_pd_test2(<2 x double> %A, <2 x double> %B) {
377 ; SSE-LABEL: hadd_pd_test2:
378 ; SSE:       # %bb.0:
379 ; SSE-NEXT:    haddpd %xmm1, %xmm0
380 ; SSE-NEXT:    retq
382 ; AVX-LABEL: hadd_pd_test2:
383 ; AVX:       # %bb.0:
384 ; AVX-NEXT:    vhaddpd %xmm1, %xmm0, %xmm0
385 ; AVX-NEXT:    retq
386   %vecext = extractelement <2 x double> %A, i32 1
387   %vecext1 = extractelement <2 x double> %A, i32 0
388   %add = fadd double %vecext, %vecext1
389   %vecinit = insertelement <2 x double> undef, double %add, i32 0
390   %vecext2 = extractelement <2 x double> %B, i32 1
391   %vecext3 = extractelement <2 x double> %B, i32 0
392   %add2 = fadd double %vecext2, %vecext3
393   %vecinit2 = insertelement <2 x double> %vecinit, double %add2, i32 1
394   ret <2 x double> %vecinit2
397 define <2 x double> @hsub_pd_test1(<2 x double> %A, <2 x double> %B) {
398 ; SSE-LABEL: hsub_pd_test1:
399 ; SSE:       # %bb.0:
400 ; SSE-NEXT:    hsubpd %xmm1, %xmm0
401 ; SSE-NEXT:    retq
403 ; AVX-LABEL: hsub_pd_test1:
404 ; AVX:       # %bb.0:
405 ; AVX-NEXT:    vhsubpd %xmm1, %xmm0, %xmm0
406 ; AVX-NEXT:    retq
407   %vecext = extractelement <2 x double> %A, i32 0
408   %vecext1 = extractelement <2 x double> %A, i32 1
409   %sub = fsub double %vecext, %vecext1
410   %vecinit = insertelement <2 x double> undef, double %sub, i32 0
411   %vecext2 = extractelement <2 x double> %B, i32 0
412   %vecext3 = extractelement <2 x double> %B, i32 1
413   %sub2 = fsub double %vecext2, %vecext3
414   %vecinit2 = insertelement <2 x double> %vecinit, double %sub2, i32 1
415   ret <2 x double> %vecinit2
418 define <2 x double> @hsub_pd_test2(<2 x double> %A, <2 x double> %B) {
419 ; SSE-LABEL: hsub_pd_test2:
420 ; SSE:       # %bb.0:
421 ; SSE-NEXT:    hsubpd %xmm1, %xmm0
422 ; SSE-NEXT:    retq
424 ; AVX-LABEL: hsub_pd_test2:
425 ; AVX:       # %bb.0:
426 ; AVX-NEXT:    vhsubpd %xmm1, %xmm0, %xmm0
427 ; AVX-NEXT:    retq
428   %vecext = extractelement <2 x double> %B, i32 0
429   %vecext1 = extractelement <2 x double> %B, i32 1
430   %sub = fsub double %vecext, %vecext1
431   %vecinit = insertelement <2 x double> undef, double %sub, i32 1
432   %vecext2 = extractelement <2 x double> %A, i32 0
433   %vecext3 = extractelement <2 x double> %A, i32 1
434   %sub2 = fsub double %vecext2, %vecext3
435   %vecinit2 = insertelement <2 x double> %vecinit, double %sub2, i32 0
436   ret <2 x double> %vecinit2
439 define <4 x double> @avx_vhadd_pd_test(<4 x double> %A, <4 x double> %B) {
440 ; SSE-LABEL: avx_vhadd_pd_test:
441 ; SSE:       # %bb.0:
442 ; SSE-NEXT:    haddpd %xmm1, %xmm0
443 ; SSE-NEXT:    haddpd %xmm3, %xmm2
444 ; SSE-NEXT:    movapd %xmm2, %xmm1
445 ; SSE-NEXT:    retq
447 ; AVX-LABEL: avx_vhadd_pd_test:
448 ; AVX:       # %bb.0:
449 ; AVX-NEXT:    vextractf128 $1, %ymm1, %xmm2
450 ; AVX-NEXT:    vhaddpd %xmm2, %xmm1, %xmm1
451 ; AVX-NEXT:    vextractf128 $1, %ymm0, %xmm2
452 ; AVX-NEXT:    vhaddpd %xmm2, %xmm0, %xmm0
453 ; AVX-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
454 ; AVX-NEXT:    retq
455   %vecext = extractelement <4 x double> %A, i32 0
456   %vecext1 = extractelement <4 x double> %A, i32 1
457   %add = fadd double %vecext, %vecext1
458   %vecinit = insertelement <4 x double> undef, double %add, i32 0
459   %vecext2 = extractelement <4 x double> %A, i32 2
460   %vecext3 = extractelement <4 x double> %A, i32 3
461   %add4 = fadd double %vecext2, %vecext3
462   %vecinit5 = insertelement <4 x double> %vecinit, double %add4, i32 1
463   %vecext6 = extractelement <4 x double> %B, i32 0
464   %vecext7 = extractelement <4 x double> %B, i32 1
465   %add8 = fadd double %vecext6, %vecext7
466   %vecinit9 = insertelement <4 x double> %vecinit5, double %add8, i32 2
467   %vecext10 = extractelement <4 x double> %B, i32 2
468   %vecext11 = extractelement <4 x double> %B, i32 3
469   %add12 = fadd double %vecext10, %vecext11
470   %vecinit13 = insertelement <4 x double> %vecinit9, double %add12, i32 3
471   ret <4 x double> %vecinit13
474 define <4 x double> @avx_vhsub_pd_test(<4 x double> %A, <4 x double> %B) {
475 ; SSE-LABEL: avx_vhsub_pd_test:
476 ; SSE:       # %bb.0:
477 ; SSE-NEXT:    hsubpd %xmm1, %xmm0
478 ; SSE-NEXT:    hsubpd %xmm3, %xmm2
479 ; SSE-NEXT:    movapd %xmm2, %xmm1
480 ; SSE-NEXT:    retq
482 ; AVX-LABEL: avx_vhsub_pd_test:
483 ; AVX:       # %bb.0:
484 ; AVX-NEXT:    vextractf128 $1, %ymm1, %xmm2
485 ; AVX-NEXT:    vhsubpd %xmm2, %xmm1, %xmm1
486 ; AVX-NEXT:    vextractf128 $1, %ymm0, %xmm2
487 ; AVX-NEXT:    vhsubpd %xmm2, %xmm0, %xmm0
488 ; AVX-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
489 ; AVX-NEXT:    retq
490   %vecext = extractelement <4 x double> %A, i32 0
491   %vecext1 = extractelement <4 x double> %A, i32 1
492   %sub = fsub double %vecext, %vecext1
493   %vecinit = insertelement <4 x double> undef, double %sub, i32 0
494   %vecext2 = extractelement <4 x double> %A, i32 2
495   %vecext3 = extractelement <4 x double> %A, i32 3
496   %sub4 = fsub double %vecext2, %vecext3
497   %vecinit5 = insertelement <4 x double> %vecinit, double %sub4, i32 1
498   %vecext6 = extractelement <4 x double> %B, i32 0
499   %vecext7 = extractelement <4 x double> %B, i32 1
500   %sub8 = fsub double %vecext6, %vecext7
501   %vecinit9 = insertelement <4 x double> %vecinit5, double %sub8, i32 2
502   %vecext10 = extractelement <4 x double> %B, i32 2
503   %vecext11 = extractelement <4 x double> %B, i32 3
504   %sub12 = fsub double %vecext10, %vecext11
505   %vecinit13 = insertelement <4 x double> %vecinit9, double %sub12, i32 3
506   ret <4 x double> %vecinit13
509 define <8 x i32> @avx2_vphadd_d_test(<8 x i32> %A, <8 x i32> %B) {
510 ; SSE3-LABEL: avx2_vphadd_d_test:
511 ; SSE3:       # %bb.0:
512 ; SSE3-NEXT:    movd %xmm0, %ecx
513 ; SSE3-NEXT:    pshufd {{.*#+}} xmm4 = xmm0[1,1,2,3]
514 ; SSE3-NEXT:    movd %xmm4, %r8d
515 ; SSE3-NEXT:    addl %ecx, %r8d
516 ; SSE3-NEXT:    pshufd {{.*#+}} xmm4 = xmm0[2,3,0,1]
517 ; SSE3-NEXT:    movd %xmm4, %edx
518 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[3,1,2,3]
519 ; SSE3-NEXT:    movd %xmm0, %r9d
520 ; SSE3-NEXT:    addl %edx, %r9d
521 ; SSE3-NEXT:    movd %xmm1, %edx
522 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,2,3]
523 ; SSE3-NEXT:    movd %xmm0, %esi
524 ; SSE3-NEXT:    addl %edx, %esi
525 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[2,3,0,1]
526 ; SSE3-NEXT:    movd %xmm0, %edx
527 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[3,1,2,3]
528 ; SSE3-NEXT:    movd %xmm0, %edi
529 ; SSE3-NEXT:    addl %edx, %edi
530 ; SSE3-NEXT:    movd %xmm2, %eax
531 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[1,1,2,3]
532 ; SSE3-NEXT:    movd %xmm0, %r10d
533 ; SSE3-NEXT:    addl %eax, %r10d
534 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[2,3,0,1]
535 ; SSE3-NEXT:    movd %xmm0, %eax
536 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[3,1,2,3]
537 ; SSE3-NEXT:    movd %xmm0, %ecx
538 ; SSE3-NEXT:    addl %eax, %ecx
539 ; SSE3-NEXT:    movd %xmm3, %eax
540 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[1,1,2,3]
541 ; SSE3-NEXT:    movd %xmm0, %edx
542 ; SSE3-NEXT:    addl %eax, %edx
543 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[2,3,0,1]
544 ; SSE3-NEXT:    movd %xmm0, %r11d
545 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[3,1,2,3]
546 ; SSE3-NEXT:    movd %xmm0, %eax
547 ; SSE3-NEXT:    addl %r11d, %eax
548 ; SSE3-NEXT:    movd %edi, %xmm0
549 ; SSE3-NEXT:    movd %esi, %xmm1
550 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
551 ; SSE3-NEXT:    movd %r9d, %xmm2
552 ; SSE3-NEXT:    movd %r8d, %xmm0
553 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
554 ; SSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
555 ; SSE3-NEXT:    movd %eax, %xmm1
556 ; SSE3-NEXT:    movd %edx, %xmm2
557 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
558 ; SSE3-NEXT:    movd %ecx, %xmm3
559 ; SSE3-NEXT:    movd %r10d, %xmm1
560 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
561 ; SSE3-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]
562 ; SSE3-NEXT:    retq
564 ; SSSE3-LABEL: avx2_vphadd_d_test:
565 ; SSSE3:       # %bb.0:
566 ; SSSE3-NEXT:    phaddd %xmm1, %xmm0
567 ; SSSE3-NEXT:    phaddd %xmm3, %xmm2
568 ; SSSE3-NEXT:    movdqa %xmm2, %xmm1
569 ; SSSE3-NEXT:    retq
571 ; AVX1-LABEL: avx2_vphadd_d_test:
572 ; AVX1:       # %bb.0:
573 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
574 ; AVX1-NEXT:    vphaddd %xmm2, %xmm1, %xmm1
575 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
576 ; AVX1-NEXT:    vphaddd %xmm2, %xmm0, %xmm0
577 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
578 ; AVX1-NEXT:    retq
580 ; AVX2-LABEL: avx2_vphadd_d_test:
581 ; AVX2:       # %bb.0:
582 ; AVX2-NEXT:    vextracti128 $1, %ymm1, %xmm2
583 ; AVX2-NEXT:    vphaddd %xmm2, %xmm1, %xmm1
584 ; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm2
585 ; AVX2-NEXT:    vphaddd %xmm2, %xmm0, %xmm0
586 ; AVX2-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
587 ; AVX2-NEXT:    retq
588   %vecext = extractelement <8 x i32> %A, i32 0
589   %vecext1 = extractelement <8 x i32> %A, i32 1
590   %add = add i32 %vecext, %vecext1
591   %vecinit = insertelement <8 x i32> undef, i32 %add, i32 0
592   %vecext2 = extractelement <8 x i32> %A, i32 2
593   %vecext3 = extractelement <8 x i32> %A, i32 3
594   %add4 = add i32 %vecext2, %vecext3
595   %vecinit5 = insertelement <8 x i32> %vecinit, i32 %add4, i32 1
596   %vecext6 = extractelement <8 x i32> %A, i32 4
597   %vecext7 = extractelement <8 x i32> %A, i32 5
598   %add8 = add i32 %vecext6, %vecext7
599   %vecinit9 = insertelement <8 x i32> %vecinit5, i32 %add8, i32 2
600   %vecext10 = extractelement <8 x i32> %A, i32 6
601   %vecext11 = extractelement <8 x i32> %A, i32 7
602   %add12 = add i32 %vecext10, %vecext11
603   %vecinit13 = insertelement <8 x i32> %vecinit9, i32 %add12, i32 3
604   %vecext14 = extractelement <8 x i32> %B, i32 0
605   %vecext15 = extractelement <8 x i32> %B, i32 1
606   %add16 = add i32 %vecext14, %vecext15
607   %vecinit17 = insertelement <8 x i32> %vecinit13, i32 %add16, i32 4
608   %vecext18 = extractelement <8 x i32> %B, i32 2
609   %vecext19 = extractelement <8 x i32> %B, i32 3
610   %add20 = add i32 %vecext18, %vecext19
611   %vecinit21 = insertelement <8 x i32> %vecinit17, i32 %add20, i32 5
612   %vecext22 = extractelement <8 x i32> %B, i32 4
613   %vecext23 = extractelement <8 x i32> %B, i32 5
614   %add24 = add i32 %vecext22, %vecext23
615   %vecinit25 = insertelement <8 x i32> %vecinit21, i32 %add24, i32 6
616   %vecext26 = extractelement <8 x i32> %B, i32 6
617   %vecext27 = extractelement <8 x i32> %B, i32 7
618   %add28 = add i32 %vecext26, %vecext27
619   %vecinit29 = insertelement <8 x i32> %vecinit25, i32 %add28, i32 7
620   ret <8 x i32> %vecinit29
623 define <16 x i16> @avx2_vphadd_w_test(<16 x i16> %a, <16 x i16> %b) nounwind {
624 ; SSE3-LABEL: avx2_vphadd_w_test:
625 ; SSE3:       # %bb.0:
626 ; SSE3-NEXT:    pushq %rbp
627 ; SSE3-NEXT:    pushq %r15
628 ; SSE3-NEXT:    pushq %r14
629 ; SSE3-NEXT:    pushq %r13
630 ; SSE3-NEXT:    pushq %r12
631 ; SSE3-NEXT:    pushq %rbx
632 ; SSE3-NEXT:    movd %xmm0, %eax
633 ; SSE3-NEXT:    pextrw $1, %xmm0, %ecx
634 ; SSE3-NEXT:    addl %eax, %ecx
635 ; SSE3-NEXT:    movl %ecx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
636 ; SSE3-NEXT:    pextrw $2, %xmm0, %eax
637 ; SSE3-NEXT:    pextrw $3, %xmm0, %ecx
638 ; SSE3-NEXT:    addl %eax, %ecx
639 ; SSE3-NEXT:    movl %ecx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
640 ; SSE3-NEXT:    pextrw $4, %xmm0, %eax
641 ; SSE3-NEXT:    pextrw $5, %xmm0, %r11d
642 ; SSE3-NEXT:    addl %eax, %r11d
643 ; SSE3-NEXT:    pextrw $6, %xmm0, %eax
644 ; SSE3-NEXT:    pextrw $7, %xmm0, %r15d
645 ; SSE3-NEXT:    addl %eax, %r15d
646 ; SSE3-NEXT:    movd %xmm1, %eax
647 ; SSE3-NEXT:    pextrw $1, %xmm1, %r13d
648 ; SSE3-NEXT:    addl %eax, %r13d
649 ; SSE3-NEXT:    pextrw $2, %xmm1, %eax
650 ; SSE3-NEXT:    pextrw $3, %xmm1, %ebx
651 ; SSE3-NEXT:    addl %eax, %ebx
652 ; SSE3-NEXT:    pextrw $4, %xmm1, %eax
653 ; SSE3-NEXT:    pextrw $5, %xmm1, %r8d
654 ; SSE3-NEXT:    addl %eax, %r8d
655 ; SSE3-NEXT:    pextrw $6, %xmm1, %eax
656 ; SSE3-NEXT:    pextrw $7, %xmm1, %esi
657 ; SSE3-NEXT:    addl %eax, %esi
658 ; SSE3-NEXT:    movd %xmm2, %eax
659 ; SSE3-NEXT:    pextrw $1, %xmm2, %r10d
660 ; SSE3-NEXT:    addl %eax, %r10d
661 ; SSE3-NEXT:    pextrw $2, %xmm2, %eax
662 ; SSE3-NEXT:    pextrw $3, %xmm2, %r14d
663 ; SSE3-NEXT:    addl %eax, %r14d
664 ; SSE3-NEXT:    pextrw $4, %xmm2, %eax
665 ; SSE3-NEXT:    pextrw $5, %xmm2, %r12d
666 ; SSE3-NEXT:    addl %eax, %r12d
667 ; SSE3-NEXT:    pextrw $6, %xmm2, %eax
668 ; SSE3-NEXT:    pextrw $7, %xmm2, %r9d
669 ; SSE3-NEXT:    addl %eax, %r9d
670 ; SSE3-NEXT:    movd %xmm3, %eax
671 ; SSE3-NEXT:    pextrw $1, %xmm3, %ebp
672 ; SSE3-NEXT:    addl %eax, %ebp
673 ; SSE3-NEXT:    pextrw $2, %xmm3, %edx
674 ; SSE3-NEXT:    pextrw $3, %xmm3, %edi
675 ; SSE3-NEXT:    addl %edx, %edi
676 ; SSE3-NEXT:    pextrw $4, %xmm3, %edx
677 ; SSE3-NEXT:    pextrw $5, %xmm3, %ecx
678 ; SSE3-NEXT:    addl %edx, %ecx
679 ; SSE3-NEXT:    pextrw $6, %xmm3, %edx
680 ; SSE3-NEXT:    pextrw $7, %xmm3, %eax
681 ; SSE3-NEXT:    addl %edx, %eax
682 ; SSE3-NEXT:    movd %esi, %xmm8
683 ; SSE3-NEXT:    movd %r8d, %xmm3
684 ; SSE3-NEXT:    movd %ebx, %xmm9
685 ; SSE3-NEXT:    movd %r13d, %xmm4
686 ; SSE3-NEXT:    movd %r15d, %xmm10
687 ; SSE3-NEXT:    movd %r11d, %xmm7
688 ; SSE3-NEXT:    movd {{[-0-9]+}}(%r{{[sb]}}p), %xmm11 # 4-byte Folded Reload
689 ; SSE3-NEXT:    # xmm11 = mem[0],zero,zero,zero
690 ; SSE3-NEXT:    movd {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Folded Reload
691 ; SSE3-NEXT:    # xmm0 = mem[0],zero,zero,zero
692 ; SSE3-NEXT:    movd %eax, %xmm12
693 ; SSE3-NEXT:    movd %ecx, %xmm6
694 ; SSE3-NEXT:    movd %edi, %xmm13
695 ; SSE3-NEXT:    movd %ebp, %xmm5
696 ; SSE3-NEXT:    movd %r9d, %xmm14
697 ; SSE3-NEXT:    movd %r12d, %xmm2
698 ; SSE3-NEXT:    movd %r14d, %xmm15
699 ; SSE3-NEXT:    movd %r10d, %xmm1
700 ; SSE3-NEXT:    punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm8[0],xmm3[1],xmm8[1],xmm3[2],xmm8[2],xmm3[3],xmm8[3]
701 ; SSE3-NEXT:    punpcklwd {{.*#+}} xmm4 = xmm4[0],xmm9[0],xmm4[1],xmm9[1],xmm4[2],xmm9[2],xmm4[3],xmm9[3]
702 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm3[0],xmm4[1],xmm3[1]
703 ; SSE3-NEXT:    punpcklwd {{.*#+}} xmm7 = xmm7[0],xmm10[0],xmm7[1],xmm10[1],xmm7[2],xmm10[2],xmm7[3],xmm10[3]
704 ; SSE3-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm11[0],xmm0[1],xmm11[1],xmm0[2],xmm11[2],xmm0[3],xmm11[3]
705 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm7[0],xmm0[1],xmm7[1]
706 ; SSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm4[0]
707 ; SSE3-NEXT:    punpcklwd {{.*#+}} xmm6 = xmm6[0],xmm12[0],xmm6[1],xmm12[1],xmm6[2],xmm12[2],xmm6[3],xmm12[3]
708 ; SSE3-NEXT:    punpcklwd {{.*#+}} xmm5 = xmm5[0],xmm13[0],xmm5[1],xmm13[1],xmm5[2],xmm13[2],xmm5[3],xmm13[3]
709 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm5 = xmm5[0],xmm6[0],xmm5[1],xmm6[1]
710 ; SSE3-NEXT:    punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm14[0],xmm2[1],xmm14[1],xmm2[2],xmm14[2],xmm2[3],xmm14[3]
711 ; SSE3-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm15[0],xmm1[1],xmm15[1],xmm1[2],xmm15[2],xmm1[3],xmm15[3]
712 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
713 ; SSE3-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm5[0]
714 ; SSE3-NEXT:    popq %rbx
715 ; SSE3-NEXT:    popq %r12
716 ; SSE3-NEXT:    popq %r13
717 ; SSE3-NEXT:    popq %r14
718 ; SSE3-NEXT:    popq %r15
719 ; SSE3-NEXT:    popq %rbp
720 ; SSE3-NEXT:    retq
722 ; SSSE3-LABEL: avx2_vphadd_w_test:
723 ; SSSE3:       # %bb.0:
724 ; SSSE3-NEXT:    phaddw %xmm1, %xmm0
725 ; SSSE3-NEXT:    phaddw %xmm3, %xmm2
726 ; SSSE3-NEXT:    movdqa %xmm2, %xmm1
727 ; SSSE3-NEXT:    retq
729 ; AVX1-LABEL: avx2_vphadd_w_test:
730 ; AVX1:       # %bb.0:
731 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
732 ; AVX1-NEXT:    vphaddw %xmm2, %xmm1, %xmm1
733 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
734 ; AVX1-NEXT:    vphaddw %xmm2, %xmm0, %xmm0
735 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
736 ; AVX1-NEXT:    retq
738 ; AVX2-LABEL: avx2_vphadd_w_test:
739 ; AVX2:       # %bb.0:
740 ; AVX2-NEXT:    vextracti128 $1, %ymm1, %xmm2
741 ; AVX2-NEXT:    vphaddw %xmm2, %xmm1, %xmm1
742 ; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm2
743 ; AVX2-NEXT:    vphaddw %xmm2, %xmm0, %xmm0
744 ; AVX2-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
745 ; AVX2-NEXT:    retq
746   %vecext = extractelement <16 x i16> %a, i32 0
747   %vecext1 = extractelement <16 x i16> %a, i32 1
748   %add = add i16 %vecext, %vecext1
749   %vecinit = insertelement <16 x i16> undef, i16 %add, i32 0
750   %vecext4 = extractelement <16 x i16> %a, i32 2
751   %vecext6 = extractelement <16 x i16> %a, i32 3
752   %add8 = add i16 %vecext4, %vecext6
753   %vecinit10 = insertelement <16 x i16> %vecinit, i16 %add8, i32 1
754   %vecext11 = extractelement <16 x i16> %a, i32 4
755   %vecext13 = extractelement <16 x i16> %a, i32 5
756   %add15 = add i16 %vecext11, %vecext13
757   %vecinit17 = insertelement <16 x i16> %vecinit10, i16 %add15, i32 2
758   %vecext18 = extractelement <16 x i16> %a, i32 6
759   %vecext20 = extractelement <16 x i16> %a, i32 7
760   %add22 = add i16 %vecext18, %vecext20
761   %vecinit24 = insertelement <16 x i16> %vecinit17, i16 %add22, i32 3
762   %vecext25 = extractelement <16 x i16> %a, i32 8
763   %vecext27 = extractelement <16 x i16> %a, i32 9
764   %add29 = add i16 %vecext25, %vecext27
765   %vecinit31 = insertelement <16 x i16> %vecinit24, i16 %add29, i32 4
766   %vecext32 = extractelement <16 x i16> %a, i32 10
767   %vecext34 = extractelement <16 x i16> %a, i32 11
768   %add36 = add i16 %vecext32, %vecext34
769   %vecinit38 = insertelement <16 x i16> %vecinit31, i16 %add36, i32 5
770   %vecext39 = extractelement <16 x i16> %a, i32 12
771   %vecext41 = extractelement <16 x i16> %a, i32 13
772   %add43 = add i16 %vecext39, %vecext41
773   %vecinit45 = insertelement <16 x i16> %vecinit38, i16 %add43, i32 6
774   %vecext46 = extractelement <16 x i16> %a, i32 14
775   %vecext48 = extractelement <16 x i16> %a, i32 15
776   %add50 = add i16 %vecext46, %vecext48
777   %vecinit52 = insertelement <16 x i16> %vecinit45, i16 %add50, i32 7
778   %vecext53 = extractelement <16 x i16> %b, i32 0
779   %vecext55 = extractelement <16 x i16> %b, i32 1
780   %add57 = add i16 %vecext53, %vecext55
781   %vecinit59 = insertelement <16 x i16> %vecinit52, i16 %add57, i32 8
782   %vecext60 = extractelement <16 x i16> %b, i32 2
783   %vecext62 = extractelement <16 x i16> %b, i32 3
784   %add64 = add i16 %vecext60, %vecext62
785   %vecinit66 = insertelement <16 x i16> %vecinit59, i16 %add64, i32 9
786   %vecext67 = extractelement <16 x i16> %b, i32 4
787   %vecext69 = extractelement <16 x i16> %b, i32 5
788   %add71 = add i16 %vecext67, %vecext69
789   %vecinit73 = insertelement <16 x i16> %vecinit66, i16 %add71, i32 10
790   %vecext74 = extractelement <16 x i16> %b, i32 6
791   %vecext76 = extractelement <16 x i16> %b, i32 7
792   %add78 = add i16 %vecext74, %vecext76
793   %vecinit80 = insertelement <16 x i16> %vecinit73, i16 %add78, i32 11
794   %vecext81 = extractelement <16 x i16> %b, i32 8
795   %vecext83 = extractelement <16 x i16> %b, i32 9
796   %add85 = add i16 %vecext81, %vecext83
797   %vecinit87 = insertelement <16 x i16> %vecinit80, i16 %add85, i32 12
798   %vecext88 = extractelement <16 x i16> %b, i32 10
799   %vecext90 = extractelement <16 x i16> %b, i32 11
800   %add92 = add i16 %vecext88, %vecext90
801   %vecinit94 = insertelement <16 x i16> %vecinit87, i16 %add92, i32 13
802   %vecext95 = extractelement <16 x i16> %b, i32 12
803   %vecext97 = extractelement <16 x i16> %b, i32 13
804   %add99 = add i16 %vecext95, %vecext97
805   %vecinit101 = insertelement <16 x i16> %vecinit94, i16 %add99, i32 14
806   %vecext102 = extractelement <16 x i16> %b, i32 14
807   %vecext104 = extractelement <16 x i16> %b, i32 15
808   %add106 = add i16 %vecext102, %vecext104
809   %vecinit108 = insertelement <16 x i16> %vecinit101, i16 %add106, i32 15
810   ret <16 x i16> %vecinit108
813 ; Verify that we don't select horizontal subs in the following functions.
815 define <4 x i32> @not_a_hsub_1(<4 x i32> %A, <4 x i32> %B) {
816 ; SSE-LABEL: not_a_hsub_1:
817 ; SSE:       # %bb.0:
818 ; SSE-NEXT:    movd %xmm0, %eax
819 ; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[1,1,2,3]
820 ; SSE-NEXT:    movd %xmm2, %ecx
821 ; SSE-NEXT:    subl %ecx, %eax
822 ; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[2,3,0,1]
823 ; SSE-NEXT:    movd %xmm2, %ecx
824 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[3,1,2,3]
825 ; SSE-NEXT:    movd %xmm0, %edx
826 ; SSE-NEXT:    subl %edx, %ecx
827 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,2,3]
828 ; SSE-NEXT:    movd %xmm0, %edx
829 ; SSE-NEXT:    movd %xmm1, %esi
830 ; SSE-NEXT:    subl %esi, %edx
831 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[3,1,2,3]
832 ; SSE-NEXT:    movd %xmm0, %esi
833 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[2,3,0,1]
834 ; SSE-NEXT:    movd %xmm0, %edi
835 ; SSE-NEXT:    subl %edi, %esi
836 ; SSE-NEXT:    movd %esi, %xmm0
837 ; SSE-NEXT:    movd %edx, %xmm1
838 ; SSE-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
839 ; SSE-NEXT:    movd %ecx, %xmm2
840 ; SSE-NEXT:    movd %eax, %xmm0
841 ; SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
842 ; SSE-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
843 ; SSE-NEXT:    retq
845 ; AVX-LABEL: not_a_hsub_1:
846 ; AVX:       # %bb.0:
847 ; AVX-NEXT:    vmovd %xmm0, %eax
848 ; AVX-NEXT:    vpextrd $1, %xmm0, %ecx
849 ; AVX-NEXT:    subl %ecx, %eax
850 ; AVX-NEXT:    vpextrd $2, %xmm0, %ecx
851 ; AVX-NEXT:    vpextrd $3, %xmm0, %edx
852 ; AVX-NEXT:    subl %edx, %ecx
853 ; AVX-NEXT:    vpextrd $1, %xmm1, %edx
854 ; AVX-NEXT:    vmovd %xmm1, %esi
855 ; AVX-NEXT:    subl %esi, %edx
856 ; AVX-NEXT:    vpextrd $3, %xmm1, %esi
857 ; AVX-NEXT:    vpextrd $2, %xmm1, %edi
858 ; AVX-NEXT:    subl %edi, %esi
859 ; AVX-NEXT:    vmovd %eax, %xmm0
860 ; AVX-NEXT:    vpinsrd $1, %ecx, %xmm0, %xmm0
861 ; AVX-NEXT:    vpinsrd $2, %edx, %xmm0, %xmm0
862 ; AVX-NEXT:    vpinsrd $3, %esi, %xmm0, %xmm0
863 ; AVX-NEXT:    retq
864   %vecext = extractelement <4 x i32> %A, i32 0
865   %vecext1 = extractelement <4 x i32> %A, i32 1
866   %sub = sub i32 %vecext, %vecext1
867   %vecinit = insertelement <4 x i32> undef, i32 %sub, i32 0
868   %vecext2 = extractelement <4 x i32> %A, i32 2
869   %vecext3 = extractelement <4 x i32> %A, i32 3
870   %sub4 = sub i32 %vecext2, %vecext3
871   %vecinit5 = insertelement <4 x i32> %vecinit, i32 %sub4, i32 1
872   %vecext6 = extractelement <4 x i32> %B, i32 1
873   %vecext7 = extractelement <4 x i32> %B, i32 0
874   %sub8 = sub i32 %vecext6, %vecext7
875   %vecinit9 = insertelement <4 x i32> %vecinit5, i32 %sub8, i32 2
876   %vecext10 = extractelement <4 x i32> %B, i32 3
877   %vecext11 = extractelement <4 x i32> %B, i32 2
878   %sub12 = sub i32 %vecext10, %vecext11
879   %vecinit13 = insertelement <4 x i32> %vecinit9, i32 %sub12, i32 3
880   ret <4 x i32> %vecinit13
883 define <4 x float> @not_a_hsub_2(<4 x float> %A, <4 x float> %B) {
884 ; SSE-LABEL: not_a_hsub_2:
885 ; SSE:       # %bb.0:
886 ; SSE-NEXT:    movaps %xmm0, %xmm2
887 ; SSE-NEXT:    unpckhpd {{.*#+}} xmm2 = xmm2[1],xmm0[1]
888 ; SSE-NEXT:    movaps %xmm0, %xmm3
889 ; SSE-NEXT:    shufps {{.*#+}} xmm3 = xmm3[3,1],xmm0[2,3]
890 ; SSE-NEXT:    subss %xmm3, %xmm2
891 ; SSE-NEXT:    movshdup {{.*#+}} xmm3 = xmm0[1,1,3,3]
892 ; SSE-NEXT:    subss %xmm3, %xmm0
893 ; SSE-NEXT:    unpcklps {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
894 ; SSE-NEXT:    movaps %xmm1, %xmm2
895 ; SSE-NEXT:    shufps {{.*#+}} xmm2 = xmm2[3,1],xmm1[2,3]
896 ; SSE-NEXT:    movaps %xmm1, %xmm3
897 ; SSE-NEXT:    unpckhpd {{.*#+}} xmm3 = xmm3[1],xmm1[1]
898 ; SSE-NEXT:    subss %xmm3, %xmm2
899 ; SSE-NEXT:    movshdup {{.*#+}} xmm3 = xmm1[1,1,3,3]
900 ; SSE-NEXT:    subss %xmm3, %xmm1
901 ; SSE-NEXT:    unpcklps {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
902 ; SSE-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
903 ; SSE-NEXT:    retq
905 ; AVX-LABEL: not_a_hsub_2:
906 ; AVX:       # %bb.0:
907 ; AVX-NEXT:    vpermilpd {{.*#+}} xmm2 = xmm0[1,0]
908 ; AVX-NEXT:    vpermilps {{.*#+}} xmm3 = xmm0[3,1,2,3]
909 ; AVX-NEXT:    vsubss %xmm3, %xmm2, %xmm2
910 ; AVX-NEXT:    vmovshdup {{.*#+}} xmm3 = xmm0[1,1,3,3]
911 ; AVX-NEXT:    vsubss %xmm3, %xmm0, %xmm0
912 ; AVX-NEXT:    vinsertps {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[2,3]
913 ; AVX-NEXT:    vpermilps {{.*#+}} xmm2 = xmm1[3,1,2,3]
914 ; AVX-NEXT:    vpermilpd {{.*#+}} xmm3 = xmm1[1,0]
915 ; AVX-NEXT:    vsubss %xmm3, %xmm2, %xmm2
916 ; AVX-NEXT:    vmovshdup {{.*#+}} xmm3 = xmm1[1,1,3,3]
917 ; AVX-NEXT:    vsubss %xmm3, %xmm1, %xmm1
918 ; AVX-NEXT:    vinsertps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0],xmm0[3]
919 ; AVX-NEXT:    vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],xmm2[0]
920 ; AVX-NEXT:    retq
921   %vecext = extractelement <4 x float> %A, i32 2
922   %vecext1 = extractelement <4 x float> %A, i32 3
923   %sub = fsub float %vecext, %vecext1
924   %vecinit = insertelement <4 x float> undef, float %sub, i32 1
925   %vecext2 = extractelement <4 x float> %A, i32 0
926   %vecext3 = extractelement <4 x float> %A, i32 1
927   %sub4 = fsub float %vecext2, %vecext3
928   %vecinit5 = insertelement <4 x float> %vecinit, float %sub4, i32 0
929   %vecext6 = extractelement <4 x float> %B, i32 3
930   %vecext7 = extractelement <4 x float> %B, i32 2
931   %sub8 = fsub float %vecext6, %vecext7
932   %vecinit9 = insertelement <4 x float> %vecinit5, float %sub8, i32 3
933   %vecext10 = extractelement <4 x float> %B, i32 0
934   %vecext11 = extractelement <4 x float> %B, i32 1
935   %sub12 = fsub float %vecext10, %vecext11
936   %vecinit13 = insertelement <4 x float> %vecinit9, float %sub12, i32 2
937   ret <4 x float> %vecinit13
940 define <2 x double> @not_a_hsub_3(<2 x double> %A, <2 x double> %B) {
941 ; SSE-LABEL: not_a_hsub_3:
942 ; SSE:       # %bb.0:
943 ; SSE-NEXT:    movapd %xmm1, %xmm2
944 ; SSE-NEXT:    unpckhpd {{.*#+}} xmm2 = xmm2[1],xmm1[1]
945 ; SSE-NEXT:    subsd %xmm2, %xmm1
946 ; SSE-NEXT:    movapd %xmm0, %xmm2
947 ; SSE-NEXT:    unpckhpd {{.*#+}} xmm2 = xmm2[1],xmm0[1]
948 ; SSE-NEXT:    subsd %xmm0, %xmm2
949 ; SSE-NEXT:    unpcklpd {{.*#+}} xmm2 = xmm2[0],xmm1[0]
950 ; SSE-NEXT:    movapd %xmm2, %xmm0
951 ; SSE-NEXT:    retq
953 ; AVX-LABEL: not_a_hsub_3:
954 ; AVX:       # %bb.0:
955 ; AVX-NEXT:    vpermilpd {{.*#+}} xmm2 = xmm1[1,0]
956 ; AVX-NEXT:    vsubsd %xmm2, %xmm1, %xmm1
957 ; AVX-NEXT:    vpermilpd {{.*#+}} xmm2 = xmm0[1,0]
958 ; AVX-NEXT:    vsubsd %xmm0, %xmm2, %xmm0
959 ; AVX-NEXT:    vunpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0]
960 ; AVX-NEXT:    retq
961   %vecext = extractelement <2 x double> %B, i32 0
962   %vecext1 = extractelement <2 x double> %B, i32 1
963   %sub = fsub double %vecext, %vecext1
964   %vecinit = insertelement <2 x double> undef, double %sub, i32 1
965   %vecext2 = extractelement <2 x double> %A, i32 1
966   %vecext3 = extractelement <2 x double> %A, i32 0
967   %sub2 = fsub double %vecext2, %vecext3
968   %vecinit2 = insertelement <2 x double> %vecinit, double %sub2, i32 0
969   ret <2 x double> %vecinit2
972 ; Test AVX horizontal add/sub of packed single/double precision
973 ; floating point values from 256-bit vectors.
975 define <8 x float> @avx_vhadd_ps(<8 x float> %a, <8 x float> %b) {
976 ; SSE-LABEL: avx_vhadd_ps:
977 ; SSE:       # %bb.0:
978 ; SSE-NEXT:    haddps %xmm2, %xmm0
979 ; SSE-NEXT:    haddps %xmm3, %xmm1
980 ; SSE-NEXT:    retq
982 ; AVX-LABEL: avx_vhadd_ps:
983 ; AVX:       # %bb.0:
984 ; AVX-NEXT:    vhaddps %ymm1, %ymm0, %ymm0
985 ; AVX-NEXT:    retq
986   %vecext = extractelement <8 x float> %a, i32 0
987   %vecext1 = extractelement <8 x float> %a, i32 1
988   %add = fadd float %vecext, %vecext1
989   %vecinit = insertelement <8 x float> undef, float %add, i32 0
990   %vecext2 = extractelement <8 x float> %a, i32 2
991   %vecext3 = extractelement <8 x float> %a, i32 3
992   %add4 = fadd float %vecext2, %vecext3
993   %vecinit5 = insertelement <8 x float> %vecinit, float %add4, i32 1
994   %vecext6 = extractelement <8 x float> %b, i32 0
995   %vecext7 = extractelement <8 x float> %b, i32 1
996   %add8 = fadd float %vecext6, %vecext7
997   %vecinit9 = insertelement <8 x float> %vecinit5, float %add8, i32 2
998   %vecext10 = extractelement <8 x float> %b, i32 2
999   %vecext11 = extractelement <8 x float> %b, i32 3
1000   %add12 = fadd float %vecext10, %vecext11
1001   %vecinit13 = insertelement <8 x float> %vecinit9, float %add12, i32 3
1002   %vecext14 = extractelement <8 x float> %a, i32 4
1003   %vecext15 = extractelement <8 x float> %a, i32 5
1004   %add16 = fadd float %vecext14, %vecext15
1005   %vecinit17 = insertelement <8 x float> %vecinit13, float %add16, i32 4
1006   %vecext18 = extractelement <8 x float> %a, i32 6
1007   %vecext19 = extractelement <8 x float> %a, i32 7
1008   %add20 = fadd float %vecext18, %vecext19
1009   %vecinit21 = insertelement <8 x float> %vecinit17, float %add20, i32 5
1010   %vecext22 = extractelement <8 x float> %b, i32 4
1011   %vecext23 = extractelement <8 x float> %b, i32 5
1012   %add24 = fadd float %vecext22, %vecext23
1013   %vecinit25 = insertelement <8 x float> %vecinit21, float %add24, i32 6
1014   %vecext26 = extractelement <8 x float> %b, i32 6
1015   %vecext27 = extractelement <8 x float> %b, i32 7
1016   %add28 = fadd float %vecext26, %vecext27
1017   %vecinit29 = insertelement <8 x float> %vecinit25, float %add28, i32 7
1018   ret <8 x float> %vecinit29
1021 define <8 x float> @avx_vhsub_ps(<8 x float> %a, <8 x float> %b) {
1022 ; SSE-LABEL: avx_vhsub_ps:
1023 ; SSE:       # %bb.0:
1024 ; SSE-NEXT:    hsubps %xmm2, %xmm0
1025 ; SSE-NEXT:    hsubps %xmm3, %xmm1
1026 ; SSE-NEXT:    retq
1028 ; AVX-LABEL: avx_vhsub_ps:
1029 ; AVX:       # %bb.0:
1030 ; AVX-NEXT:    vhsubps %ymm1, %ymm0, %ymm0
1031 ; AVX-NEXT:    retq
1032   %vecext = extractelement <8 x float> %a, i32 0
1033   %vecext1 = extractelement <8 x float> %a, i32 1
1034   %sub = fsub float %vecext, %vecext1
1035   %vecinit = insertelement <8 x float> undef, float %sub, i32 0
1036   %vecext2 = extractelement <8 x float> %a, i32 2
1037   %vecext3 = extractelement <8 x float> %a, i32 3
1038   %sub4 = fsub float %vecext2, %vecext3
1039   %vecinit5 = insertelement <8 x float> %vecinit, float %sub4, i32 1
1040   %vecext6 = extractelement <8 x float> %b, i32 0
1041   %vecext7 = extractelement <8 x float> %b, i32 1
1042   %sub8 = fsub float %vecext6, %vecext7
1043   %vecinit9 = insertelement <8 x float> %vecinit5, float %sub8, i32 2
1044   %vecext10 = extractelement <8 x float> %b, i32 2
1045   %vecext11 = extractelement <8 x float> %b, i32 3
1046   %sub12 = fsub float %vecext10, %vecext11
1047   %vecinit13 = insertelement <8 x float> %vecinit9, float %sub12, i32 3
1048   %vecext14 = extractelement <8 x float> %a, i32 4
1049   %vecext15 = extractelement <8 x float> %a, i32 5
1050   %sub16 = fsub float %vecext14, %vecext15
1051   %vecinit17 = insertelement <8 x float> %vecinit13, float %sub16, i32 4
1052   %vecext18 = extractelement <8 x float> %a, i32 6
1053   %vecext19 = extractelement <8 x float> %a, i32 7
1054   %sub20 = fsub float %vecext18, %vecext19
1055   %vecinit21 = insertelement <8 x float> %vecinit17, float %sub20, i32 5
1056   %vecext22 = extractelement <8 x float> %b, i32 4
1057   %vecext23 = extractelement <8 x float> %b, i32 5
1058   %sub24 = fsub float %vecext22, %vecext23
1059   %vecinit25 = insertelement <8 x float> %vecinit21, float %sub24, i32 6
1060   %vecext26 = extractelement <8 x float> %b, i32 6
1061   %vecext27 = extractelement <8 x float> %b, i32 7
1062   %sub28 = fsub float %vecext26, %vecext27
1063   %vecinit29 = insertelement <8 x float> %vecinit25, float %sub28, i32 7
1064   ret <8 x float> %vecinit29
1067 define <4 x double> @avx_hadd_pd(<4 x double> %a, <4 x double> %b) {
1068 ; SSE-LABEL: avx_hadd_pd:
1069 ; SSE:       # %bb.0:
1070 ; SSE-NEXT:    haddpd %xmm2, %xmm0
1071 ; SSE-NEXT:    haddpd %xmm3, %xmm1
1072 ; SSE-NEXT:    retq
1074 ; AVX-LABEL: avx_hadd_pd:
1075 ; AVX:       # %bb.0:
1076 ; AVX-NEXT:    vhaddpd %ymm1, %ymm0, %ymm0
1077 ; AVX-NEXT:    retq
1078   %vecext = extractelement <4 x double> %a, i32 0
1079   %vecext1 = extractelement <4 x double> %a, i32 1
1080   %add = fadd double %vecext, %vecext1
1081   %vecinit = insertelement <4 x double> undef, double %add, i32 0
1082   %vecext2 = extractelement <4 x double> %b, i32 0
1083   %vecext3 = extractelement <4 x double> %b, i32 1
1084   %add4 = fadd double %vecext2, %vecext3
1085   %vecinit5 = insertelement <4 x double> %vecinit, double %add4, i32 1
1086   %vecext6 = extractelement <4 x double> %a, i32 2
1087   %vecext7 = extractelement <4 x double> %a, i32 3
1088   %add8 = fadd double %vecext6, %vecext7
1089   %vecinit9 = insertelement <4 x double> %vecinit5, double %add8, i32 2
1090   %vecext10 = extractelement <4 x double> %b, i32 2
1091   %vecext11 = extractelement <4 x double> %b, i32 3
1092   %add12 = fadd double %vecext10, %vecext11
1093   %vecinit13 = insertelement <4 x double> %vecinit9, double %add12, i32 3
1094   ret <4 x double> %vecinit13
1097 define <4 x double> @avx_hsub_pd(<4 x double> %a, <4 x double> %b) {
1098 ; SSE-LABEL: avx_hsub_pd:
1099 ; SSE:       # %bb.0:
1100 ; SSE-NEXT:    hsubpd %xmm2, %xmm0
1101 ; SSE-NEXT:    hsubpd %xmm3, %xmm1
1102 ; SSE-NEXT:    retq
1104 ; AVX-LABEL: avx_hsub_pd:
1105 ; AVX:       # %bb.0:
1106 ; AVX-NEXT:    vhsubpd %ymm1, %ymm0, %ymm0
1107 ; AVX-NEXT:    retq
1108   %vecext = extractelement <4 x double> %a, i32 0
1109   %vecext1 = extractelement <4 x double> %a, i32 1
1110   %sub = fsub double %vecext, %vecext1
1111   %vecinit = insertelement <4 x double> undef, double %sub, i32 0
1112   %vecext2 = extractelement <4 x double> %b, i32 0
1113   %vecext3 = extractelement <4 x double> %b, i32 1
1114   %sub4 = fsub double %vecext2, %vecext3
1115   %vecinit5 = insertelement <4 x double> %vecinit, double %sub4, i32 1
1116   %vecext6 = extractelement <4 x double> %a, i32 2
1117   %vecext7 = extractelement <4 x double> %a, i32 3
1118   %sub8 = fsub double %vecext6, %vecext7
1119   %vecinit9 = insertelement <4 x double> %vecinit5, double %sub8, i32 2
1120   %vecext10 = extractelement <4 x double> %b, i32 2
1121   %vecext11 = extractelement <4 x double> %b, i32 3
1122   %sub12 = fsub double %vecext10, %vecext11
1123   %vecinit13 = insertelement <4 x double> %vecinit9, double %sub12, i32 3
1124   ret <4 x double> %vecinit13
1127 ; Test AVX2 horizontal add of packed integer values from 256-bit vectors.
1129 define <8 x i32> @avx2_hadd_d(<8 x i32> %a, <8 x i32> %b) {
1130 ; SSE3-LABEL: avx2_hadd_d:
1131 ; SSE3:       # %bb.0:
1132 ; SSE3-NEXT:    movd %xmm0, %ecx
1133 ; SSE3-NEXT:    pshufd {{.*#+}} xmm4 = xmm0[1,1,2,3]
1134 ; SSE3-NEXT:    movd %xmm4, %r8d
1135 ; SSE3-NEXT:    addl %ecx, %r8d
1136 ; SSE3-NEXT:    pshufd {{.*#+}} xmm4 = xmm0[2,3,0,1]
1137 ; SSE3-NEXT:    movd %xmm4, %edx
1138 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[3,1,2,3]
1139 ; SSE3-NEXT:    movd %xmm0, %r9d
1140 ; SSE3-NEXT:    addl %edx, %r9d
1141 ; SSE3-NEXT:    movd %xmm2, %edx
1142 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[1,1,2,3]
1143 ; SSE3-NEXT:    movd %xmm0, %esi
1144 ; SSE3-NEXT:    addl %edx, %esi
1145 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[2,3,0,1]
1146 ; SSE3-NEXT:    movd %xmm0, %edx
1147 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[3,1,2,3]
1148 ; SSE3-NEXT:    movd %xmm0, %edi
1149 ; SSE3-NEXT:    addl %edx, %edi
1150 ; SSE3-NEXT:    movd %xmm1, %eax
1151 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,2,3]
1152 ; SSE3-NEXT:    movd %xmm0, %r10d
1153 ; SSE3-NEXT:    addl %eax, %r10d
1154 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[2,3,0,1]
1155 ; SSE3-NEXT:    movd %xmm0, %eax
1156 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[3,1,2,3]
1157 ; SSE3-NEXT:    movd %xmm0, %ecx
1158 ; SSE3-NEXT:    addl %eax, %ecx
1159 ; SSE3-NEXT:    movd %xmm3, %eax
1160 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[1,1,2,3]
1161 ; SSE3-NEXT:    movd %xmm0, %edx
1162 ; SSE3-NEXT:    addl %eax, %edx
1163 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[2,3,0,1]
1164 ; SSE3-NEXT:    movd %xmm0, %r11d
1165 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm3[3,1,2,3]
1166 ; SSE3-NEXT:    movd %xmm0, %eax
1167 ; SSE3-NEXT:    addl %r11d, %eax
1168 ; SSE3-NEXT:    movd %edi, %xmm0
1169 ; SSE3-NEXT:    movd %esi, %xmm1
1170 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
1171 ; SSE3-NEXT:    movd %r9d, %xmm2
1172 ; SSE3-NEXT:    movd %r8d, %xmm0
1173 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
1174 ; SSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1175 ; SSE3-NEXT:    movd %eax, %xmm1
1176 ; SSE3-NEXT:    movd %edx, %xmm2
1177 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
1178 ; SSE3-NEXT:    movd %ecx, %xmm3
1179 ; SSE3-NEXT:    movd %r10d, %xmm1
1180 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
1181 ; SSE3-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]
1182 ; SSE3-NEXT:    retq
1184 ; SSSE3-LABEL: avx2_hadd_d:
1185 ; SSSE3:       # %bb.0:
1186 ; SSSE3-NEXT:    phaddd %xmm2, %xmm0
1187 ; SSSE3-NEXT:    phaddd %xmm3, %xmm1
1188 ; SSSE3-NEXT:    retq
1190 ; AVX1-LABEL: avx2_hadd_d:
1191 ; AVX1:       # %bb.0:
1192 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
1193 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
1194 ; AVX1-NEXT:    vphaddd %xmm2, %xmm3, %xmm2
1195 ; AVX1-NEXT:    vphaddd %xmm1, %xmm0, %xmm0
1196 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
1197 ; AVX1-NEXT:    retq
1199 ; AVX2-LABEL: avx2_hadd_d:
1200 ; AVX2:       # %bb.0:
1201 ; AVX2-NEXT:    vphaddd %ymm1, %ymm0, %ymm0
1202 ; AVX2-NEXT:    retq
1203   %vecext = extractelement <8 x i32> %a, i32 0
1204   %vecext1 = extractelement <8 x i32> %a, i32 1
1205   %add = add i32 %vecext, %vecext1
1206   %vecinit = insertelement <8 x i32> undef, i32 %add, i32 0
1207   %vecext2 = extractelement <8 x i32> %a, i32 2
1208   %vecext3 = extractelement <8 x i32> %a, i32 3
1209   %add4 = add i32 %vecext2, %vecext3
1210   %vecinit5 = insertelement <8 x i32> %vecinit, i32 %add4, i32 1
1211   %vecext6 = extractelement <8 x i32> %b, i32 0
1212   %vecext7 = extractelement <8 x i32> %b, i32 1
1213   %add8 = add i32 %vecext6, %vecext7
1214   %vecinit9 = insertelement <8 x i32> %vecinit5, i32 %add8, i32 2
1215   %vecext10 = extractelement <8 x i32> %b, i32 2
1216   %vecext11 = extractelement <8 x i32> %b, i32 3
1217   %add12 = add i32 %vecext10, %vecext11
1218   %vecinit13 = insertelement <8 x i32> %vecinit9, i32 %add12, i32 3
1219   %vecext14 = extractelement <8 x i32> %a, i32 4
1220   %vecext15 = extractelement <8 x i32> %a, i32 5
1221   %add16 = add i32 %vecext14, %vecext15
1222   %vecinit17 = insertelement <8 x i32> %vecinit13, i32 %add16, i32 4
1223   %vecext18 = extractelement <8 x i32> %a, i32 6
1224   %vecext19 = extractelement <8 x i32> %a, i32 7
1225   %add20 = add i32 %vecext18, %vecext19
1226   %vecinit21 = insertelement <8 x i32> %vecinit17, i32 %add20, i32 5
1227   %vecext22 = extractelement <8 x i32> %b, i32 4
1228   %vecext23 = extractelement <8 x i32> %b, i32 5
1229   %add24 = add i32 %vecext22, %vecext23
1230   %vecinit25 = insertelement <8 x i32> %vecinit21, i32 %add24, i32 6
1231   %vecext26 = extractelement <8 x i32> %b, i32 6
1232   %vecext27 = extractelement <8 x i32> %b, i32 7
1233   %add28 = add i32 %vecext26, %vecext27
1234   %vecinit29 = insertelement <8 x i32> %vecinit25, i32 %add28, i32 7
1235   ret <8 x i32> %vecinit29
1238 define <16 x i16> @avx2_hadd_w(<16 x i16> %a, <16 x i16> %b) nounwind {
1239 ; SSE3-LABEL: avx2_hadd_w:
1240 ; SSE3:       # %bb.0:
1241 ; SSE3-NEXT:    pushq %rbp
1242 ; SSE3-NEXT:    pushq %r15
1243 ; SSE3-NEXT:    pushq %r14
1244 ; SSE3-NEXT:    pushq %r13
1245 ; SSE3-NEXT:    pushq %r12
1246 ; SSE3-NEXT:    pushq %rbx
1247 ; SSE3-NEXT:    movd %xmm0, %eax
1248 ; SSE3-NEXT:    pextrw $1, %xmm0, %r10d
1249 ; SSE3-NEXT:    addl %eax, %r10d
1250 ; SSE3-NEXT:    pextrw $2, %xmm0, %eax
1251 ; SSE3-NEXT:    pextrw $3, %xmm0, %r11d
1252 ; SSE3-NEXT:    addl %eax, %r11d
1253 ; SSE3-NEXT:    pextrw $4, %xmm0, %eax
1254 ; SSE3-NEXT:    pextrw $5, %xmm0, %r12d
1255 ; SSE3-NEXT:    addl %eax, %r12d
1256 ; SSE3-NEXT:    pextrw $6, %xmm0, %eax
1257 ; SSE3-NEXT:    pextrw $7, %xmm0, %r13d
1258 ; SSE3-NEXT:    addl %eax, %r13d
1259 ; SSE3-NEXT:    movd %xmm1, %eax
1260 ; SSE3-NEXT:    pextrw $1, %xmm1, %ecx
1261 ; SSE3-NEXT:    addl %eax, %ecx
1262 ; SSE3-NEXT:    movl %ecx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
1263 ; SSE3-NEXT:    pextrw $2, %xmm1, %eax
1264 ; SSE3-NEXT:    pextrw $3, %xmm1, %ecx
1265 ; SSE3-NEXT:    addl %eax, %ecx
1266 ; SSE3-NEXT:    movl %ecx, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
1267 ; SSE3-NEXT:    pextrw $4, %xmm1, %eax
1268 ; SSE3-NEXT:    pextrw $5, %xmm1, %r14d
1269 ; SSE3-NEXT:    addl %eax, %r14d
1270 ; SSE3-NEXT:    pextrw $6, %xmm1, %esi
1271 ; SSE3-NEXT:    pextrw $7, %xmm1, %r15d
1272 ; SSE3-NEXT:    addl %esi, %r15d
1273 ; SSE3-NEXT:    movd %xmm2, %esi
1274 ; SSE3-NEXT:    pextrw $1, %xmm2, %ebp
1275 ; SSE3-NEXT:    addl %esi, %ebp
1276 ; SSE3-NEXT:    pextrw $2, %xmm2, %esi
1277 ; SSE3-NEXT:    pextrw $3, %xmm2, %edi
1278 ; SSE3-NEXT:    addl %esi, %edi
1279 ; SSE3-NEXT:    pextrw $4, %xmm2, %esi
1280 ; SSE3-NEXT:    pextrw $5, %xmm2, %eax
1281 ; SSE3-NEXT:    addl %esi, %eax
1282 ; SSE3-NEXT:    pextrw $6, %xmm2, %esi
1283 ; SSE3-NEXT:    pextrw $7, %xmm2, %ecx
1284 ; SSE3-NEXT:    addl %esi, %ecx
1285 ; SSE3-NEXT:    movd %xmm3, %ebx
1286 ; SSE3-NEXT:    pextrw $1, %xmm3, %r9d
1287 ; SSE3-NEXT:    addl %ebx, %r9d
1288 ; SSE3-NEXT:    pextrw $2, %xmm3, %edx
1289 ; SSE3-NEXT:    pextrw $3, %xmm3, %ebx
1290 ; SSE3-NEXT:    addl %edx, %ebx
1291 ; SSE3-NEXT:    pextrw $4, %xmm3, %edx
1292 ; SSE3-NEXT:    pextrw $5, %xmm3, %esi
1293 ; SSE3-NEXT:    addl %edx, %esi
1294 ; SSE3-NEXT:    pextrw $6, %xmm3, %r8d
1295 ; SSE3-NEXT:    pextrw $7, %xmm3, %edx
1296 ; SSE3-NEXT:    addl %r8d, %edx
1297 ; SSE3-NEXT:    movd %ecx, %xmm8
1298 ; SSE3-NEXT:    movd %eax, %xmm3
1299 ; SSE3-NEXT:    movd %edi, %xmm9
1300 ; SSE3-NEXT:    movd %ebp, %xmm4
1301 ; SSE3-NEXT:    movd %r13d, %xmm10
1302 ; SSE3-NEXT:    movd %r12d, %xmm7
1303 ; SSE3-NEXT:    movd %r11d, %xmm11
1304 ; SSE3-NEXT:    movd %r10d, %xmm0
1305 ; SSE3-NEXT:    movd %edx, %xmm12
1306 ; SSE3-NEXT:    movd %esi, %xmm6
1307 ; SSE3-NEXT:    movd %ebx, %xmm13
1308 ; SSE3-NEXT:    movd %r9d, %xmm5
1309 ; SSE3-NEXT:    movd %r15d, %xmm14
1310 ; SSE3-NEXT:    movd %r14d, %xmm2
1311 ; SSE3-NEXT:    movd {{[-0-9]+}}(%r{{[sb]}}p), %xmm15 # 4-byte Folded Reload
1312 ; SSE3-NEXT:    # xmm15 = mem[0],zero,zero,zero
1313 ; SSE3-NEXT:    movd {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 4-byte Folded Reload
1314 ; SSE3-NEXT:    # xmm1 = mem[0],zero,zero,zero
1315 ; SSE3-NEXT:    punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm8[0],xmm3[1],xmm8[1],xmm3[2],xmm8[2],xmm3[3],xmm8[3]
1316 ; SSE3-NEXT:    punpcklwd {{.*#+}} xmm4 = xmm4[0],xmm9[0],xmm4[1],xmm9[1],xmm4[2],xmm9[2],xmm4[3],xmm9[3]
1317 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm3[0],xmm4[1],xmm3[1]
1318 ; SSE3-NEXT:    punpcklwd {{.*#+}} xmm7 = xmm7[0],xmm10[0],xmm7[1],xmm10[1],xmm7[2],xmm10[2],xmm7[3],xmm10[3]
1319 ; SSE3-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm11[0],xmm0[1],xmm11[1],xmm0[2],xmm11[2],xmm0[3],xmm11[3]
1320 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm7[0],xmm0[1],xmm7[1]
1321 ; SSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm4[0]
1322 ; SSE3-NEXT:    punpcklwd {{.*#+}} xmm6 = xmm6[0],xmm12[0],xmm6[1],xmm12[1],xmm6[2],xmm12[2],xmm6[3],xmm12[3]
1323 ; SSE3-NEXT:    punpcklwd {{.*#+}} xmm5 = xmm5[0],xmm13[0],xmm5[1],xmm13[1],xmm5[2],xmm13[2],xmm5[3],xmm13[3]
1324 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm5 = xmm5[0],xmm6[0],xmm5[1],xmm6[1]
1325 ; SSE3-NEXT:    punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm14[0],xmm2[1],xmm14[1],xmm2[2],xmm14[2],xmm2[3],xmm14[3]
1326 ; SSE3-NEXT:    punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm15[0],xmm1[1],xmm15[1],xmm1[2],xmm15[2],xmm1[3],xmm15[3]
1327 ; SSE3-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
1328 ; SSE3-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm5[0]
1329 ; SSE3-NEXT:    popq %rbx
1330 ; SSE3-NEXT:    popq %r12
1331 ; SSE3-NEXT:    popq %r13
1332 ; SSE3-NEXT:    popq %r14
1333 ; SSE3-NEXT:    popq %r15
1334 ; SSE3-NEXT:    popq %rbp
1335 ; SSE3-NEXT:    retq
1337 ; SSSE3-LABEL: avx2_hadd_w:
1338 ; SSSE3:       # %bb.0:
1339 ; SSSE3-NEXT:    phaddw %xmm2, %xmm0
1340 ; SSSE3-NEXT:    phaddw %xmm3, %xmm1
1341 ; SSSE3-NEXT:    retq
1343 ; AVX1-LABEL: avx2_hadd_w:
1344 ; AVX1:       # %bb.0:
1345 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
1346 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
1347 ; AVX1-NEXT:    vphaddw %xmm2, %xmm3, %xmm2
1348 ; AVX1-NEXT:    vphaddw %xmm1, %xmm0, %xmm0
1349 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
1350 ; AVX1-NEXT:    retq
1352 ; AVX2-LABEL: avx2_hadd_w:
1353 ; AVX2:       # %bb.0:
1354 ; AVX2-NEXT:    vphaddw %ymm1, %ymm0, %ymm0
1355 ; AVX2-NEXT:    retq
1356   %vecext = extractelement <16 x i16> %a, i32 0
1357   %vecext1 = extractelement <16 x i16> %a, i32 1
1358   %add = add i16 %vecext, %vecext1
1359   %vecinit = insertelement <16 x i16> undef, i16 %add, i32 0
1360   %vecext4 = extractelement <16 x i16> %a, i32 2
1361   %vecext6 = extractelement <16 x i16> %a, i32 3
1362   %add8 = add i16 %vecext4, %vecext6
1363   %vecinit10 = insertelement <16 x i16> %vecinit, i16 %add8, i32 1
1364   %vecext11 = extractelement <16 x i16> %a, i32 4
1365   %vecext13 = extractelement <16 x i16> %a, i32 5
1366   %add15 = add i16 %vecext11, %vecext13
1367   %vecinit17 = insertelement <16 x i16> %vecinit10, i16 %add15, i32 2
1368   %vecext18 = extractelement <16 x i16> %a, i32 6
1369   %vecext20 = extractelement <16 x i16> %a, i32 7
1370   %add22 = add i16 %vecext18, %vecext20
1371   %vecinit24 = insertelement <16 x i16> %vecinit17, i16 %add22, i32 3
1372   %vecext25 = extractelement <16 x i16> %a, i32 8
1373   %vecext27 = extractelement <16 x i16> %a, i32 9
1374   %add29 = add i16 %vecext25, %vecext27
1375   %vecinit31 = insertelement <16 x i16> %vecinit24, i16 %add29, i32 8
1376   %vecext32 = extractelement <16 x i16> %a, i32 10
1377   %vecext34 = extractelement <16 x i16> %a, i32 11
1378   %add36 = add i16 %vecext32, %vecext34
1379   %vecinit38 = insertelement <16 x i16> %vecinit31, i16 %add36, i32 9
1380   %vecext39 = extractelement <16 x i16> %a, i32 12
1381   %vecext41 = extractelement <16 x i16> %a, i32 13
1382   %add43 = add i16 %vecext39, %vecext41
1383   %vecinit45 = insertelement <16 x i16> %vecinit38, i16 %add43, i32 10
1384   %vecext46 = extractelement <16 x i16> %a, i32 14
1385   %vecext48 = extractelement <16 x i16> %a, i32 15
1386   %add50 = add i16 %vecext46, %vecext48
1387   %vecinit52 = insertelement <16 x i16> %vecinit45, i16 %add50, i32 11
1388   %vecext53 = extractelement <16 x i16> %b, i32 0
1389   %vecext55 = extractelement <16 x i16> %b, i32 1
1390   %add57 = add i16 %vecext53, %vecext55
1391   %vecinit59 = insertelement <16 x i16> %vecinit52, i16 %add57, i32 4
1392   %vecext60 = extractelement <16 x i16> %b, i32 2
1393   %vecext62 = extractelement <16 x i16> %b, i32 3
1394   %add64 = add i16 %vecext60, %vecext62
1395   %vecinit66 = insertelement <16 x i16> %vecinit59, i16 %add64, i32 5
1396   %vecext67 = extractelement <16 x i16> %b, i32 4
1397   %vecext69 = extractelement <16 x i16> %b, i32 5
1398   %add71 = add i16 %vecext67, %vecext69
1399   %vecinit73 = insertelement <16 x i16> %vecinit66, i16 %add71, i32 6
1400   %vecext74 = extractelement <16 x i16> %b, i32 6
1401   %vecext76 = extractelement <16 x i16> %b, i32 7
1402   %add78 = add i16 %vecext74, %vecext76
1403   %vecinit80 = insertelement <16 x i16> %vecinit73, i16 %add78, i32 7
1404   %vecext81 = extractelement <16 x i16> %b, i32 8
1405   %vecext83 = extractelement <16 x i16> %b, i32 9
1406   %add85 = add i16 %vecext81, %vecext83
1407   %vecinit87 = insertelement <16 x i16> %vecinit80, i16 %add85, i32 12
1408   %vecext88 = extractelement <16 x i16> %b, i32 10
1409   %vecext90 = extractelement <16 x i16> %b, i32 11
1410   %add92 = add i16 %vecext88, %vecext90
1411   %vecinit94 = insertelement <16 x i16> %vecinit87, i16 %add92, i32 13
1412   %vecext95 = extractelement <16 x i16> %b, i32 12
1413   %vecext97 = extractelement <16 x i16> %b, i32 13
1414   %add99 = add i16 %vecext95, %vecext97
1415   %vecinit101 = insertelement <16 x i16> %vecinit94, i16 %add99, i32 14
1416   %vecext102 = extractelement <16 x i16> %b, i32 14
1417   %vecext104 = extractelement <16 x i16> %b, i32 15
1418   %add106 = add i16 %vecext102, %vecext104
1419   %vecinit108 = insertelement <16 x i16> %vecinit101, i16 %add106, i32 15
1420   ret <16 x i16> %vecinit108