[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / X86 / haddsub-shuf.ll
blobcf3ed256d6ef3bacc744ff43a47ddc6073ae7fc9
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+sse3           | FileCheck %s --check-prefixes=SSE,SSE_SLOW,SSE3
3 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+sse3,fast-hops | FileCheck %s --check-prefixes=SSE,SSE_FAST,SSE3
4 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+ssse3           | FileCheck %s --check-prefixes=SSE,SSE_SLOW,SSSE3,SSSE3_SLOW
5 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+ssse3,fast-hops | FileCheck %s --check-prefixes=SSE,SSE_FAST,SSSE3,SSSE3_FAST
6 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx             | FileCheck %s --check-prefixes=AVX,AVX1,AVX1_SLOW
7 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx,fast-hops   | FileCheck %s --check-prefixes=AVX,AVX1,AVX1_FAST
8 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx2            | FileCheck %s --check-prefixes=AVX,AVX2,AVX2_SLOW
9 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx2,fast-hops  | FileCheck %s --check-prefixes=AVX,AVX2,AVX2_FAST
11 ; The next 8 tests check for matching the horizontal op and eliminating the shuffle.
12 ; PR34111 - https://bugs.llvm.org/show_bug.cgi?id=34111
14 define <4 x float> @hadd_v4f32(<4 x float> %a) {
15 ; SSE-LABEL: hadd_v4f32:
16 ; SSE:       # %bb.0:
17 ; SSE-NEXT:    haddps %xmm0, %xmm0
18 ; SSE-NEXT:    retq
20 ; AVX-LABEL: hadd_v4f32:
21 ; AVX:       # %bb.0:
22 ; AVX-NEXT:    vhaddps %xmm0, %xmm0, %xmm0
23 ; AVX-NEXT:    retq
24   %a02 = shufflevector <4 x float> %a, <4 x float> undef, <2 x i32> <i32 0, i32 2>
25   %a13 = shufflevector <4 x float> %a, <4 x float> undef, <2 x i32> <i32 1, i32 3>
26   %hop = fadd <2 x float> %a02, %a13
27   %shuf = shufflevector <2 x float> %hop, <2 x float> undef, <4 x i32> <i32 undef, i32 undef, i32 0, i32 1>
28   ret <4 x float> %shuf
31 define <8 x float> @hadd_v8f32a(<8 x float> %a) {
32 ; SSE_SLOW-LABEL: hadd_v8f32a:
33 ; SSE_SLOW:       # %bb.0:
34 ; SSE_SLOW-NEXT:    movaps %xmm0, %xmm2
35 ; SSE_SLOW-NEXT:    haddps %xmm1, %xmm2
36 ; SSE_SLOW-NEXT:    movddup {{.*#+}} xmm0 = xmm2[0,0]
37 ; SSE_SLOW-NEXT:    movaps %xmm2, %xmm1
38 ; SSE_SLOW-NEXT:    retq
40 ; SSE_FAST-LABEL: hadd_v8f32a:
41 ; SSE_FAST:       # %bb.0:
42 ; SSE_FAST-NEXT:    movaps %xmm0, %xmm2
43 ; SSE_FAST-NEXT:    haddps %xmm1, %xmm2
44 ; SSE_FAST-NEXT:    haddps %xmm0, %xmm0
45 ; SSE_FAST-NEXT:    movaps %xmm2, %xmm1
46 ; SSE_FAST-NEXT:    retq
48 ; AVX1_SLOW-LABEL: hadd_v8f32a:
49 ; AVX1_SLOW:       # %bb.0:
50 ; AVX1_SLOW-NEXT:    vextractf128 $1, %ymm0, %xmm1
51 ; AVX1_SLOW-NEXT:    vhaddps %xmm1, %xmm0, %xmm0
52 ; AVX1_SLOW-NEXT:    vmovddup {{.*#+}} xmm1 = xmm0[0,0]
53 ; AVX1_SLOW-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
54 ; AVX1_SLOW-NEXT:    retq
56 ; AVX1_FAST-LABEL: hadd_v8f32a:
57 ; AVX1_FAST:       # %bb.0:
58 ; AVX1_FAST-NEXT:    vinsertf128 $1, %xmm0, %ymm0, %ymm1
59 ; AVX1_FAST-NEXT:    vhaddps %ymm0, %ymm1, %ymm0
60 ; AVX1_FAST-NEXT:    retq
62 ; AVX2-LABEL: hadd_v8f32a:
63 ; AVX2:       # %bb.0:
64 ; AVX2-NEXT:    vextractf128 $1, %ymm0, %xmm1
65 ; AVX2-NEXT:    vhaddps %xmm1, %xmm0, %xmm0
66 ; AVX2-NEXT:    vpermpd {{.*#+}} ymm0 = ymm0[0,0,2,1]
67 ; AVX2-NEXT:    retq
68   %a0 = shufflevector <8 x float> %a, <8 x float> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
69   %a1 = shufflevector <8 x float> %a, <8 x float> undef, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
70   %hop = fadd <4 x float> %a0, %a1
71   %shuf = shufflevector <4 x float> %hop, <4 x float> undef, <8 x i32> <i32 undef, i32 undef, i32 0, i32 1, i32 undef, i32 undef, i32 2, i32 3>
72   ret <8 x float> %shuf
75 define <8 x float> @hadd_v8f32b(<8 x float> %a) {
76 ; SSE-LABEL: hadd_v8f32b:
77 ; SSE:       # %bb.0:
78 ; SSE-NEXT:    haddps %xmm0, %xmm0
79 ; SSE-NEXT:    haddps %xmm1, %xmm1
80 ; SSE-NEXT:    retq
82 ; AVX-LABEL: hadd_v8f32b:
83 ; AVX:       # %bb.0:
84 ; AVX-NEXT:    vhaddps %ymm0, %ymm0, %ymm0
85 ; AVX-NEXT:    retq
86   %a0 = shufflevector <8 x float> %a, <8 x float> undef, <8 x i32> <i32 0, i32 2, i32 undef, i32 undef, i32 4, i32 6, i32 undef, i32 undef>
87   %a1 = shufflevector <8 x float> %a, <8 x float> undef, <8 x i32> <i32 1, i32 3, i32 undef, i32 undef, i32 5, i32 7, i32 undef, i32 undef>
88   %hop = fadd <8 x float> %a0, %a1
89   %shuf = shufflevector <8 x float> %hop, <8 x float> undef, <8 x i32> <i32 0, i32 1, i32 0, i32 1, i32 4, i32 5, i32 4, i32 5>
90   ret <8 x float> %shuf
93 define <4 x float> @hsub_v4f32(<4 x float> %a) {
94 ; SSE-LABEL: hsub_v4f32:
95 ; SSE:       # %bb.0:
96 ; SSE-NEXT:    hsubps %xmm0, %xmm0
97 ; SSE-NEXT:    retq
99 ; AVX-LABEL: hsub_v4f32:
100 ; AVX:       # %bb.0:
101 ; AVX-NEXT:    vhsubps %xmm0, %xmm0, %xmm0
102 ; AVX-NEXT:    retq
103   %a02 = shufflevector <4 x float> %a, <4 x float> undef, <2 x i32> <i32 0, i32 2>
104   %a13 = shufflevector <4 x float> %a, <4 x float> undef, <2 x i32> <i32 1, i32 3>
105   %hop = fsub <2 x float> %a02, %a13
106   %shuf = shufflevector <2 x float> %hop, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
107   ret <4 x float> %shuf
110 define <8 x float> @hsub_v8f32a(<8 x float> %a) {
111 ; SSE_SLOW-LABEL: hsub_v8f32a:
112 ; SSE_SLOW:       # %bb.0:
113 ; SSE_SLOW-NEXT:    movaps %xmm0, %xmm2
114 ; SSE_SLOW-NEXT:    hsubps %xmm1, %xmm2
115 ; SSE_SLOW-NEXT:    movddup {{.*#+}} xmm0 = xmm2[0,0]
116 ; SSE_SLOW-NEXT:    movaps %xmm2, %xmm1
117 ; SSE_SLOW-NEXT:    retq
119 ; SSE_FAST-LABEL: hsub_v8f32a:
120 ; SSE_FAST:       # %bb.0:
121 ; SSE_FAST-NEXT:    movaps %xmm0, %xmm2
122 ; SSE_FAST-NEXT:    hsubps %xmm1, %xmm2
123 ; SSE_FAST-NEXT:    hsubps %xmm0, %xmm0
124 ; SSE_FAST-NEXT:    movaps %xmm2, %xmm1
125 ; SSE_FAST-NEXT:    retq
127 ; AVX1_SLOW-LABEL: hsub_v8f32a:
128 ; AVX1_SLOW:       # %bb.0:
129 ; AVX1_SLOW-NEXT:    vextractf128 $1, %ymm0, %xmm1
130 ; AVX1_SLOW-NEXT:    vhsubps %xmm1, %xmm0, %xmm0
131 ; AVX1_SLOW-NEXT:    vmovddup {{.*#+}} xmm1 = xmm0[0,0]
132 ; AVX1_SLOW-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
133 ; AVX1_SLOW-NEXT:    retq
135 ; AVX1_FAST-LABEL: hsub_v8f32a:
136 ; AVX1_FAST:       # %bb.0:
137 ; AVX1_FAST-NEXT:    vinsertf128 $1, %xmm0, %ymm0, %ymm1
138 ; AVX1_FAST-NEXT:    vhsubps %ymm0, %ymm1, %ymm0
139 ; AVX1_FAST-NEXT:    retq
141 ; AVX2-LABEL: hsub_v8f32a:
142 ; AVX2:       # %bb.0:
143 ; AVX2-NEXT:    vextractf128 $1, %ymm0, %xmm1
144 ; AVX2-NEXT:    vhsubps %xmm1, %xmm0, %xmm0
145 ; AVX2-NEXT:    vpermpd {{.*#+}} ymm0 = ymm0[0,0,2,1]
146 ; AVX2-NEXT:    retq
147   %a0 = shufflevector <8 x float> %a, <8 x float> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
148   %a1 = shufflevector <8 x float> %a, <8 x float> undef, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
149   %hop = fsub <4 x float> %a0, %a1
150   %shuf = shufflevector <4 x float> %hop, <4 x float> undef, <8 x i32> <i32 undef, i32 undef, i32 0, i32 1, i32 undef, i32 undef, i32 2, i32 3>
151   ret <8 x float> %shuf
154 define <8 x float> @hsub_v8f32b(<8 x float> %a) {
155 ; SSE-LABEL: hsub_v8f32b:
156 ; SSE:       # %bb.0:
157 ; SSE-NEXT:    hsubps %xmm0, %xmm0
158 ; SSE-NEXT:    hsubps %xmm1, %xmm1
159 ; SSE-NEXT:    retq
161 ; AVX-LABEL: hsub_v8f32b:
162 ; AVX:       # %bb.0:
163 ; AVX-NEXT:    vhsubps %ymm0, %ymm0, %ymm0
164 ; AVX-NEXT:    retq
165   %a0 = shufflevector <8 x float> %a, <8 x float> undef, <8 x i32> <i32 0, i32 2, i32 undef, i32 undef, i32 4, i32 6, i32 undef, i32 undef>
166   %a1 = shufflevector <8 x float> %a, <8 x float> undef, <8 x i32> <i32 1, i32 3, i32 undef, i32 undef, i32 5, i32 7, i32 undef, i32 undef>
167   %hop = fsub <8 x float> %a0, %a1
168   %shuf = shufflevector <8 x float> %hop, <8 x float> undef, <8 x i32> <i32 0, i32 1, i32 0, i32 1, i32 4, i32 5, i32 4, i32 5>
169   ret <8 x float> %shuf
172 define <2 x double> @hadd_v2f64(<2 x double> %a) {
173 ; SSE_SLOW-LABEL: hadd_v2f64:
174 ; SSE_SLOW:       # %bb.0:
175 ; SSE_SLOW-NEXT:    movapd %xmm0, %xmm1
176 ; SSE_SLOW-NEXT:    unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1]
177 ; SSE_SLOW-NEXT:    addsd %xmm0, %xmm1
178 ; SSE_SLOW-NEXT:    movddup {{.*#+}} xmm0 = xmm1[0,0]
179 ; SSE_SLOW-NEXT:    retq
181 ; SSE_FAST-LABEL: hadd_v2f64:
182 ; SSE_FAST:       # %bb.0:
183 ; SSE_FAST-NEXT:    haddpd %xmm0, %xmm0
184 ; SSE_FAST-NEXT:    retq
186 ; AVX1_SLOW-LABEL: hadd_v2f64:
187 ; AVX1_SLOW:       # %bb.0:
188 ; AVX1_SLOW-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm0[1,0]
189 ; AVX1_SLOW-NEXT:    vaddsd %xmm1, %xmm0, %xmm0
190 ; AVX1_SLOW-NEXT:    vmovddup {{.*#+}} xmm0 = xmm0[0,0]
191 ; AVX1_SLOW-NEXT:    retq
193 ; AVX1_FAST-LABEL: hadd_v2f64:
194 ; AVX1_FAST:       # %bb.0:
195 ; AVX1_FAST-NEXT:    vhaddpd %xmm0, %xmm0, %xmm0
196 ; AVX1_FAST-NEXT:    retq
198 ; AVX2_SLOW-LABEL: hadd_v2f64:
199 ; AVX2_SLOW:       # %bb.0:
200 ; AVX2_SLOW-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm0[1,0]
201 ; AVX2_SLOW-NEXT:    vaddsd %xmm1, %xmm0, %xmm0
202 ; AVX2_SLOW-NEXT:    vmovddup {{.*#+}} xmm0 = xmm0[0,0]
203 ; AVX2_SLOW-NEXT:    retq
205 ; AVX2_FAST-LABEL: hadd_v2f64:
206 ; AVX2_FAST:       # %bb.0:
207 ; AVX2_FAST-NEXT:    vhaddpd %xmm0, %xmm0, %xmm0
208 ; AVX2_FAST-NEXT:    retq
209   %a0 = shufflevector <2 x double> %a, <2 x double> undef, <2 x i32> <i32 0, i32 undef>
210   %a1 = shufflevector <2 x double> %a, <2 x double> undef, <2 x i32> <i32 1, i32 undef>
211   %hop = fadd <2 x double> %a0, %a1
212   %shuf = shufflevector <2 x double> %hop, <2 x double> undef, <2 x i32> <i32 0, i32 0>
213   ret <2 x double> %shuf
216 define <2 x double> @hadd_v2f64_scalar_splat(<2 x double> %a) {
217 ; SSE_SLOW-LABEL: hadd_v2f64_scalar_splat:
218 ; SSE_SLOW:       # %bb.0:
219 ; SSE_SLOW-NEXT:    movapd %xmm0, %xmm1
220 ; SSE_SLOW-NEXT:    unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1]
221 ; SSE_SLOW-NEXT:    addsd %xmm0, %xmm1
222 ; SSE_SLOW-NEXT:    movddup {{.*#+}} xmm0 = xmm1[0,0]
223 ; SSE_SLOW-NEXT:    retq
225 ; SSE_FAST-LABEL: hadd_v2f64_scalar_splat:
226 ; SSE_FAST:       # %bb.0:
227 ; SSE_FAST-NEXT:    haddpd %xmm0, %xmm0
228 ; SSE_FAST-NEXT:    retq
230 ; AVX1_SLOW-LABEL: hadd_v2f64_scalar_splat:
231 ; AVX1_SLOW:       # %bb.0:
232 ; AVX1_SLOW-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm0[1,0]
233 ; AVX1_SLOW-NEXT:    vaddsd %xmm1, %xmm0, %xmm0
234 ; AVX1_SLOW-NEXT:    vmovddup {{.*#+}} xmm0 = xmm0[0,0]
235 ; AVX1_SLOW-NEXT:    retq
237 ; AVX1_FAST-LABEL: hadd_v2f64_scalar_splat:
238 ; AVX1_FAST:       # %bb.0:
239 ; AVX1_FAST-NEXT:    vhaddpd %xmm0, %xmm0, %xmm0
240 ; AVX1_FAST-NEXT:    retq
242 ; AVX2_SLOW-LABEL: hadd_v2f64_scalar_splat:
243 ; AVX2_SLOW:       # %bb.0:
244 ; AVX2_SLOW-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm0[1,0]
245 ; AVX2_SLOW-NEXT:    vaddsd %xmm1, %xmm0, %xmm0
246 ; AVX2_SLOW-NEXT:    vmovddup {{.*#+}} xmm0 = xmm0[0,0]
247 ; AVX2_SLOW-NEXT:    retq
249 ; AVX2_FAST-LABEL: hadd_v2f64_scalar_splat:
250 ; AVX2_FAST:       # %bb.0:
251 ; AVX2_FAST-NEXT:    vhaddpd %xmm0, %xmm0, %xmm0
252 ; AVX2_FAST-NEXT:    retq
253   %a0 = extractelement <2 x double> %a, i32 0
254   %a1 = extractelement <2 x double> %a, i32 1
255   %hop = fadd double %a0, %a1
256   %ins = insertelement <2 x double> undef, double %hop, i32 0
257   %shuf = shufflevector <2 x double> %ins, <2 x double> undef, <2 x i32> <i32 0, i32 0>
258   ret <2 x double> %shuf
261 define <4 x double> @hadd_v4f64_scalar_splat(<4 x double> %a) {
262 ; SSE_SLOW-LABEL: hadd_v4f64_scalar_splat:
263 ; SSE_SLOW:       # %bb.0:
264 ; SSE_SLOW-NEXT:    movapd %xmm0, %xmm2
265 ; SSE_SLOW-NEXT:    unpckhpd {{.*#+}} xmm2 = xmm2[1],xmm0[1]
266 ; SSE_SLOW-NEXT:    addsd %xmm0, %xmm2
267 ; SSE_SLOW-NEXT:    movapd %xmm1, %xmm3
268 ; SSE_SLOW-NEXT:    unpckhpd {{.*#+}} xmm3 = xmm3[1],xmm1[1]
269 ; SSE_SLOW-NEXT:    addsd %xmm1, %xmm3
270 ; SSE_SLOW-NEXT:    movddup {{.*#+}} xmm0 = xmm2[0,0]
271 ; SSE_SLOW-NEXT:    movddup {{.*#+}} xmm1 = xmm3[0,0]
272 ; SSE_SLOW-NEXT:    retq
274 ; SSE_FAST-LABEL: hadd_v4f64_scalar_splat:
275 ; SSE_FAST:       # %bb.0:
276 ; SSE_FAST-NEXT:    haddpd %xmm0, %xmm0
277 ; SSE_FAST-NEXT:    haddpd %xmm1, %xmm1
278 ; SSE_FAST-NEXT:    retq
280 ; AVX-LABEL: hadd_v4f64_scalar_splat:
281 ; AVX:       # %bb.0:
282 ; AVX-NEXT:    vhaddpd %ymm0, %ymm0, %ymm0
283 ; AVX-NEXT:    retq
284   %a0 = extractelement <4 x double> %a, i32 0
285   %a1 = extractelement <4 x double> %a, i32 1
286   %hop0 = fadd double %a0, %a1
287   %a2 = extractelement <4 x double> %a, i32 2
288   %a3 = extractelement <4 x double> %a, i32 3
289   %hop1 = fadd double %a2, %a3
290   %ins = insertelement <4 x double> undef, double %hop0, i32 0
291   %ins2 = insertelement <4 x double> %ins,  double %hop1, i32 2
292   %shuf = shufflevector <4 x double> %ins2, <4 x double> undef, <4 x i32> <i32 0, i32 0, i32 2, i32 2>
293   ret <4 x double> %shuf
296 define <4 x double> @hadd_v4f64_scalar_broadcast(<4 x double> %a) {
297 ; SSE_SLOW-LABEL: hadd_v4f64_scalar_broadcast:
298 ; SSE_SLOW:       # %bb.0:
299 ; SSE_SLOW-NEXT:    movapd %xmm0, %xmm1
300 ; SSE_SLOW-NEXT:    unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1]
301 ; SSE_SLOW-NEXT:    addsd %xmm0, %xmm1
302 ; SSE_SLOW-NEXT:    movddup {{.*#+}} xmm0 = xmm1[0,0]
303 ; SSE_SLOW-NEXT:    movapd %xmm0, %xmm1
304 ; SSE_SLOW-NEXT:    retq
306 ; SSE_FAST-LABEL: hadd_v4f64_scalar_broadcast:
307 ; SSE_FAST:       # %bb.0:
308 ; SSE_FAST-NEXT:    haddpd %xmm0, %xmm0
309 ; SSE_FAST-NEXT:    movapd %xmm0, %xmm1
310 ; SSE_FAST-NEXT:    retq
312 ; AVX1_SLOW-LABEL: hadd_v4f64_scalar_broadcast:
313 ; AVX1_SLOW:       # %bb.0:
314 ; AVX1_SLOW-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm0[1,0]
315 ; AVX1_SLOW-NEXT:    vaddsd %xmm1, %xmm0, %xmm0
316 ; AVX1_SLOW-NEXT:    vmovddup {{.*#+}} xmm0 = xmm0[0,0]
317 ; AVX1_SLOW-NEXT:    vinsertf128 $1, %xmm0, %ymm0, %ymm0
318 ; AVX1_SLOW-NEXT:    retq
320 ; AVX1_FAST-LABEL: hadd_v4f64_scalar_broadcast:
321 ; AVX1_FAST:       # %bb.0:
322 ; AVX1_FAST-NEXT:    vhaddpd %xmm0, %xmm0, %xmm0
323 ; AVX1_FAST-NEXT:    vinsertf128 $1, %xmm0, %ymm0, %ymm0
324 ; AVX1_FAST-NEXT:    retq
326 ; AVX2_SLOW-LABEL: hadd_v4f64_scalar_broadcast:
327 ; AVX2_SLOW:       # %bb.0:
328 ; AVX2_SLOW-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm0[1,0]
329 ; AVX2_SLOW-NEXT:    vaddsd %xmm1, %xmm0, %xmm0
330 ; AVX2_SLOW-NEXT:    vbroadcastsd %xmm0, %ymm0
331 ; AVX2_SLOW-NEXT:    retq
333 ; AVX2_FAST-LABEL: hadd_v4f64_scalar_broadcast:
334 ; AVX2_FAST:       # %bb.0:
335 ; AVX2_FAST-NEXT:    vhaddpd %xmm0, %xmm0, %xmm0
336 ; AVX2_FAST-NEXT:    vbroadcastsd %xmm0, %ymm0
337 ; AVX2_FAST-NEXT:    retq
338   %a0 = extractelement <4 x double> %a, i32 0
339   %a1 = extractelement <4 x double> %a, i32 1
340   %hop0 = fadd double %a0, %a1
341   %a2 = extractelement <4 x double> %a, i32 2
342   %a3 = extractelement <4 x double> %a, i32 3
343   %hop1 = fadd double %a2, %a3
344   %ins = insertelement <4 x double> undef, double %hop0, i32 0
345   %ins2 = insertelement <4 x double> %ins,  double %hop1, i32 2
346   %shuf = shufflevector <4 x double> %ins2, <4 x double> undef, <4 x i32> <i32 0, i32 0, i32 0, i32 0>
347   ret <4 x double> %shuf
350 define <4 x double> @hadd_v4f64(<4 x double> %a) {
351 ; SSE_SLOW-LABEL: hadd_v4f64:
352 ; SSE_SLOW:       # %bb.0:
353 ; SSE_SLOW-NEXT:    movapd %xmm0, %xmm2
354 ; SSE_SLOW-NEXT:    unpckhpd {{.*#+}} xmm2 = xmm2[1],xmm0[1]
355 ; SSE_SLOW-NEXT:    addsd %xmm0, %xmm2
356 ; SSE_SLOW-NEXT:    movddup {{.*#+}} xmm0 = xmm2[0,0]
357 ; SSE_SLOW-NEXT:    movapd %xmm1, %xmm2
358 ; SSE_SLOW-NEXT:    unpckhpd {{.*#+}} xmm2 = xmm2[1],xmm1[1]
359 ; SSE_SLOW-NEXT:    addsd %xmm1, %xmm2
360 ; SSE_SLOW-NEXT:    movddup {{.*#+}} xmm1 = xmm2[0,0]
361 ; SSE_SLOW-NEXT:    retq
363 ; SSE_FAST-LABEL: hadd_v4f64:
364 ; SSE_FAST:       # %bb.0:
365 ; SSE_FAST-NEXT:    haddpd %xmm0, %xmm0
366 ; SSE_FAST-NEXT:    haddpd %xmm1, %xmm1
367 ; SSE_FAST-NEXT:    retq
369 ; AVX-LABEL: hadd_v4f64:
370 ; AVX:       # %bb.0:
371 ; AVX-NEXT:    vhaddpd %ymm0, %ymm0, %ymm0
372 ; AVX-NEXT:    retq
373   %a0 = shufflevector <4 x double> %a, <4 x double> undef, <4 x i32> <i32 0, i32 undef, i32 2, i32 undef>
374   %a1 = shufflevector <4 x double> %a, <4 x double> undef, <4 x i32> <i32 1, i32 undef, i32 3, i32 undef>
375   %hop = fadd <4 x double> %a0, %a1
376   %shuf = shufflevector <4 x double> %hop, <4 x double> undef, <4 x i32> <i32 0, i32 0, i32 2, i32 2>
377   ret <4 x double> %shuf
380 define <2 x double> @hsub_v2f64(<2 x double> %a) {
381 ; SSE_SLOW-LABEL: hsub_v2f64:
382 ; SSE_SLOW:       # %bb.0:
383 ; SSE_SLOW-NEXT:    movapd %xmm0, %xmm1
384 ; SSE_SLOW-NEXT:    unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1]
385 ; SSE_SLOW-NEXT:    subsd %xmm1, %xmm0
386 ; SSE_SLOW-NEXT:    movddup {{.*#+}} xmm0 = xmm0[0,0]
387 ; SSE_SLOW-NEXT:    retq
389 ; SSE_FAST-LABEL: hsub_v2f64:
390 ; SSE_FAST:       # %bb.0:
391 ; SSE_FAST-NEXT:    hsubpd %xmm0, %xmm0
392 ; SSE_FAST-NEXT:    retq
394 ; AVX1_SLOW-LABEL: hsub_v2f64:
395 ; AVX1_SLOW:       # %bb.0:
396 ; AVX1_SLOW-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm0[1,0]
397 ; AVX1_SLOW-NEXT:    vsubsd %xmm1, %xmm0, %xmm0
398 ; AVX1_SLOW-NEXT:    vmovddup {{.*#+}} xmm0 = xmm0[0,0]
399 ; AVX1_SLOW-NEXT:    retq
401 ; AVX1_FAST-LABEL: hsub_v2f64:
402 ; AVX1_FAST:       # %bb.0:
403 ; AVX1_FAST-NEXT:    vhsubpd %xmm0, %xmm0, %xmm0
404 ; AVX1_FAST-NEXT:    retq
406 ; AVX2_SLOW-LABEL: hsub_v2f64:
407 ; AVX2_SLOW:       # %bb.0:
408 ; AVX2_SLOW-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm0[1,0]
409 ; AVX2_SLOW-NEXT:    vsubsd %xmm1, %xmm0, %xmm0
410 ; AVX2_SLOW-NEXT:    vmovddup {{.*#+}} xmm0 = xmm0[0,0]
411 ; AVX2_SLOW-NEXT:    retq
413 ; AVX2_FAST-LABEL: hsub_v2f64:
414 ; AVX2_FAST:       # %bb.0:
415 ; AVX2_FAST-NEXT:    vhsubpd %xmm0, %xmm0, %xmm0
416 ; AVX2_FAST-NEXT:    retq
417   %a0 = shufflevector <2 x double> %a, <2 x double> undef, <2 x i32> <i32 0, i32 undef>
418   %a1 = shufflevector <2 x double> %a, <2 x double> undef, <2 x i32> <i32 1, i32 undef>
419   %hop = fsub <2 x double> %a0, %a1
420   %shuf = shufflevector <2 x double> %hop, <2 x double> undef, <2 x i32> <i32 undef, i32 0>
421   ret <2 x double> %shuf
424 define <4 x double> @hsub_v4f64(<4 x double> %a) {
425 ; SSE_SLOW-LABEL: hsub_v4f64:
426 ; SSE_SLOW:       # %bb.0:
427 ; SSE_SLOW-NEXT:    movapd %xmm0, %xmm2
428 ; SSE_SLOW-NEXT:    unpckhpd {{.*#+}} xmm2 = xmm2[1],xmm0[1]
429 ; SSE_SLOW-NEXT:    subsd %xmm2, %xmm0
430 ; SSE_SLOW-NEXT:    movddup {{.*#+}} xmm0 = xmm0[0,0]
431 ; SSE_SLOW-NEXT:    movapd %xmm1, %xmm2
432 ; SSE_SLOW-NEXT:    unpckhpd {{.*#+}} xmm2 = xmm2[1],xmm1[1]
433 ; SSE_SLOW-NEXT:    subsd %xmm2, %xmm1
434 ; SSE_SLOW-NEXT:    movddup {{.*#+}} xmm1 = xmm1[0,0]
435 ; SSE_SLOW-NEXT:    retq
437 ; SSE_FAST-LABEL: hsub_v4f64:
438 ; SSE_FAST:       # %bb.0:
439 ; SSE_FAST-NEXT:    hsubpd %xmm0, %xmm0
440 ; SSE_FAST-NEXT:    hsubpd %xmm1, %xmm1
441 ; SSE_FAST-NEXT:    retq
443 ; AVX-LABEL: hsub_v4f64:
444 ; AVX:       # %bb.0:
445 ; AVX-NEXT:    vhsubpd %ymm0, %ymm0, %ymm0
446 ; AVX-NEXT:    retq
447   %a0 = shufflevector <4 x double> %a, <4 x double> undef, <4 x i32> <i32 0, i32 undef, i32 2, i32 undef>
448   %a1 = shufflevector <4 x double> %a, <4 x double> undef, <4 x i32> <i32 1, i32 undef, i32 3, i32 undef>
449   %hop = fsub <4 x double> %a0, %a1
450   %shuf = shufflevector <4 x double> %hop, <4 x double> undef, <4 x i32> <i32 0, i32 0, i32 2, i32 2>
451   ret <4 x double> %shuf
454 define <4 x i32> @hadd_v4i32(<4 x i32> %a) {
455 ; SSE3-LABEL: hadd_v4i32:
456 ; SSE3:       # %bb.0:
457 ; SSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[1,1,2,3]
458 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,1,2,2]
459 ; SSE3-NEXT:    paddd %xmm1, %xmm0
460 ; SSE3-NEXT:    retq
462 ; SSSE3-LABEL: hadd_v4i32:
463 ; SSSE3:       # %bb.0:
464 ; SSSE3-NEXT:    phaddd %xmm0, %xmm0
465 ; SSSE3-NEXT:    retq
467 ; AVX-LABEL: hadd_v4i32:
468 ; AVX:       # %bb.0:
469 ; AVX-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
470 ; AVX-NEXT:    retq
471   %a02 = shufflevector <4 x i32> %a, <4 x i32> undef, <4 x i32> <i32 0, i32 2, i32 undef, i32 undef>
472   %a13 = shufflevector <4 x i32> %a, <4 x i32> undef, <4 x i32> <i32 1, i32 3, i32 undef, i32 undef>
473   %hop = add <4 x i32> %a02, %a13
474   %shuf = shufflevector <4 x i32> %hop, <4 x i32> undef, <4 x i32> <i32 0, i32 undef, i32 undef, i32 1>
475   ret <4 x i32> %shuf
478 define <8 x i32> @hadd_v8i32a(<8 x i32> %a) {
479 ; SSE3-LABEL: hadd_v8i32a:
480 ; SSE3:       # %bb.0:
481 ; SSE3-NEXT:    movaps %xmm0, %xmm2
482 ; SSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
483 ; SSE3-NEXT:    shufps {{.*#+}} xmm2 = xmm2[1,3],xmm1[1,3]
484 ; SSE3-NEXT:    paddd %xmm0, %xmm2
485 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,1,0,1]
486 ; SSE3-NEXT:    movdqa %xmm2, %xmm1
487 ; SSE3-NEXT:    retq
489 ; SSSE3_SLOW-LABEL: hadd_v8i32a:
490 ; SSSE3_SLOW:       # %bb.0:
491 ; SSSE3_SLOW-NEXT:    movdqa %xmm0, %xmm2
492 ; SSSE3_SLOW-NEXT:    phaddd %xmm1, %xmm2
493 ; SSSE3_SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,1,0,1]
494 ; SSSE3_SLOW-NEXT:    movdqa %xmm2, %xmm1
495 ; SSSE3_SLOW-NEXT:    retq
497 ; SSSE3_FAST-LABEL: hadd_v8i32a:
498 ; SSSE3_FAST:       # %bb.0:
499 ; SSSE3_FAST-NEXT:    movdqa %xmm0, %xmm2
500 ; SSSE3_FAST-NEXT:    phaddd %xmm1, %xmm2
501 ; SSSE3_FAST-NEXT:    phaddd %xmm0, %xmm0
502 ; SSSE3_FAST-NEXT:    movdqa %xmm2, %xmm1
503 ; SSSE3_FAST-NEXT:    retq
505 ; AVX1_SLOW-LABEL: hadd_v8i32a:
506 ; AVX1_SLOW:       # %bb.0:
507 ; AVX1_SLOW-NEXT:    vextractf128 $1, %ymm0, %xmm1
508 ; AVX1_SLOW-NEXT:    vphaddd %xmm1, %xmm0, %xmm0
509 ; AVX1_SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[0,1,0,1]
510 ; AVX1_SLOW-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
511 ; AVX1_SLOW-NEXT:    retq
513 ; AVX1_FAST-LABEL: hadd_v8i32a:
514 ; AVX1_FAST:       # %bb.0:
515 ; AVX1_FAST-NEXT:    vextractf128 $1, %ymm0, %xmm1
516 ; AVX1_FAST-NEXT:    vphaddd %xmm1, %xmm0, %xmm1
517 ; AVX1_FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
518 ; AVX1_FAST-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
519 ; AVX1_FAST-NEXT:    retq
521 ; AVX2-LABEL: hadd_v8i32a:
522 ; AVX2:       # %bb.0:
523 ; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
524 ; AVX2-NEXT:    vphaddd %xmm1, %xmm0, %xmm0
525 ; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,0,2,1]
526 ; AVX2-NEXT:    retq
527   %a0 = shufflevector <8 x i32> %a, <8 x i32> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
528   %a1 = shufflevector <8 x i32> %a, <8 x i32> undef, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
529   %hop = add <4 x i32> %a0, %a1
530   %shuf = shufflevector <4 x i32> %hop, <4 x i32> undef, <8 x i32> <i32 undef, i32 undef, i32 0, i32 1, i32 undef, i32 undef, i32 2, i32 3>
531   ret <8 x i32> %shuf
534 define <8 x i32> @hadd_v8i32b(<8 x i32> %a) {
535 ; SSE3-LABEL: hadd_v8i32b:
536 ; SSE3:       # %bb.0:
537 ; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[1,3,1,3]
538 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,0,2]
539 ; SSE3-NEXT:    paddd %xmm2, %xmm0
540 ; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[1,3,1,3]
541 ; SSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,0,2]
542 ; SSE3-NEXT:    paddd %xmm2, %xmm1
543 ; SSE3-NEXT:    retq
545 ; SSSE3-LABEL: hadd_v8i32b:
546 ; SSSE3:       # %bb.0:
547 ; SSSE3-NEXT:    phaddd %xmm0, %xmm0
548 ; SSSE3-NEXT:    phaddd %xmm1, %xmm1
549 ; SSSE3-NEXT:    retq
551 ; AVX1-LABEL: hadd_v8i32b:
552 ; AVX1:       # %bb.0:
553 ; AVX1-NEXT:    vphaddd %xmm0, %xmm0, %xmm1
554 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
555 ; AVX1-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
556 ; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
557 ; AVX1-NEXT:    retq
559 ; AVX2-LABEL: hadd_v8i32b:
560 ; AVX2:       # %bb.0:
561 ; AVX2-NEXT:    vphaddd %ymm0, %ymm0, %ymm0
562 ; AVX2-NEXT:    retq
563   %a0 = shufflevector <8 x i32> %a, <8 x i32> undef, <8 x i32> <i32 0, i32 2, i32 undef, i32 undef, i32 4, i32 6, i32 undef, i32 undef>
564   %a1 = shufflevector <8 x i32> %a, <8 x i32> undef, <8 x i32> <i32 1, i32 3, i32 undef, i32 undef, i32 5, i32 7, i32 undef, i32 undef>
565   %hop = add <8 x i32> %a0, %a1
566   %shuf = shufflevector <8 x i32> %hop, <8 x i32> undef, <8 x i32> <i32 0, i32 1, i32 0, i32 1, i32 4, i32 5, i32 4, i32 5>
567   ret <8 x i32> %shuf
570 define <4 x i32> @hsub_v4i32(<4 x i32> %a) {
571 ; SSE3-LABEL: hsub_v4i32:
572 ; SSE3:       # %bb.0:
573 ; SSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[0,3,1,3]
574 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,0,3]
575 ; SSE3-NEXT:    psubd %xmm1, %xmm0
576 ; SSE3-NEXT:    retq
578 ; SSSE3-LABEL: hsub_v4i32:
579 ; SSSE3:       # %bb.0:
580 ; SSSE3-NEXT:    phsubd %xmm0, %xmm0
581 ; SSSE3-NEXT:    retq
583 ; AVX-LABEL: hsub_v4i32:
584 ; AVX:       # %bb.0:
585 ; AVX-NEXT:    vphsubd %xmm0, %xmm0, %xmm0
586 ; AVX-NEXT:    retq
587   %a02 = shufflevector <4 x i32> %a, <4 x i32> undef, <4 x i32> <i32 0, i32 2, i32 undef, i32 undef>
588   %a13 = shufflevector <4 x i32> %a, <4 x i32> undef, <4 x i32> <i32 1, i32 3, i32 undef, i32 undef>
589   %hop = sub <4 x i32> %a02, %a13
590   %shuf = shufflevector <4 x i32> %hop, <4 x i32> undef, <4 x i32> <i32 undef, i32 1, i32 0, i32 undef>
591   ret <4 x i32> %shuf
594 define <8 x i32> @hsub_v8i32a(<8 x i32> %a) {
595 ; SSE3-LABEL: hsub_v8i32a:
596 ; SSE3:       # %bb.0:
597 ; SSE3-NEXT:    movaps %xmm0, %xmm2
598 ; SSE3-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,2],xmm1[0,2]
599 ; SSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,3],xmm1[1,3]
600 ; SSE3-NEXT:    psubd %xmm0, %xmm2
601 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,1,0,1]
602 ; SSE3-NEXT:    movdqa %xmm2, %xmm1
603 ; SSE3-NEXT:    retq
605 ; SSSE3_SLOW-LABEL: hsub_v8i32a:
606 ; SSSE3_SLOW:       # %bb.0:
607 ; SSSE3_SLOW-NEXT:    movdqa %xmm0, %xmm2
608 ; SSSE3_SLOW-NEXT:    phsubd %xmm1, %xmm2
609 ; SSSE3_SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,1,0,1]
610 ; SSSE3_SLOW-NEXT:    movdqa %xmm2, %xmm1
611 ; SSSE3_SLOW-NEXT:    retq
613 ; SSSE3_FAST-LABEL: hsub_v8i32a:
614 ; SSSE3_FAST:       # %bb.0:
615 ; SSSE3_FAST-NEXT:    movdqa %xmm0, %xmm2
616 ; SSSE3_FAST-NEXT:    phsubd %xmm1, %xmm2
617 ; SSSE3_FAST-NEXT:    phsubd %xmm0, %xmm0
618 ; SSSE3_FAST-NEXT:    movdqa %xmm2, %xmm1
619 ; SSSE3_FAST-NEXT:    retq
621 ; AVX1_SLOW-LABEL: hsub_v8i32a:
622 ; AVX1_SLOW:       # %bb.0:
623 ; AVX1_SLOW-NEXT:    vextractf128 $1, %ymm0, %xmm1
624 ; AVX1_SLOW-NEXT:    vphsubd %xmm1, %xmm0, %xmm0
625 ; AVX1_SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[0,1,0,1]
626 ; AVX1_SLOW-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
627 ; AVX1_SLOW-NEXT:    retq
629 ; AVX1_FAST-LABEL: hsub_v8i32a:
630 ; AVX1_FAST:       # %bb.0:
631 ; AVX1_FAST-NEXT:    vextractf128 $1, %ymm0, %xmm1
632 ; AVX1_FAST-NEXT:    vphsubd %xmm1, %xmm0, %xmm1
633 ; AVX1_FAST-NEXT:    vphsubd %xmm0, %xmm0, %xmm0
634 ; AVX1_FAST-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
635 ; AVX1_FAST-NEXT:    retq
637 ; AVX2-LABEL: hsub_v8i32a:
638 ; AVX2:       # %bb.0:
639 ; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
640 ; AVX2-NEXT:    vphsubd %xmm1, %xmm0, %xmm0
641 ; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,0,2,1]
642 ; AVX2-NEXT:    retq
643   %a0 = shufflevector <8 x i32> %a, <8 x i32> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
644   %a1 = shufflevector <8 x i32> %a, <8 x i32> undef, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
645   %hop = sub <4 x i32> %a0, %a1
646   %shuf = shufflevector <4 x i32> %hop, <4 x i32> undef, <8 x i32> <i32 undef, i32 undef, i32 0, i32 1, i32 undef, i32 undef, i32 2, i32 3>
647   ret <8 x i32> %shuf
650 define <8 x i32> @hsub_v8i32b(<8 x i32> %a) {
651 ; SSE3-LABEL: hsub_v8i32b:
652 ; SSE3:       # %bb.0:
653 ; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[1,3,1,3]
654 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,0,2]
655 ; SSE3-NEXT:    psubd %xmm2, %xmm0
656 ; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[1,3,1,3]
657 ; SSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,0,2]
658 ; SSE3-NEXT:    psubd %xmm2, %xmm1
659 ; SSE3-NEXT:    retq
661 ; SSSE3-LABEL: hsub_v8i32b:
662 ; SSSE3:       # %bb.0:
663 ; SSSE3-NEXT:    phsubd %xmm0, %xmm0
664 ; SSSE3-NEXT:    phsubd %xmm1, %xmm1
665 ; SSSE3-NEXT:    retq
667 ; AVX1-LABEL: hsub_v8i32b:
668 ; AVX1:       # %bb.0:
669 ; AVX1-NEXT:    vphsubd %xmm0, %xmm0, %xmm1
670 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
671 ; AVX1-NEXT:    vphsubd %xmm0, %xmm0, %xmm0
672 ; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
673 ; AVX1-NEXT:    retq
675 ; AVX2-LABEL: hsub_v8i32b:
676 ; AVX2:       # %bb.0:
677 ; AVX2-NEXT:    vphsubd %ymm0, %ymm0, %ymm0
678 ; AVX2-NEXT:    retq
679   %a0 = shufflevector <8 x i32> %a, <8 x i32> undef, <8 x i32> <i32 0, i32 2, i32 undef, i32 undef, i32 4, i32 6, i32 undef, i32 undef>
680   %a1 = shufflevector <8 x i32> %a, <8 x i32> undef, <8 x i32> <i32 1, i32 3, i32 undef, i32 undef, i32 5, i32 7, i32 undef, i32 undef>
681   %hop = sub <8 x i32> %a0, %a1
682   %shuf = shufflevector <8 x i32> %hop, <8 x i32> undef, <8 x i32> <i32 0, i32 1, i32 0, i32 1, i32 4, i32 5, i32 4, i32 5>
683   ret <8 x i32> %shuf
686 define <8 x i16> @hadd_v8i16(<8 x i16> %a) {
687 ; SSE3-LABEL: hadd_v8i16:
688 ; SSE3:       # %bb.0:
689 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm1 = xmm0[0,2,2,3,4,5,6,7]
690 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm1 = xmm1[0,1,2,3,4,6,6,7]
691 ; SSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,1,0,2]
692 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[3,1,2,3,4,5,6,7]
693 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,5,6,7]
694 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,1,2,0]
695 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,6,5,4]
696 ; SSE3-NEXT:    paddw %xmm1, %xmm0
697 ; SSE3-NEXT:    retq
699 ; SSSE3-LABEL: hadd_v8i16:
700 ; SSSE3:       # %bb.0:
701 ; SSSE3-NEXT:    phaddw %xmm0, %xmm0
702 ; SSSE3-NEXT:    retq
704 ; AVX-LABEL: hadd_v8i16:
705 ; AVX:       # %bb.0:
706 ; AVX-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
707 ; AVX-NEXT:    retq
708   %a0246 = shufflevector <8 x i16> %a, <8 x i16> undef, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 undef, i32 undef, i32 undef, i32 undef>
709   %a1357 = shufflevector <8 x i16> %a, <8 x i16> undef, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
710   %hop = add <8 x i16> %a0246, %a1357
711   %shuf = shufflevector <8 x i16> %hop, <8 x i16> undef, <8 x i32> <i32 undef, i32 undef, i32 undef, i32 undef, i32 0, i32 1, i32 2, i32 3>
712   ret <8 x i16> %shuf
715 define <16 x i16> @hadd_v16i16a(<16 x i16> %a) {
716 ; SSE3-LABEL: hadd_v16i16a:
717 ; SSE3:       # %bb.0:
718 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm2 = xmm1[0,2,2,3,4,5,6,7]
719 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm2 = xmm2[0,1,2,3,4,6,6,7]
720 ; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,2,2,3]
721 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm3 = xmm0[0,2,2,3,4,5,6,7]
722 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm3 = xmm3[0,1,2,3,4,6,6,7]
723 ; SSE3-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[0,2,2,3]
724 ; SSE3-NEXT:    punpcklqdq {{.*#+}} xmm3 = xmm3[0],xmm2[0]
725 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[3,1,2,3,4,5,6,7]
726 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm1 = xmm1[0,1,2,3,7,5,6,7]
727 ; SSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
728 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm2 = xmm1[1,0,3,2,4,5,6,7]
729 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[3,1,2,3,4,5,6,7]
730 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,5,6,7]
731 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
732 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm1 = xmm0[1,0,3,2,4,5,6,7]
733 ; SSE3-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]
734 ; SSE3-NEXT:    paddw %xmm3, %xmm1
735 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[0,1,0,1]
736 ; SSE3-NEXT:    retq
738 ; SSSE3_SLOW-LABEL: hadd_v16i16a:
739 ; SSSE3_SLOW:       # %bb.0:
740 ; SSSE3_SLOW-NEXT:    movdqa %xmm0, %xmm2
741 ; SSSE3_SLOW-NEXT:    phaddw %xmm1, %xmm2
742 ; SSSE3_SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,1,0,1]
743 ; SSSE3_SLOW-NEXT:    movdqa %xmm2, %xmm1
744 ; SSSE3_SLOW-NEXT:    retq
746 ; SSSE3_FAST-LABEL: hadd_v16i16a:
747 ; SSSE3_FAST:       # %bb.0:
748 ; SSSE3_FAST-NEXT:    movdqa %xmm0, %xmm2
749 ; SSSE3_FAST-NEXT:    phaddw %xmm1, %xmm2
750 ; SSSE3_FAST-NEXT:    phaddw %xmm0, %xmm0
751 ; SSSE3_FAST-NEXT:    movdqa %xmm2, %xmm1
752 ; SSSE3_FAST-NEXT:    retq
754 ; AVX1_SLOW-LABEL: hadd_v16i16a:
755 ; AVX1_SLOW:       # %bb.0:
756 ; AVX1_SLOW-NEXT:    vextractf128 $1, %ymm0, %xmm1
757 ; AVX1_SLOW-NEXT:    vphaddw %xmm1, %xmm0, %xmm0
758 ; AVX1_SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[0,1,0,1]
759 ; AVX1_SLOW-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
760 ; AVX1_SLOW-NEXT:    retq
762 ; AVX1_FAST-LABEL: hadd_v16i16a:
763 ; AVX1_FAST:       # %bb.0:
764 ; AVX1_FAST-NEXT:    vextractf128 $1, %ymm0, %xmm1
765 ; AVX1_FAST-NEXT:    vphaddw %xmm1, %xmm0, %xmm1
766 ; AVX1_FAST-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
767 ; AVX1_FAST-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
768 ; AVX1_FAST-NEXT:    retq
770 ; AVX2-LABEL: hadd_v16i16a:
771 ; AVX2:       # %bb.0:
772 ; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
773 ; AVX2-NEXT:    vphaddw %xmm1, %xmm0, %xmm0
774 ; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,0,2,1]
775 ; AVX2-NEXT:    retq
776   %a0 = shufflevector <16 x i16> %a, <16 x i16> undef, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>
777   %a1 = shufflevector <16 x i16> %a, <16 x i16> undef, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15>
778   %hop = add <8 x i16> %a0, %a1
779   %shuf = shufflevector <8 x i16> %hop, <8 x i16> undef, <16 x i32> <i32 undef, i32 undef, i32 undef, i32 undef, i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 4, i32 5, i32 6, i32 7>
780   ret <16 x i16> %shuf
783 define <16 x i16> @hadd_v16i16b(<16 x i16> %a) {
784 ; SSE3-LABEL: hadd_v16i16b:
785 ; SSE3:       # %bb.0:
786 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm2 = xmm0[3,1,1,3,4,5,6,7]
787 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm2 = xmm2[0,1,2,3,7,5,5,7]
788 ; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,3,2,1]
789 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm2 = xmm2[1,0,2,3,4,5,6,7]
790 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm2 = xmm2[0,1,2,3,6,7,5,4]
791 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,2,2,0,4,5,6,7]
792 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,4,6,6,4]
793 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,3,2,1]
794 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,1,3,2,4,5,6,7]
795 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,6,4,5]
796 ; SSE3-NEXT:    paddw %xmm2, %xmm0
797 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm2 = xmm1[3,1,1,3,4,5,6,7]
798 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm2 = xmm2[0,1,2,3,7,5,5,7]
799 ; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,3,2,1]
800 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm2 = xmm2[1,0,2,3,4,5,6,7]
801 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm2 = xmm2[0,1,2,3,6,7,5,4]
802 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,0,4,5,6,7]
803 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm1 = xmm1[0,1,2,3,4,6,6,4]
804 ; SSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,3,2,1]
805 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,1,3,2,4,5,6,7]
806 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm1 = xmm1[0,1,2,3,7,6,4,5]
807 ; SSE3-NEXT:    paddw %xmm2, %xmm1
808 ; SSE3-NEXT:    retq
810 ; SSSE3-LABEL: hadd_v16i16b:
811 ; SSSE3:       # %bb.0:
812 ; SSSE3-NEXT:    phaddw %xmm0, %xmm0
813 ; SSSE3-NEXT:    phaddw %xmm1, %xmm1
814 ; SSSE3-NEXT:    retq
816 ; AVX1-LABEL: hadd_v16i16b:
817 ; AVX1:       # %bb.0:
818 ; AVX1-NEXT:    vphaddw %xmm0, %xmm0, %xmm1
819 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
820 ; AVX1-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
821 ; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
822 ; AVX1-NEXT:    retq
824 ; AVX2-LABEL: hadd_v16i16b:
825 ; AVX2:       # %bb.0:
826 ; AVX2-NEXT:    vphaddw %ymm0, %ymm0, %ymm0
827 ; AVX2-NEXT:    retq
828   %a0 = shufflevector <16 x i16> %a, <16 x i16> undef, <16 x i32> <i32 0, i32 2, i32 4, i32 6, i32 undef, i32 undef, i32 undef, i32 undef, i32 8, i32 10, i32 12, i32 14, i32 undef, i32 undef, i32 undef, i32 undef>
829   %a1 = shufflevector <16 x i16> %a, <16 x i16> undef, <16 x i32> <i32 1, i32 3, i32 5, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 9, i32 11, i32 13, i32 15, i32 undef, i32 undef, i32 undef, i32 undef>
830   %hop = add <16 x i16> %a0, %a1
831   %shuf = shufflevector <16 x i16> %hop, <16 x i16> undef, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11, i32 8, i32 9, i32 10, i32 11>
832   ret <16 x i16> %shuf
835 define <8 x i16> @hsub_v8i16(<8 x i16> %a) {
836 ; SSE3-LABEL: hsub_v8i16:
837 ; SSE3:       # %bb.0:
838 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,1,3]
839 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm1 = xmm0[1,1,3,3,4,5,6,7]
840 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,4,4,6,6]
841 ; SSE3-NEXT:    psubw %xmm1, %xmm0
842 ; SSE3-NEXT:    retq
844 ; SSSE3-LABEL: hsub_v8i16:
845 ; SSSE3:       # %bb.0:
846 ; SSSE3-NEXT:    phsubw %xmm0, %xmm0
847 ; SSSE3-NEXT:    retq
849 ; AVX-LABEL: hsub_v8i16:
850 ; AVX:       # %bb.0:
851 ; AVX-NEXT:    vphsubw %xmm0, %xmm0, %xmm0
852 ; AVX-NEXT:    retq
853   %a0246 = shufflevector <8 x i16> %a, <8 x i16> undef, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 undef, i32 undef, i32 undef, i32 undef>
854   %a1357 = shufflevector <8 x i16> %a, <8 x i16> undef, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
855   %hop = sub <8 x i16> %a0246, %a1357
856   %shuf = shufflevector <8 x i16> %hop, <8 x i16> undef, <8 x i32> <i32 0, i32 undef, i32 2, i32 undef, i32 undef, i32 1, i32 undef, i32 3>
857   ret <8 x i16> %shuf
860 define <16 x i16> @hsub_v16i16a(<16 x i16> %a) {
861 ; SSE3-LABEL: hsub_v16i16a:
862 ; SSE3:       # %bb.0:
863 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm2 = xmm1[0,2,2,3,4,5,6,7]
864 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm2 = xmm2[0,1,2,3,4,6,6,7]
865 ; SSE3-NEXT:    pshufd {{.*#+}} xmm3 = xmm2[0,2,2,3]
866 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm2 = xmm0[0,2,2,3,4,5,6,7]
867 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm2 = xmm2[0,1,2,3,4,6,6,7]
868 ; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,2,2,3]
869 ; SSE3-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
870 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[3,1,2,3,4,5,6,7]
871 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm1 = xmm1[0,1,2,3,7,5,6,7]
872 ; SSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
873 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[1,0,3,2,4,5,6,7]
874 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[3,1,2,3,4,5,6,7]
875 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,5,6,7]
876 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
877 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[1,0,3,2,4,5,6,7]
878 ; SSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
879 ; SSE3-NEXT:    psubw %xmm0, %xmm2
880 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,1,0,1]
881 ; SSE3-NEXT:    movdqa %xmm2, %xmm1
882 ; SSE3-NEXT:    retq
884 ; SSSE3_SLOW-LABEL: hsub_v16i16a:
885 ; SSSE3_SLOW:       # %bb.0:
886 ; SSSE3_SLOW-NEXT:    movdqa %xmm0, %xmm2
887 ; SSSE3_SLOW-NEXT:    phsubw %xmm1, %xmm2
888 ; SSSE3_SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[0,1,0,1]
889 ; SSSE3_SLOW-NEXT:    movdqa %xmm2, %xmm1
890 ; SSSE3_SLOW-NEXT:    retq
892 ; SSSE3_FAST-LABEL: hsub_v16i16a:
893 ; SSSE3_FAST:       # %bb.0:
894 ; SSSE3_FAST-NEXT:    movdqa %xmm0, %xmm2
895 ; SSSE3_FAST-NEXT:    phsubw %xmm1, %xmm2
896 ; SSSE3_FAST-NEXT:    phsubw %xmm0, %xmm0
897 ; SSSE3_FAST-NEXT:    movdqa %xmm2, %xmm1
898 ; SSSE3_FAST-NEXT:    retq
900 ; AVX1_SLOW-LABEL: hsub_v16i16a:
901 ; AVX1_SLOW:       # %bb.0:
902 ; AVX1_SLOW-NEXT:    vextractf128 $1, %ymm0, %xmm1
903 ; AVX1_SLOW-NEXT:    vphsubw %xmm1, %xmm0, %xmm0
904 ; AVX1_SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[0,1,0,1]
905 ; AVX1_SLOW-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
906 ; AVX1_SLOW-NEXT:    retq
908 ; AVX1_FAST-LABEL: hsub_v16i16a:
909 ; AVX1_FAST:       # %bb.0:
910 ; AVX1_FAST-NEXT:    vextractf128 $1, %ymm0, %xmm1
911 ; AVX1_FAST-NEXT:    vphsubw %xmm1, %xmm0, %xmm1
912 ; AVX1_FAST-NEXT:    vphsubw %xmm0, %xmm0, %xmm0
913 ; AVX1_FAST-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
914 ; AVX1_FAST-NEXT:    retq
916 ; AVX2-LABEL: hsub_v16i16a:
917 ; AVX2:       # %bb.0:
918 ; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
919 ; AVX2-NEXT:    vphsubw %xmm1, %xmm0, %xmm0
920 ; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,0,2,1]
921 ; AVX2-NEXT:    retq
922   %a0 = shufflevector <16 x i16> %a, <16 x i16> undef, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>
923   %a1 = shufflevector <16 x i16> %a, <16 x i16> undef, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15>
924   %hop = sub <8 x i16> %a0, %a1
925   %shuf = shufflevector <8 x i16> %hop, <8 x i16> undef, <16 x i32> <i32 undef, i32 undef, i32 undef, i32 undef, i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 4, i32 5, i32 6, i32 7>
926   ret <16 x i16> %shuf
929 define <16 x i16> @hsub_v16i16b(<16 x i16> %a) {
930 ; SSE3-LABEL: hsub_v16i16b:
931 ; SSE3:       # %bb.0:
932 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm2 = xmm0[3,1,1,3,4,5,6,7]
933 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm2 = xmm2[0,1,2,3,7,5,5,7]
934 ; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,3,2,1]
935 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm2 = xmm2[1,0,2,3,4,5,6,7]
936 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm2 = xmm2[0,1,2,3,6,7,5,4]
937 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,2,2,0,4,5,6,7]
938 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,4,6,6,4]
939 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,3,2,1]
940 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,1,3,2,4,5,6,7]
941 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,6,4,5]
942 ; SSE3-NEXT:    psubw %xmm2, %xmm0
943 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm2 = xmm1[3,1,1,3,4,5,6,7]
944 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm2 = xmm2[0,1,2,3,7,5,5,7]
945 ; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,3,2,1]
946 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm2 = xmm2[1,0,2,3,4,5,6,7]
947 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm2 = xmm2[0,1,2,3,6,7,5,4]
948 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,0,4,5,6,7]
949 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm1 = xmm1[0,1,2,3,4,6,6,4]
950 ; SSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,3,2,1]
951 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,1,3,2,4,5,6,7]
952 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm1 = xmm1[0,1,2,3,7,6,4,5]
953 ; SSE3-NEXT:    psubw %xmm2, %xmm1
954 ; SSE3-NEXT:    retq
956 ; SSSE3-LABEL: hsub_v16i16b:
957 ; SSSE3:       # %bb.0:
958 ; SSSE3-NEXT:    phsubw %xmm0, %xmm0
959 ; SSSE3-NEXT:    phsubw %xmm1, %xmm1
960 ; SSSE3-NEXT:    retq
962 ; AVX1-LABEL: hsub_v16i16b:
963 ; AVX1:       # %bb.0:
964 ; AVX1-NEXT:    vphsubw %xmm0, %xmm0, %xmm1
965 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
966 ; AVX1-NEXT:    vphsubw %xmm0, %xmm0, %xmm0
967 ; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
968 ; AVX1-NEXT:    retq
970 ; AVX2-LABEL: hsub_v16i16b:
971 ; AVX2:       # %bb.0:
972 ; AVX2-NEXT:    vphsubw %ymm0, %ymm0, %ymm0
973 ; AVX2-NEXT:    retq
974   %a0 = shufflevector <16 x i16> %a, <16 x i16> undef, <16 x i32> <i32 0, i32 2, i32 4, i32 6, i32 undef, i32 undef, i32 undef, i32 undef, i32 8, i32 10, i32 12, i32 14, i32 undef, i32 undef, i32 undef, i32 undef>
975   %a1 = shufflevector <16 x i16> %a, <16 x i16> undef, <16 x i32> <i32 1, i32 3, i32 5, i32 7, i32 undef, i32 undef, i32 undef, i32 undef, i32 9, i32 11, i32 13, i32 15, i32 undef, i32 undef, i32 undef, i32 undef>
976   %hop = sub <16 x i16> %a0, %a1
977   %shuf = shufflevector <16 x i16> %hop, <16 x i16> undef, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11, i32 8, i32 9, i32 10, i32 11>
978   ret <16 x i16> %shuf
981 define <4 x float> @broadcast_haddps_v4f32(<4 x float> %a0) {
982 ; SSE-LABEL: broadcast_haddps_v4f32:
983 ; SSE:       # %bb.0:
984 ; SSE-NEXT:    haddps %xmm0, %xmm0
985 ; SSE-NEXT:    movsldup {{.*#+}} xmm0 = xmm0[0,0,2,2]
986 ; SSE-NEXT:    retq
988 ; AVX1-LABEL: broadcast_haddps_v4f32:
989 ; AVX1:       # %bb.0:
990 ; AVX1-NEXT:    vhaddps %xmm0, %xmm0, %xmm0
991 ; AVX1-NEXT:    vmovsldup {{.*#+}} xmm0 = xmm0[0,0,2,2]
992 ; AVX1-NEXT:    retq
994 ; AVX2-LABEL: broadcast_haddps_v4f32:
995 ; AVX2:       # %bb.0:
996 ; AVX2-NEXT:    vhaddps %xmm0, %xmm0, %xmm0
997 ; AVX2-NEXT:    vbroadcastss %xmm0, %xmm0
998 ; AVX2-NEXT:    retq
999   %1 = tail call <4 x float> @llvm.x86.sse3.hadd.ps(<4 x float> %a0, <4 x float> %a0)
1000   %2 = shufflevector <4 x float> %1, <4 x float> undef, <4 x i32> zeroinitializer
1001   ret <4 x float> %2
1004 declare <4 x float> @llvm.x86.sse3.hadd.ps(<4 x float>, <4 x float>)
1006 define <4 x float> @PR34724_1(<4 x float> %a, <4 x float> %b) {
1007 ; SSE-LABEL: PR34724_1:
1008 ; SSE:       # %bb.0:
1009 ; SSE-NEXT:    haddps %xmm1, %xmm0
1010 ; SSE-NEXT:    retq
1012 ; AVX-LABEL: PR34724_1:
1013 ; AVX:       # %bb.0:
1014 ; AVX-NEXT:    vhaddps %xmm1, %xmm0, %xmm0
1015 ; AVX-NEXT:    retq
1016   %t0 = shufflevector <4 x float> %a, <4 x float> %b, <2 x i32> <i32 2, i32 4>
1017   %t1 = shufflevector <4 x float> %a, <4 x float> %b, <2 x i32> <i32 3, i32 5>
1018   %t2 = fadd <2 x float> %t0, %t1
1019   %vecinit9 = shufflevector <2 x float> %t2, <2 x float> undef, <4 x i32> <i32 undef, i32 0, i32 1, i32 undef>
1020   %t3 = shufflevector <4 x float> %b, <4 x float> undef, <4 x i32> <i32 undef, i32 undef, i32 undef, i32 2>
1021   %t4 = fadd <4 x float> %t3, %b
1022   %vecinit13 = shufflevector <4 x float> %vecinit9, <4 x float> %t4, <4 x i32> <i32 undef, i32 1, i32 2, i32 7>
1023   ret <4 x float> %vecinit13
1026 define <4 x float> @PR34724_2(<4 x float> %a, <4 x float> %b) {
1027 ; SSE-LABEL: PR34724_2:
1028 ; SSE:       # %bb.0:
1029 ; SSE-NEXT:    haddps %xmm1, %xmm0
1030 ; SSE-NEXT:    retq
1032 ; AVX-LABEL: PR34724_2:
1033 ; AVX:       # %bb.0:
1034 ; AVX-NEXT:    vhaddps %xmm1, %xmm0, %xmm0
1035 ; AVX-NEXT:    retq
1036   %t0 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 2, i32 4, i32 undef, i32 undef>
1037   %t1 = shufflevector <4 x float> %a, <4 x float> %b, <4 x i32> <i32 3, i32 5, i32 undef, i32 undef>
1038   %t2 = fadd <4 x float> %t0, %t1
1039   %vecinit9 = shufflevector <4 x float> %t2, <4 x float> undef, <4 x i32> <i32 undef, i32 0, i32 1, i32 undef>
1040   %t3 = shufflevector <4 x float> %b, <4 x float> undef, <4 x i32> <i32 undef, i32 undef, i32 undef, i32 2>
1041   %t4 = fadd <4 x float> %t3, %b
1042   %vecinit13 = shufflevector <4 x float> %vecinit9, <4 x float> %t4, <4 x i32> <i32 undef, i32 1, i32 2, i32 7>
1043   ret <4 x float> %vecinit13
1047 ; fold HOP(LOSUBVECTOR(SHUFFLE(X)),HISUBVECTOR(SHUFFLE(X)))
1048 ;  --> SHUFFLE(HOP(LOSUBVECTOR(X),HISUBVECTOR(X))).
1051 define <4 x float> @hadd_4f32_v8f32_shuffle(<8 x float> %a0) {
1052 ; SSE-LABEL: hadd_4f32_v8f32_shuffle:
1053 ; SSE:       # %bb.0:
1054 ; SSE-NEXT:    haddps %xmm1, %xmm0
1055 ; SSE-NEXT:    movshdup {{.*#+}} xmm0 = xmm0[1,1,3,3]
1056 ; SSE-NEXT:    retq
1058 ; AVX-LABEL: hadd_4f32_v8f32_shuffle:
1059 ; AVX:       # %bb.0:
1060 ; AVX-NEXT:    vextractf128 $1, %ymm0, %xmm1
1061 ; AVX-NEXT:    vhaddps %xmm1, %xmm0, %xmm0
1062 ; AVX-NEXT:    vmovshdup {{.*#+}} xmm0 = xmm0[1,1,3,3]
1063 ; AVX-NEXT:    vzeroupper
1064 ; AVX-NEXT:    retq
1065   %shuf256 = shufflevector <8 x float> %a0, <8 x float> undef, <8 x i32> <i32 2, i32 3, i32 2, i32 3, i32 6, i32 7, i32 6, i32 7>
1066   %lo = shufflevector <8 x float> %shuf256, <8 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1067   %hi = shufflevector <8 x float> %shuf256, <8 x float> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
1068   %hadd0 = shufflevector <4 x float> %lo, <4 x float> %hi, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
1069   %hadd1 = shufflevector <4 x float> %lo, <4 x float> %hi, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
1070   %hadd = fadd <4 x float> %hadd0, %hadd1
1071   ret <4 x float> %hadd
1074 define <4 x float> @hsub_4f32_v8f32_shuffle(<8 x float> %a0) {
1075 ; SSE-LABEL: hsub_4f32_v8f32_shuffle:
1076 ; SSE:       # %bb.0:
1077 ; SSE-NEXT:    haddps %xmm1, %xmm0
1078 ; SSE-NEXT:    movshdup {{.*#+}} xmm0 = xmm0[1,1,3,3]
1079 ; SSE-NEXT:    retq
1081 ; AVX-LABEL: hsub_4f32_v8f32_shuffle:
1082 ; AVX:       # %bb.0:
1083 ; AVX-NEXT:    vextractf128 $1, %ymm0, %xmm1
1084 ; AVX-NEXT:    vhaddps %xmm1, %xmm0, %xmm0
1085 ; AVX-NEXT:    vmovshdup {{.*#+}} xmm0 = xmm0[1,1,3,3]
1086 ; AVX-NEXT:    vzeroupper
1087 ; AVX-NEXT:    retq
1088   %shuf256 = shufflevector <8 x float> %a0, <8 x float> undef, <8 x i32> <i32 2, i32 3, i32 2, i32 3, i32 6, i32 7, i32 6, i32 7>
1089   %lo = shufflevector <8 x float> %shuf256, <8 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1090   %hi = shufflevector <8 x float> %shuf256, <8 x float> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
1091   %hsub0 = shufflevector <4 x float> %lo, <4 x float> %hi, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
1092   %hsub1 = shufflevector <4 x float> %lo, <4 x float> %hi, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
1093   %hsub = fadd <4 x float> %hsub0, %hsub1
1094   ret <4 x float> %hsub
1097 define <4 x i32> @hadd_4i32_v8i32_shuffle(<8 x i32> %a0) {
1098 ; SSE3-LABEL: hadd_4i32_v8i32_shuffle:
1099 ; SSE3:       # %bb.0:
1100 ; SSE3-NEXT:    movaps %xmm0, %xmm2
1101 ; SSE3-NEXT:    shufps {{.*#+}} xmm2 = xmm2[2,2],xmm1[2,2]
1102 ; SSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3],xmm1[3,3]
1103 ; SSE3-NEXT:    paddd %xmm2, %xmm0
1104 ; SSE3-NEXT:    retq
1106 ; SSSE3-LABEL: hadd_4i32_v8i32_shuffle:
1107 ; SSSE3:       # %bb.0:
1108 ; SSSE3-NEXT:    phaddd %xmm1, %xmm0
1109 ; SSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
1110 ; SSSE3-NEXT:    retq
1112 ; AVX1-LABEL: hadd_4i32_v8i32_shuffle:
1113 ; AVX1:       # %bb.0:
1114 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
1115 ; AVX1-NEXT:    vphaddd %xmm1, %xmm0, %xmm0
1116 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
1117 ; AVX1-NEXT:    vzeroupper
1118 ; AVX1-NEXT:    retq
1120 ; AVX2-LABEL: hadd_4i32_v8i32_shuffle:
1121 ; AVX2:       # %bb.0:
1122 ; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
1123 ; AVX2-NEXT:    vphaddd %xmm1, %xmm0, %xmm0
1124 ; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
1125 ; AVX2-NEXT:    vzeroupper
1126 ; AVX2-NEXT:    retq
1127   %shuf256 = shufflevector <8 x i32> %a0, <8 x i32> undef, <8 x i32> <i32 2, i32 3, i32 2, i32 3, i32 6, i32 7, i32 6, i32 7>
1128   %lo = shufflevector <8 x i32> %shuf256, <8 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1129   %hi = shufflevector <8 x i32> %shuf256, <8 x i32> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
1130   %hadd0 = shufflevector <4 x i32> %lo, <4 x i32> %hi, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
1131   %hadd1 = shufflevector <4 x i32> %lo, <4 x i32> %hi, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
1132   %hadd = add <4 x i32> %hadd0, %hadd1
1133   ret <4 x i32> %hadd
1136 define <4 x i32> @hsub_4i32_v8i32_shuffle(<8 x i32> %a0) {
1137 ; SSE3-LABEL: hsub_4i32_v8i32_shuffle:
1138 ; SSE3:       # %bb.0:
1139 ; SSE3-NEXT:    movaps %xmm0, %xmm2
1140 ; SSE3-NEXT:    shufps {{.*#+}} xmm2 = xmm2[2,2],xmm1[2,2]
1141 ; SSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3],xmm1[3,3]
1142 ; SSE3-NEXT:    paddd %xmm2, %xmm0
1143 ; SSE3-NEXT:    retq
1145 ; SSSE3-LABEL: hsub_4i32_v8i32_shuffle:
1146 ; SSSE3:       # %bb.0:
1147 ; SSSE3-NEXT:    phaddd %xmm1, %xmm0
1148 ; SSSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
1149 ; SSSE3-NEXT:    retq
1151 ; AVX1-LABEL: hsub_4i32_v8i32_shuffle:
1152 ; AVX1:       # %bb.0:
1153 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
1154 ; AVX1-NEXT:    vphaddd %xmm1, %xmm0, %xmm0
1155 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
1156 ; AVX1-NEXT:    vzeroupper
1157 ; AVX1-NEXT:    retq
1159 ; AVX2-LABEL: hsub_4i32_v8i32_shuffle:
1160 ; AVX2:       # %bb.0:
1161 ; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
1162 ; AVX2-NEXT:    vphaddd %xmm1, %xmm0, %xmm0
1163 ; AVX2-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
1164 ; AVX2-NEXT:    vzeroupper
1165 ; AVX2-NEXT:    retq
1166   %shuf256 = shufflevector <8 x i32> %a0, <8 x i32> undef, <8 x i32> <i32 2, i32 3, i32 2, i32 3, i32 6, i32 7, i32 6, i32 7>
1167   %lo = shufflevector <8 x i32> %shuf256, <8 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1168   %hi = shufflevector <8 x i32> %shuf256, <8 x i32> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
1169   %hsub0 = shufflevector <4 x i32> %lo, <4 x i32> %hi, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
1170   %hsub1 = shufflevector <4 x i32> %lo, <4 x i32> %hi, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
1171   %hsub = add <4 x i32> %hsub0, %hsub1
1172   ret <4 x i32> %hsub
1176 ; fold HOP(SHUFFLE(X,Y),SHUFFLE(X,Y)) --> SHUFFLE(HOP(X,Y)).
1179 define <4 x double> @hadd_4f64_v4f64_shuffle(<4 x double> %a0, <4 x double> %a1) {
1180 ; SSE-LABEL: hadd_4f64_v4f64_shuffle:
1181 ; SSE:       # %bb.0:
1182 ; SSE-NEXT:    haddpd %xmm1, %xmm0
1183 ; SSE-NEXT:    haddpd %xmm3, %xmm2
1184 ; SSE-NEXT:    movapd %xmm2, %xmm1
1185 ; SSE-NEXT:    retq
1187 ; AVX1-LABEL: hadd_4f64_v4f64_shuffle:
1188 ; AVX1:       # %bb.0:
1189 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm2
1190 ; AVX1-NEXT:    vperm2f128 {{.*#+}} ymm0 = ymm0[2,3],ymm1[2,3]
1191 ; AVX1-NEXT:    vhaddpd %ymm0, %ymm2, %ymm0
1192 ; AVX1-NEXT:    retq
1194 ; AVX2-LABEL: hadd_4f64_v4f64_shuffle:
1195 ; AVX2:       # %bb.0:
1196 ; AVX2-NEXT:    vhaddpd %ymm1, %ymm0, %ymm0
1197 ; AVX2-NEXT:    vpermpd {{.*#+}} ymm0 = ymm0[0,2,1,3]
1198 ; AVX2-NEXT:    retq
1199   %shuf0 = shufflevector <4 x double> %a0, <4 x double> %a1, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
1200   %shuf1 = shufflevector <4 x double> %a0, <4 x double> %a1, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
1201   %hadd0 = shufflevector <4 x double> %shuf0, <4 x double> %shuf1, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
1202   %hadd1 = shufflevector <4 x double> %shuf0, <4 x double> %shuf1, <4 x i32> <i32 1, i32 5, i32 3, i32 7>
1203   %hadd = fadd <4 x double> %hadd0, %hadd1
1204   ret <4 x double> %hadd
1207 define <4 x double> @hsub_4f64_v4f64_shuffle(<4 x double> %a0, <4 x double> %a1) {
1208 ; SSE-LABEL: hsub_4f64_v4f64_shuffle:
1209 ; SSE:       # %bb.0:
1210 ; SSE-NEXT:    hsubpd %xmm1, %xmm0
1211 ; SSE-NEXT:    hsubpd %xmm3, %xmm2
1212 ; SSE-NEXT:    movapd %xmm2, %xmm1
1213 ; SSE-NEXT:    retq
1215 ; AVX1-LABEL: hsub_4f64_v4f64_shuffle:
1216 ; AVX1:       # %bb.0:
1217 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm2
1218 ; AVX1-NEXT:    vperm2f128 {{.*#+}} ymm0 = ymm0[2,3],ymm1[2,3]
1219 ; AVX1-NEXT:    vhsubpd %ymm0, %ymm2, %ymm0
1220 ; AVX1-NEXT:    retq
1222 ; AVX2-LABEL: hsub_4f64_v4f64_shuffle:
1223 ; AVX2:       # %bb.0:
1224 ; AVX2-NEXT:    vhsubpd %ymm1, %ymm0, %ymm0
1225 ; AVX2-NEXT:    vpermpd {{.*#+}} ymm0 = ymm0[0,2,1,3]
1226 ; AVX2-NEXT:    retq
1227   %shuf0 = shufflevector <4 x double> %a0, <4 x double> %a1, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
1228   %shuf1 = shufflevector <4 x double> %a0, <4 x double> %a1, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
1229   %hadd0 = shufflevector <4 x double> %shuf0, <4 x double> %shuf1, <4 x i32> <i32 0, i32 4, i32 2, i32 6>
1230   %hadd1 = shufflevector <4 x double> %shuf0, <4 x double> %shuf1, <4 x i32> <i32 1, i32 5, i32 3, i32 7>
1231   %hadd = fsub <4 x double> %hadd0, %hadd1
1232   ret <4 x double> %hadd
1235 define <8 x float> @hadd_8f32_v8f32_shuffle(<8 x float> %a0, <8 x float> %a1) {
1236 ; SSE-LABEL: hadd_8f32_v8f32_shuffle:
1237 ; SSE:       # %bb.0:
1238 ; SSE-NEXT:    haddps %xmm1, %xmm0
1239 ; SSE-NEXT:    haddps %xmm3, %xmm2
1240 ; SSE-NEXT:    movaps %xmm2, %xmm1
1241 ; SSE-NEXT:    retq
1243 ; AVX1-LABEL: hadd_8f32_v8f32_shuffle:
1244 ; AVX1:       # %bb.0:
1245 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm2
1246 ; AVX1-NEXT:    vperm2f128 {{.*#+}} ymm0 = ymm0[2,3],ymm1[2,3]
1247 ; AVX1-NEXT:    vhaddps %ymm0, %ymm2, %ymm0
1248 ; AVX1-NEXT:    retq
1250 ; AVX2-LABEL: hadd_8f32_v8f32_shuffle:
1251 ; AVX2:       # %bb.0:
1252 ; AVX2-NEXT:    vhaddps %ymm1, %ymm0, %ymm0
1253 ; AVX2-NEXT:    vpermpd {{.*#+}} ymm0 = ymm0[0,2,1,3]
1254 ; AVX2-NEXT:    retq
1255   %shuf0 = shufflevector <8 x float> %a0, <8 x float> %a1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11>
1256   %shuf1 = shufflevector <8 x float> %a0, <8 x float> %a1, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 12, i32 13, i32 14, i32 15>
1257   %hadd0 = shufflevector <8 x float> %shuf0, <8 x float> %shuf1, <8 x i32> <i32 0, i32 2, i32 8, i32 10, i32 4, i32 6, i32 12, i32 14>
1258   %hadd1 = shufflevector <8 x float> %shuf0, <8 x float> %shuf1, <8 x i32> <i32 1, i32 3, i32 9, i32 11, i32 5, i32 7, i32 13, i32 15>
1259   %hadd = fadd <8 x float> %hadd0, %hadd1
1260   ret <8 x float> %hadd
1263 define <8 x float> @hsub_8f32_v8f32_shuffle(<8 x float> %a0, <8 x float> %a1) {
1264 ; SSE-LABEL: hsub_8f32_v8f32_shuffle:
1265 ; SSE:       # %bb.0:
1266 ; SSE-NEXT:    haddps %xmm1, %xmm0
1267 ; SSE-NEXT:    haddps %xmm3, %xmm2
1268 ; SSE-NEXT:    movaps %xmm2, %xmm1
1269 ; SSE-NEXT:    retq
1271 ; AVX1-LABEL: hsub_8f32_v8f32_shuffle:
1272 ; AVX1:       # %bb.0:
1273 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm2
1274 ; AVX1-NEXT:    vperm2f128 {{.*#+}} ymm0 = ymm0[2,3],ymm1[2,3]
1275 ; AVX1-NEXT:    vhaddps %ymm0, %ymm2, %ymm0
1276 ; AVX1-NEXT:    retq
1278 ; AVX2-LABEL: hsub_8f32_v8f32_shuffle:
1279 ; AVX2:       # %bb.0:
1280 ; AVX2-NEXT:    vhaddps %ymm1, %ymm0, %ymm0
1281 ; AVX2-NEXT:    vpermpd {{.*#+}} ymm0 = ymm0[0,2,1,3]
1282 ; AVX2-NEXT:    retq
1283   %shuf0 = shufflevector <8 x float> %a0, <8 x float> %a1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11>
1284   %shuf1 = shufflevector <8 x float> %a0, <8 x float> %a1, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 12, i32 13, i32 14, i32 15>
1285   %hsub0 = shufflevector <8 x float> %shuf0, <8 x float> %shuf1, <8 x i32> <i32 0, i32 2, i32 8, i32 10, i32 4, i32 6, i32 12, i32 14>
1286   %hsub1 = shufflevector <8 x float> %shuf0, <8 x float> %shuf1, <8 x i32> <i32 1, i32 3, i32 9, i32 11, i32 5, i32 7, i32 13, i32 15>
1287   %hsub = fadd <8 x float> %hsub0, %hsub1
1288   ret <8 x float> %hsub
1291 define <8 x i32> @hadd_8i32_v8i32_shuffle(<8 x i32> %a0, <8 x i32> %a1) {
1292 ; SSE3-LABEL: hadd_8i32_v8i32_shuffle:
1293 ; SSE3:       # %bb.0:
1294 ; SSE3-NEXT:    movaps %xmm2, %xmm4
1295 ; SSE3-NEXT:    shufps {{.*#+}} xmm4 = xmm4[0,2],xmm3[0,2]
1296 ; SSE3-NEXT:    movaps %xmm0, %xmm5
1297 ; SSE3-NEXT:    shufps {{.*#+}} xmm5 = xmm5[0,2],xmm1[0,2]
1298 ; SSE3-NEXT:    shufps {{.*#+}} xmm2 = xmm2[1,3],xmm3[1,3]
1299 ; SSE3-NEXT:    paddd %xmm4, %xmm2
1300 ; SSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,3],xmm1[1,3]
1301 ; SSE3-NEXT:    paddd %xmm5, %xmm0
1302 ; SSE3-NEXT:    movdqa %xmm2, %xmm1
1303 ; SSE3-NEXT:    retq
1305 ; SSSE3-LABEL: hadd_8i32_v8i32_shuffle:
1306 ; SSSE3:       # %bb.0:
1307 ; SSSE3-NEXT:    phaddd %xmm1, %xmm0
1308 ; SSSE3-NEXT:    phaddd %xmm3, %xmm2
1309 ; SSSE3-NEXT:    movdqa %xmm2, %xmm1
1310 ; SSSE3-NEXT:    retq
1312 ; AVX1-LABEL: hadd_8i32_v8i32_shuffle:
1313 ; AVX1:       # %bb.0:
1314 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
1315 ; AVX1-NEXT:    vphaddd %xmm2, %xmm1, %xmm1
1316 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
1317 ; AVX1-NEXT:    vphaddd %xmm2, %xmm0, %xmm0
1318 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
1319 ; AVX1-NEXT:    retq
1321 ; AVX2-LABEL: hadd_8i32_v8i32_shuffle:
1322 ; AVX2:       # %bb.0:
1323 ; AVX2-NEXT:    vphaddd %ymm1, %ymm0, %ymm0
1324 ; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
1325 ; AVX2-NEXT:    retq
1326   %shuf0 = shufflevector <8 x i32> %a0, <8 x i32> %a1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11>
1327   %shuf1 = shufflevector <8 x i32> %a0, <8 x i32> %a1, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 12, i32 13, i32 14, i32 15>
1328   %hadd0 = shufflevector <8 x i32> %shuf0, <8 x i32> %shuf1, <8 x i32> <i32 0, i32 2, i32 8, i32 10, i32 4, i32 6, i32 12, i32 14>
1329   %hadd1 = shufflevector <8 x i32> %shuf0, <8 x i32> %shuf1, <8 x i32> <i32 1, i32 3, i32 9, i32 11, i32 5, i32 7, i32 13, i32 15>
1330   %hadd = add <8 x i32> %hadd0, %hadd1
1331   ret <8 x i32> %hadd
1334 define <8 x i32> @hsub_8i32_v8i32_shuffle(<8 x i32> %a0, <8 x i32> %a1) {
1335 ; SSE3-LABEL: hsub_8i32_v8i32_shuffle:
1336 ; SSE3:       # %bb.0:
1337 ; SSE3-NEXT:    movaps %xmm2, %xmm4
1338 ; SSE3-NEXT:    shufps {{.*#+}} xmm4 = xmm4[0,2],xmm3[0,2]
1339 ; SSE3-NEXT:    movaps %xmm0, %xmm5
1340 ; SSE3-NEXT:    shufps {{.*#+}} xmm5 = xmm5[0,2],xmm1[0,2]
1341 ; SSE3-NEXT:    shufps {{.*#+}} xmm2 = xmm2[1,3],xmm3[1,3]
1342 ; SSE3-NEXT:    psubd %xmm2, %xmm4
1343 ; SSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,3],xmm1[1,3]
1344 ; SSE3-NEXT:    psubd %xmm0, %xmm5
1345 ; SSE3-NEXT:    movdqa %xmm5, %xmm0
1346 ; SSE3-NEXT:    movdqa %xmm4, %xmm1
1347 ; SSE3-NEXT:    retq
1349 ; SSSE3-LABEL: hsub_8i32_v8i32_shuffle:
1350 ; SSSE3:       # %bb.0:
1351 ; SSSE3-NEXT:    phsubd %xmm1, %xmm0
1352 ; SSSE3-NEXT:    phsubd %xmm3, %xmm2
1353 ; SSSE3-NEXT:    movdqa %xmm2, %xmm1
1354 ; SSSE3-NEXT:    retq
1356 ; AVX1-LABEL: hsub_8i32_v8i32_shuffle:
1357 ; AVX1:       # %bb.0:
1358 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
1359 ; AVX1-NEXT:    vphsubd %xmm2, %xmm1, %xmm1
1360 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
1361 ; AVX1-NEXT:    vphsubd %xmm2, %xmm0, %xmm0
1362 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
1363 ; AVX1-NEXT:    retq
1365 ; AVX2-LABEL: hsub_8i32_v8i32_shuffle:
1366 ; AVX2:       # %bb.0:
1367 ; AVX2-NEXT:    vphsubd %ymm1, %ymm0, %ymm0
1368 ; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
1369 ; AVX2-NEXT:    retq
1370   %shuf0 = shufflevector <8 x i32> %a0, <8 x i32> %a1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11>
1371   %shuf1 = shufflevector <8 x i32> %a0, <8 x i32> %a1, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 12, i32 13, i32 14, i32 15>
1372   %hadd0 = shufflevector <8 x i32> %shuf0, <8 x i32> %shuf1, <8 x i32> <i32 0, i32 2, i32 8, i32 10, i32 4, i32 6, i32 12, i32 14>
1373   %hadd1 = shufflevector <8 x i32> %shuf0, <8 x i32> %shuf1, <8 x i32> <i32 1, i32 3, i32 9, i32 11, i32 5, i32 7, i32 13, i32 15>
1374   %hadd = sub <8 x i32> %hadd0, %hadd1
1375   ret <8 x i32> %hadd
1378 define <16 x i16> @hadd_16i16_16i16_shuffle(<16 x i16> %a0, <16 x i16> %a1) {
1379 ; SSE3-LABEL: hadd_16i16_16i16_shuffle:
1380 ; SSE3:       # %bb.0:
1381 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm4 = xmm3[0,2,2,3,4,5,6,7]
1382 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm4 = xmm4[0,1,2,3,4,6,6,7]
1383 ; SSE3-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[0,2,2,3]
1384 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm5 = xmm2[0,2,2,3,4,5,6,7]
1385 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm5 = xmm5[0,1,2,3,4,6,6,7]
1386 ; SSE3-NEXT:    pshufd {{.*#+}} xmm5 = xmm5[0,2,2,3]
1387 ; SSE3-NEXT:    punpcklqdq {{.*#+}} xmm5 = xmm5[0],xmm4[0]
1388 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm4 = xmm1[0,2,2,3,4,5,6,7]
1389 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm4 = xmm4[0,1,2,3,4,6,6,7]
1390 ; SSE3-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[0,2,2,3]
1391 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm6 = xmm0[0,2,2,3,4,5,6,7]
1392 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm6 = xmm6[0,1,2,3,4,6,6,7]
1393 ; SSE3-NEXT:    pshufd {{.*#+}} xmm6 = xmm6[0,2,2,3]
1394 ; SSE3-NEXT:    punpcklqdq {{.*#+}} xmm6 = xmm6[0],xmm4[0]
1395 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm3 = xmm3[3,1,2,3,4,5,6,7]
1396 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm3 = xmm3[0,1,2,3,7,5,6,7]
1397 ; SSE3-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[0,2,2,3]
1398 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm3 = xmm3[1,0,3,2,4,5,6,7]
1399 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm2 = xmm2[3,1,2,3,4,5,6,7]
1400 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm2 = xmm2[0,1,2,3,7,5,6,7]
1401 ; SSE3-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,2,2,3]
1402 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm2 = xmm2[1,0,3,2,4,5,6,7]
1403 ; SSE3-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
1404 ; SSE3-NEXT:    paddw %xmm5, %xmm2
1405 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[3,1,2,3,4,5,6,7]
1406 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm1 = xmm1[0,1,2,3,7,5,6,7]
1407 ; SSE3-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
1408 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[1,0,3,2,4,5,6,7]
1409 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[3,1,2,3,4,5,6,7]
1410 ; SSE3-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,7,5,6,7]
1411 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1412 ; SSE3-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[1,0,3,2,4,5,6,7]
1413 ; SSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
1414 ; SSE3-NEXT:    paddw %xmm6, %xmm0
1415 ; SSE3-NEXT:    movdqa %xmm2, %xmm1
1416 ; SSE3-NEXT:    retq
1418 ; SSSE3-LABEL: hadd_16i16_16i16_shuffle:
1419 ; SSSE3:       # %bb.0:
1420 ; SSSE3-NEXT:    phaddw %xmm1, %xmm0
1421 ; SSSE3-NEXT:    phaddw %xmm3, %xmm2
1422 ; SSSE3-NEXT:    movdqa %xmm2, %xmm1
1423 ; SSSE3-NEXT:    retq
1425 ; AVX1-LABEL: hadd_16i16_16i16_shuffle:
1426 ; AVX1:       # %bb.0:
1427 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
1428 ; AVX1-NEXT:    vphaddw %xmm2, %xmm1, %xmm1
1429 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
1430 ; AVX1-NEXT:    vphaddw %xmm2, %xmm0, %xmm0
1431 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
1432 ; AVX1-NEXT:    retq
1434 ; AVX2-LABEL: hadd_16i16_16i16_shuffle:
1435 ; AVX2:       # %bb.0:
1436 ; AVX2-NEXT:    vphaddw %ymm1, %ymm0, %ymm0
1437 ; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3]
1438 ; AVX2-NEXT:    retq
1439   %shuf0 = shufflevector <16 x i16> %a0, <16 x i16> %a1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23>
1440   %shuf1 = shufflevector <16 x i16> %a0, <16 x i16> %a1, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
1441   %hadd0 = shufflevector <16 x i16> %shuf0, <16 x i16> %shuf1, <16 x i32> <i32 0, i32 2, i32 4, i32 6, i32 16, i32 18, i32 20, i32 22, i32 8, i32 10, i32 12, i32 14, i32 24, i32 26, i32 28, i32 30>
1442   %hadd1 = shufflevector <16 x i16> %shuf0, <16 x i16> %shuf1, <16 x i32> <i32 1, i32 3, i32 5, i32 7, i32 17, i32 19, i32 21, i32 23, i32 9, i32 11, i32 13, i32 15, i32 25, i32 27, i32 29, i32 31>
1443   %hadd = add <16 x i16> %hadd0, %hadd1
1444   ret <16 x i16> %hadd