[X86] Update test/CodeGen/X86/avg.ll with the help of update_llc_test_checks.py....
[oota-llvm.git] / test / CodeGen / X86 / haddsub-2.ll
1 ; RUN: llc < %s -march=x86-64 -mattr=+sse2,+sse3 | FileCheck %s -check-prefix=CHECK -check-prefix=SSE3
2 ; RUN: llc < %s -march=x86-64 -mattr=+sse2,+sse3,+ssse3 | FileCheck %s -check-prefix=CHECK -check-prefix=SSSE3
3 ; RUN: llc < %s -march=x86-64 -mattr=+avx | FileCheck %s -check-prefix=CHECK -check-prefix=AVX
4 ; RUN: llc < %s -march=x86-64 -mattr=+avx2 | FileCheck %s -check-prefix=CHECK -check-prefix=AVX2
5
6
7
8 define <4 x float> @hadd_ps_test1(<4 x float> %A, <4 x float> %B) {
9   %vecext = extractelement <4 x float> %A, i32 0
10   %vecext1 = extractelement <4 x float> %A, i32 1
11   %add = fadd float %vecext, %vecext1
12   %vecinit = insertelement <4 x float> undef, float %add, i32 0
13   %vecext2 = extractelement <4 x float> %A, i32 2
14   %vecext3 = extractelement <4 x float> %A, i32 3
15   %add4 = fadd float %vecext2, %vecext3
16   %vecinit5 = insertelement <4 x float> %vecinit, float %add4, i32 1
17   %vecext6 = extractelement <4 x float> %B, i32 0
18   %vecext7 = extractelement <4 x float> %B, i32 1
19   %add8 = fadd float %vecext6, %vecext7
20   %vecinit9 = insertelement <4 x float> %vecinit5, float %add8, i32 2
21   %vecext10 = extractelement <4 x float> %B, i32 2
22   %vecext11 = extractelement <4 x float> %B, i32 3
23   %add12 = fadd float %vecext10, %vecext11
24   %vecinit13 = insertelement <4 x float> %vecinit9, float %add12, i32 3
25   ret <4 x float> %vecinit13
26 }
27 ; CHECK-LABEL: hadd_ps_test1
28 ; CHECK: haddps
29 ; CHECK-NEXT: ret
30
31
32 define <4 x float> @hadd_ps_test2(<4 x float> %A, <4 x float> %B) {
33   %vecext = extractelement <4 x float> %A, i32 2
34   %vecext1 = extractelement <4 x float> %A, i32 3
35   %add = fadd float %vecext, %vecext1
36   %vecinit = insertelement <4 x float> undef, float %add, i32 1
37   %vecext2 = extractelement <4 x float> %A, i32 0
38   %vecext3 = extractelement <4 x float> %A, i32 1
39   %add4 = fadd float %vecext2, %vecext3
40   %vecinit5 = insertelement <4 x float> %vecinit, float %add4, i32 0
41   %vecext6 = extractelement <4 x float> %B, i32 2
42   %vecext7 = extractelement <4 x float> %B, i32 3
43   %add8 = fadd float %vecext6, %vecext7
44   %vecinit9 = insertelement <4 x float> %vecinit5, float %add8, i32 3
45   %vecext10 = extractelement <4 x float> %B, i32 0
46   %vecext11 = extractelement <4 x float> %B, i32 1
47   %add12 = fadd float %vecext10, %vecext11
48   %vecinit13 = insertelement <4 x float> %vecinit9, float %add12, i32 2
49   ret <4 x float> %vecinit13
50 }
51 ; CHECK-LABEL: hadd_ps_test2
52 ; CHECK: haddps
53 ; CHECK-NEXT: ret
54
55
56 define <4 x float> @hsub_ps_test1(<4 x float> %A, <4 x float> %B) {
57   %vecext = extractelement <4 x float> %A, i32 0
58   %vecext1 = extractelement <4 x float> %A, i32 1
59   %sub = fsub float %vecext, %vecext1
60   %vecinit = insertelement <4 x float> undef, float %sub, i32 0
61   %vecext2 = extractelement <4 x float> %A, i32 2
62   %vecext3 = extractelement <4 x float> %A, i32 3
63   %sub4 = fsub float %vecext2, %vecext3
64   %vecinit5 = insertelement <4 x float> %vecinit, float %sub4, i32 1
65   %vecext6 = extractelement <4 x float> %B, i32 0
66   %vecext7 = extractelement <4 x float> %B, i32 1
67   %sub8 = fsub float %vecext6, %vecext7
68   %vecinit9 = insertelement <4 x float> %vecinit5, float %sub8, i32 2
69   %vecext10 = extractelement <4 x float> %B, i32 2
70   %vecext11 = extractelement <4 x float> %B, i32 3
71   %sub12 = fsub float %vecext10, %vecext11
72   %vecinit13 = insertelement <4 x float> %vecinit9, float %sub12, i32 3
73   ret <4 x float> %vecinit13
74 }
75 ; CHECK-LABEL: hsub_ps_test1
76 ; CHECK: hsubps
77 ; CHECK-NEXT: ret
78
79
80 define <4 x float> @hsub_ps_test2(<4 x float> %A, <4 x float> %B) {
81   %vecext = extractelement <4 x float> %A, i32 2
82   %vecext1 = extractelement <4 x float> %A, i32 3
83   %sub = fsub float %vecext, %vecext1
84   %vecinit = insertelement <4 x float> undef, float %sub, i32 1
85   %vecext2 = extractelement <4 x float> %A, i32 0
86   %vecext3 = extractelement <4 x float> %A, i32 1
87   %sub4 = fsub float %vecext2, %vecext3
88   %vecinit5 = insertelement <4 x float> %vecinit, float %sub4, i32 0
89   %vecext6 = extractelement <4 x float> %B, i32 2
90   %vecext7 = extractelement <4 x float> %B, i32 3
91   %sub8 = fsub float %vecext6, %vecext7
92   %vecinit9 = insertelement <4 x float> %vecinit5, float %sub8, i32 3
93   %vecext10 = extractelement <4 x float> %B, i32 0
94   %vecext11 = extractelement <4 x float> %B, i32 1
95   %sub12 = fsub float %vecext10, %vecext11
96   %vecinit13 = insertelement <4 x float> %vecinit9, float %sub12, i32 2
97   ret <4 x float> %vecinit13
98 }
99 ; CHECK-LABEL: hsub_ps_test2
100 ; CHECK: hsubps
101 ; CHECK-NEXT: ret
102
103
104 define <4 x i32> @phadd_d_test1(<4 x i32> %A, <4 x i32> %B) {
105   %vecext = extractelement <4 x i32> %A, i32 0
106   %vecext1 = extractelement <4 x i32> %A, i32 1
107   %add = add i32 %vecext, %vecext1
108   %vecinit = insertelement <4 x i32> undef, i32 %add, i32 0
109   %vecext2 = extractelement <4 x i32> %A, i32 2
110   %vecext3 = extractelement <4 x i32> %A, i32 3
111   %add4 = add i32 %vecext2, %vecext3
112   %vecinit5 = insertelement <4 x i32> %vecinit, i32 %add4, i32 1
113   %vecext6 = extractelement <4 x i32> %B, i32 0
114   %vecext7 = extractelement <4 x i32> %B, i32 1
115   %add8 = add i32 %vecext6, %vecext7
116   %vecinit9 = insertelement <4 x i32> %vecinit5, i32 %add8, i32 2
117   %vecext10 = extractelement <4 x i32> %B, i32 2
118   %vecext11 = extractelement <4 x i32> %B, i32 3
119   %add12 = add i32 %vecext10, %vecext11
120   %vecinit13 = insertelement <4 x i32> %vecinit9, i32 %add12, i32 3
121   ret <4 x i32> %vecinit13
122 }
123 ; CHECK-LABEL: phadd_d_test1
124 ; SSE3-NOT: phaddd
125 ; SSSE3: phaddd
126 ; AVX: vphaddd
127 ; AVX2 vphaddd
128 ; CHECK: ret
129
130
131 define <4 x i32> @phadd_d_test2(<4 x i32> %A, <4 x i32> %B) {
132   %vecext = extractelement <4 x i32> %A, i32 2
133   %vecext1 = extractelement <4 x i32> %A, i32 3
134   %add = add i32 %vecext, %vecext1
135   %vecinit = insertelement <4 x i32> undef, i32 %add, i32 1
136   %vecext2 = extractelement <4 x i32> %A, i32 0
137   %vecext3 = extractelement <4 x i32> %A, i32 1
138   %add4 = add i32 %vecext2, %vecext3
139   %vecinit5 = insertelement <4 x i32> %vecinit, i32 %add4, i32 0
140   %vecext6 = extractelement <4 x i32> %B, i32 3
141   %vecext7 = extractelement <4 x i32> %B, i32 2
142   %add8 = add i32 %vecext6, %vecext7
143   %vecinit9 = insertelement <4 x i32> %vecinit5, i32 %add8, i32 3
144   %vecext10 = extractelement <4 x i32> %B, i32 1
145   %vecext11 = extractelement <4 x i32> %B, i32 0
146   %add12 = add i32 %vecext10, %vecext11
147   %vecinit13 = insertelement <4 x i32> %vecinit9, i32 %add12, i32 2
148   ret <4 x i32> %vecinit13
149 }
150 ; CHECK-LABEL: phadd_d_test2
151 ; SSE3-NOT: phaddd
152 ; SSSE3: phaddd
153 ; AVX: vphaddd
154 ; AVX2 vphaddd
155 ; CHECK: ret
156
157
158 define <4 x i32> @phsub_d_test1(<4 x i32> %A, <4 x i32> %B) {
159   %vecext = extractelement <4 x i32> %A, i32 0
160   %vecext1 = extractelement <4 x i32> %A, i32 1
161   %sub = sub i32 %vecext, %vecext1
162   %vecinit = insertelement <4 x i32> undef, i32 %sub, i32 0
163   %vecext2 = extractelement <4 x i32> %A, i32 2
164   %vecext3 = extractelement <4 x i32> %A, i32 3
165   %sub4 = sub i32 %vecext2, %vecext3
166   %vecinit5 = insertelement <4 x i32> %vecinit, i32 %sub4, i32 1
167   %vecext6 = extractelement <4 x i32> %B, i32 0
168   %vecext7 = extractelement <4 x i32> %B, i32 1
169   %sub8 = sub i32 %vecext6, %vecext7
170   %vecinit9 = insertelement <4 x i32> %vecinit5, i32 %sub8, i32 2
171   %vecext10 = extractelement <4 x i32> %B, i32 2
172   %vecext11 = extractelement <4 x i32> %B, i32 3
173   %sub12 = sub i32 %vecext10, %vecext11
174   %vecinit13 = insertelement <4 x i32> %vecinit9, i32 %sub12, i32 3
175   ret <4 x i32> %vecinit13
176 }
177 ; CHECK-LABEL: phsub_d_test1
178 ; SSE3-NOT: phsubd
179 ; SSSE3: phsubd
180 ; AVX: vphsubd
181 ; AVX2 vphsubd
182 ; CHECK: ret
183
184
185 define <4 x i32> @phsub_d_test2(<4 x i32> %A, <4 x i32> %B) {
186   %vecext = extractelement <4 x i32> %A, i32 2
187   %vecext1 = extractelement <4 x i32> %A, i32 3
188   %sub = sub i32 %vecext, %vecext1
189   %vecinit = insertelement <4 x i32> undef, i32 %sub, i32 1
190   %vecext2 = extractelement <4 x i32> %A, i32 0
191   %vecext3 = extractelement <4 x i32> %A, i32 1
192   %sub4 = sub i32 %vecext2, %vecext3
193   %vecinit5 = insertelement <4 x i32> %vecinit, i32 %sub4, i32 0
194   %vecext6 = extractelement <4 x i32> %B, i32 2
195   %vecext7 = extractelement <4 x i32> %B, i32 3
196   %sub8 = sub i32 %vecext6, %vecext7
197   %vecinit9 = insertelement <4 x i32> %vecinit5, i32 %sub8, i32 3
198   %vecext10 = extractelement <4 x i32> %B, i32 0
199   %vecext11 = extractelement <4 x i32> %B, i32 1
200   %sub12 = sub i32 %vecext10, %vecext11
201   %vecinit13 = insertelement <4 x i32> %vecinit9, i32 %sub12, i32 2
202   ret <4 x i32> %vecinit13
203 }
204 ; CHECK-LABEL: phsub_d_test2
205 ; SSE3-NOT: phsubd
206 ; SSSE3: phsubd
207 ; AVX: vphsubd
208 ; AVX2 vphsubd
209 ; CHECK: ret
210
211
212 define <2 x double> @hadd_pd_test1(<2 x double> %A, <2 x double> %B) {
213   %vecext = extractelement <2 x double> %A, i32 0
214   %vecext1 = extractelement <2 x double> %A, i32 1
215   %add = fadd double %vecext, %vecext1
216   %vecinit = insertelement <2 x double> undef, double %add, i32 0
217   %vecext2 = extractelement <2 x double> %B, i32 0
218   %vecext3 = extractelement <2 x double> %B, i32 1
219   %add2 = fadd double %vecext2, %vecext3
220   %vecinit2 = insertelement <2 x double> %vecinit, double %add2, i32 1
221   ret <2 x double> %vecinit2
222 }
223 ; CHECK-LABEL: hadd_pd_test1
224 ; CHECK: haddpd
225 ; CHECK-NEXT: ret
226
227
228 define <2 x double> @hadd_pd_test2(<2 x double> %A, <2 x double> %B) {
229   %vecext = extractelement <2 x double> %A, i32 1
230   %vecext1 = extractelement <2 x double> %A, i32 0
231   %add = fadd double %vecext, %vecext1
232   %vecinit = insertelement <2 x double> undef, double %add, i32 0
233   %vecext2 = extractelement <2 x double> %B, i32 1
234   %vecext3 = extractelement <2 x double> %B, i32 0
235   %add2 = fadd double %vecext2, %vecext3
236   %vecinit2 = insertelement <2 x double> %vecinit, double %add2, i32 1
237   ret <2 x double> %vecinit2
238 }
239 ; CHECK-LABEL: hadd_pd_test2
240 ; CHECK: haddpd
241 ; CHECK-NEXT: ret
242
243
244 define <2 x double> @hsub_pd_test1(<2 x double> %A, <2 x double> %B) {
245   %vecext = extractelement <2 x double> %A, i32 0
246   %vecext1 = extractelement <2 x double> %A, i32 1
247   %sub = fsub double %vecext, %vecext1
248   %vecinit = insertelement <2 x double> undef, double %sub, i32 0
249   %vecext2 = extractelement <2 x double> %B, i32 0
250   %vecext3 = extractelement <2 x double> %B, i32 1
251   %sub2 = fsub double %vecext2, %vecext3
252   %vecinit2 = insertelement <2 x double> %vecinit, double %sub2, i32 1
253   ret <2 x double> %vecinit2
254 }
255 ; CHECK-LABEL: hsub_pd_test1
256 ; CHECK: hsubpd
257 ; CHECK-NEXT: ret
258
259
260 define <2 x double> @hsub_pd_test2(<2 x double> %A, <2 x double> %B) {
261   %vecext = extractelement <2 x double> %B, i32 0
262   %vecext1 = extractelement <2 x double> %B, i32 1
263   %sub = fsub double %vecext, %vecext1
264   %vecinit = insertelement <2 x double> undef, double %sub, i32 1
265   %vecext2 = extractelement <2 x double> %A, i32 0
266   %vecext3 = extractelement <2 x double> %A, i32 1
267   %sub2 = fsub double %vecext2, %vecext3
268   %vecinit2 = insertelement <2 x double> %vecinit, double %sub2, i32 0
269   ret <2 x double> %vecinit2
270 }
271 ; CHECK-LABEL: hsub_pd_test2
272 ; CHECK: hsubpd
273 ; CHECK-NEXT: ret
274
275
276 define <4 x double> @avx_vhadd_pd_test(<4 x double> %A, <4 x double> %B) {
277   %vecext = extractelement <4 x double> %A, i32 0
278   %vecext1 = extractelement <4 x double> %A, i32 1
279   %add = fadd double %vecext, %vecext1
280   %vecinit = insertelement <4 x double> undef, double %add, i32 0
281   %vecext2 = extractelement <4 x double> %A, i32 2
282   %vecext3 = extractelement <4 x double> %A, i32 3
283   %add4 = fadd double %vecext2, %vecext3
284   %vecinit5 = insertelement <4 x double> %vecinit, double %add4, i32 1
285   %vecext6 = extractelement <4 x double> %B, i32 0
286   %vecext7 = extractelement <4 x double> %B, i32 1
287   %add8 = fadd double %vecext6, %vecext7
288   %vecinit9 = insertelement <4 x double> %vecinit5, double %add8, i32 2
289   %vecext10 = extractelement <4 x double> %B, i32 2
290   %vecext11 = extractelement <4 x double> %B, i32 3
291   %add12 = fadd double %vecext10, %vecext11
292   %vecinit13 = insertelement <4 x double> %vecinit9, double %add12, i32 3
293   ret <4 x double> %vecinit13
294 }
295 ; CHECK-LABEL: avx_vhadd_pd_test
296 ; SSE3: haddpd
297 ; SSE3-NEXT: haddpd
298 ; SSSE3: haddpd
299 ; SSSE3: haddpd
300 ; AVX: vhaddpd
301 ; AVX: vhaddpd
302 ; AVX2: vhaddpd
303 ; AVX2: vhaddpd
304 ; CHECK: ret
305
306
307 define <4 x double> @avx_vhsub_pd_test(<4 x double> %A, <4 x double> %B) {
308   %vecext = extractelement <4 x double> %A, i32 0
309   %vecext1 = extractelement <4 x double> %A, i32 1
310   %sub = fsub double %vecext, %vecext1
311   %vecinit = insertelement <4 x double> undef, double %sub, i32 0
312   %vecext2 = extractelement <4 x double> %A, i32 2
313   %vecext3 = extractelement <4 x double> %A, i32 3
314   %sub4 = fsub double %vecext2, %vecext3
315   %vecinit5 = insertelement <4 x double> %vecinit, double %sub4, i32 1
316   %vecext6 = extractelement <4 x double> %B, i32 0
317   %vecext7 = extractelement <4 x double> %B, i32 1
318   %sub8 = fsub double %vecext6, %vecext7
319   %vecinit9 = insertelement <4 x double> %vecinit5, double %sub8, i32 2
320   %vecext10 = extractelement <4 x double> %B, i32 2
321   %vecext11 = extractelement <4 x double> %B, i32 3
322   %sub12 = fsub double %vecext10, %vecext11
323   %vecinit13 = insertelement <4 x double> %vecinit9, double %sub12, i32 3
324   ret <4 x double> %vecinit13
325 }
326 ; CHECK-LABEL: avx_vhsub_pd_test
327 ; SSE3: hsubpd
328 ; SSE3-NEXT: hsubpd
329 ; SSSE3: hsubpd
330 ; SSSE3-NEXT: hsubpd
331 ; AVX: vhsubpd
332 ; AVX: vhsubpd
333 ; AVX2: vhsubpd
334 ; AVX2: vhsubpd
335 ; CHECK: ret
336
337
338 define <8 x i32> @avx2_vphadd_d_test(<8 x i32> %A, <8 x i32> %B) {
339   %vecext = extractelement <8 x i32> %A, i32 0
340   %vecext1 = extractelement <8 x i32> %A, i32 1
341   %add = add i32 %vecext, %vecext1
342   %vecinit = insertelement <8 x i32> undef, i32 %add, i32 0
343   %vecext2 = extractelement <8 x i32> %A, i32 2
344   %vecext3 = extractelement <8 x i32> %A, i32 3
345   %add4 = add i32 %vecext2, %vecext3
346   %vecinit5 = insertelement <8 x i32> %vecinit, i32 %add4, i32 1
347   %vecext6 = extractelement <8 x i32> %A, i32 4
348   %vecext7 = extractelement <8 x i32> %A, i32 5
349   %add8 = add i32 %vecext6, %vecext7
350   %vecinit9 = insertelement <8 x i32> %vecinit5, i32 %add8, i32 2
351   %vecext10 = extractelement <8 x i32> %A, i32 6
352   %vecext11 = extractelement <8 x i32> %A, i32 7
353   %add12 = add i32 %vecext10, %vecext11
354   %vecinit13 = insertelement <8 x i32> %vecinit9, i32 %add12, i32 3
355   %vecext14 = extractelement <8 x i32> %B, i32 0
356   %vecext15 = extractelement <8 x i32> %B, i32 1
357   %add16 = add i32 %vecext14, %vecext15
358   %vecinit17 = insertelement <8 x i32> %vecinit13, i32 %add16, i32 4
359   %vecext18 = extractelement <8 x i32> %B, i32 2
360   %vecext19 = extractelement <8 x i32> %B, i32 3
361   %add20 = add i32 %vecext18, %vecext19
362   %vecinit21 = insertelement <8 x i32> %vecinit17, i32 %add20, i32 5
363   %vecext22 = extractelement <8 x i32> %B, i32 4
364   %vecext23 = extractelement <8 x i32> %B, i32 5
365   %add24 = add i32 %vecext22, %vecext23
366   %vecinit25 = insertelement <8 x i32> %vecinit21, i32 %add24, i32 6
367   %vecext26 = extractelement <8 x i32> %B, i32 6
368   %vecext27 = extractelement <8 x i32> %B, i32 7
369   %add28 = add i32 %vecext26, %vecext27
370   %vecinit29 = insertelement <8 x i32> %vecinit25, i32 %add28, i32 7
371   ret <8 x i32> %vecinit29
372 }
373 ; CHECK-LABEL: avx2_vphadd_d_test
374 ; SSE3-NOT: phaddd
375 ; SSSE3: phaddd
376 ; SSSE3-NEXT: phaddd
377 ; AVX: vphaddd
378 ; AVX: vphaddd
379 ; AVX2: vphaddd
380 ; AVX2: vphaddd
381 ; CHECK: ret
382
383 define <16 x i16> @avx2_vphadd_w_test(<16 x i16> %a, <16 x i16> %b) {
384   %vecext = extractelement <16 x i16> %a, i32 0
385   %vecext1 = extractelement <16 x i16> %a, i32 1
386   %add = add i16 %vecext, %vecext1
387   %vecinit = insertelement <16 x i16> undef, i16 %add, i32 0
388   %vecext4 = extractelement <16 x i16> %a, i32 2
389   %vecext6 = extractelement <16 x i16> %a, i32 3
390   %add8 = add i16 %vecext4, %vecext6
391   %vecinit10 = insertelement <16 x i16> %vecinit, i16 %add8, i32 1
392   %vecext11 = extractelement <16 x i16> %a, i32 4
393   %vecext13 = extractelement <16 x i16> %a, i32 5
394   %add15 = add i16 %vecext11, %vecext13
395   %vecinit17 = insertelement <16 x i16> %vecinit10, i16 %add15, i32 2
396   %vecext18 = extractelement <16 x i16> %a, i32 6
397   %vecext20 = extractelement <16 x i16> %a, i32 7
398   %add22 = add i16 %vecext18, %vecext20
399   %vecinit24 = insertelement <16 x i16> %vecinit17, i16 %add22, i32 3
400   %vecext25 = extractelement <16 x i16> %a, i32 8
401   %vecext27 = extractelement <16 x i16> %a, i32 9
402   %add29 = add i16 %vecext25, %vecext27
403   %vecinit31 = insertelement <16 x i16> %vecinit24, i16 %add29, i32 4
404   %vecext32 = extractelement <16 x i16> %a, i32 10
405   %vecext34 = extractelement <16 x i16> %a, i32 11
406   %add36 = add i16 %vecext32, %vecext34
407   %vecinit38 = insertelement <16 x i16> %vecinit31, i16 %add36, i32 5
408   %vecext39 = extractelement <16 x i16> %a, i32 12
409   %vecext41 = extractelement <16 x i16> %a, i32 13
410   %add43 = add i16 %vecext39, %vecext41
411   %vecinit45 = insertelement <16 x i16> %vecinit38, i16 %add43, i32 6
412   %vecext46 = extractelement <16 x i16> %a, i32 14
413   %vecext48 = extractelement <16 x i16> %a, i32 15
414   %add50 = add i16 %vecext46, %vecext48
415   %vecinit52 = insertelement <16 x i16> %vecinit45, i16 %add50, i32 7
416   %vecext53 = extractelement <16 x i16> %b, i32 0
417   %vecext55 = extractelement <16 x i16> %b, i32 1
418   %add57 = add i16 %vecext53, %vecext55
419   %vecinit59 = insertelement <16 x i16> %vecinit52, i16 %add57, i32 8
420   %vecext60 = extractelement <16 x i16> %b, i32 2
421   %vecext62 = extractelement <16 x i16> %b, i32 3
422   %add64 = add i16 %vecext60, %vecext62
423   %vecinit66 = insertelement <16 x i16> %vecinit59, i16 %add64, i32 9
424   %vecext67 = extractelement <16 x i16> %b, i32 4
425   %vecext69 = extractelement <16 x i16> %b, i32 5
426   %add71 = add i16 %vecext67, %vecext69
427   %vecinit73 = insertelement <16 x i16> %vecinit66, i16 %add71, i32 10
428   %vecext74 = extractelement <16 x i16> %b, i32 6
429   %vecext76 = extractelement <16 x i16> %b, i32 7
430   %add78 = add i16 %vecext74, %vecext76
431   %vecinit80 = insertelement <16 x i16> %vecinit73, i16 %add78, i32 11
432   %vecext81 = extractelement <16 x i16> %b, i32 8
433   %vecext83 = extractelement <16 x i16> %b, i32 9
434   %add85 = add i16 %vecext81, %vecext83
435   %vecinit87 = insertelement <16 x i16> %vecinit80, i16 %add85, i32 12
436   %vecext88 = extractelement <16 x i16> %b, i32 10
437   %vecext90 = extractelement <16 x i16> %b, i32 11
438   %add92 = add i16 %vecext88, %vecext90
439   %vecinit94 = insertelement <16 x i16> %vecinit87, i16 %add92, i32 13
440   %vecext95 = extractelement <16 x i16> %b, i32 12
441   %vecext97 = extractelement <16 x i16> %b, i32 13
442   %add99 = add i16 %vecext95, %vecext97
443   %vecinit101 = insertelement <16 x i16> %vecinit94, i16 %add99, i32 14
444   %vecext102 = extractelement <16 x i16> %b, i32 14
445   %vecext104 = extractelement <16 x i16> %b, i32 15
446   %add106 = add i16 %vecext102, %vecext104
447   %vecinit108 = insertelement <16 x i16> %vecinit101, i16 %add106, i32 15
448   ret <16 x i16> %vecinit108
449 }
450 ; CHECK-LABEL: avx2_vphadd_w_test
451 ; SSE3-NOT: phaddw
452 ; SSSE3: phaddw
453 ; SSSE3-NEXT: phaddw
454 ; AVX: vphaddw
455 ; AVX: vphaddw
456 ; AVX2: vphaddw
457 ; AVX2: vphaddw
458 ; CHECK: ret
459
460
461 ; Verify that we don't select horizontal subs in the following functions.
462
463 define <4 x i32> @not_a_hsub_1(<4 x i32> %A, <4 x i32> %B) {
464   %vecext = extractelement <4 x i32> %A, i32 0
465   %vecext1 = extractelement <4 x i32> %A, i32 1
466   %sub = sub i32 %vecext, %vecext1
467   %vecinit = insertelement <4 x i32> undef, i32 %sub, i32 0
468   %vecext2 = extractelement <4 x i32> %A, i32 2
469   %vecext3 = extractelement <4 x i32> %A, i32 3
470   %sub4 = sub i32 %vecext2, %vecext3
471   %vecinit5 = insertelement <4 x i32> %vecinit, i32 %sub4, i32 1
472   %vecext6 = extractelement <4 x i32> %B, i32 1
473   %vecext7 = extractelement <4 x i32> %B, i32 0
474   %sub8 = sub i32 %vecext6, %vecext7
475   %vecinit9 = insertelement <4 x i32> %vecinit5, i32 %sub8, i32 2
476   %vecext10 = extractelement <4 x i32> %B, i32 3
477   %vecext11 = extractelement <4 x i32> %B, i32 2
478   %sub12 = sub i32 %vecext10, %vecext11
479   %vecinit13 = insertelement <4 x i32> %vecinit9, i32 %sub12, i32 3
480   ret <4 x i32> %vecinit13
481 }
482 ; CHECK-LABEL: not_a_hsub_1
483 ; CHECK-NOT: phsubd
484 ; CHECK: ret
485
486
487 define <4 x float> @not_a_hsub_2(<4 x float> %A, <4 x float> %B) {
488   %vecext = extractelement <4 x float> %A, i32 2
489   %vecext1 = extractelement <4 x float> %A, i32 3
490   %sub = fsub float %vecext, %vecext1
491   %vecinit = insertelement <4 x float> undef, float %sub, i32 1
492   %vecext2 = extractelement <4 x float> %A, i32 0
493   %vecext3 = extractelement <4 x float> %A, i32 1
494   %sub4 = fsub float %vecext2, %vecext3
495   %vecinit5 = insertelement <4 x float> %vecinit, float %sub4, i32 0
496   %vecext6 = extractelement <4 x float> %B, i32 3
497   %vecext7 = extractelement <4 x float> %B, i32 2
498   %sub8 = fsub float %vecext6, %vecext7
499   %vecinit9 = insertelement <4 x float> %vecinit5, float %sub8, i32 3
500   %vecext10 = extractelement <4 x float> %B, i32 0
501   %vecext11 = extractelement <4 x float> %B, i32 1
502   %sub12 = fsub float %vecext10, %vecext11
503   %vecinit13 = insertelement <4 x float> %vecinit9, float %sub12, i32 2
504   ret <4 x float> %vecinit13
505 }
506 ; CHECK-LABEL: not_a_hsub_2
507 ; CHECK-NOT: hsubps
508 ; CHECK: ret
509
510
511 define <2 x double> @not_a_hsub_3(<2 x double> %A, <2 x double> %B) {
512   %vecext = extractelement <2 x double> %B, i32 0
513   %vecext1 = extractelement <2 x double> %B, i32 1
514   %sub = fsub double %vecext, %vecext1
515   %vecinit = insertelement <2 x double> undef, double %sub, i32 1
516   %vecext2 = extractelement <2 x double> %A, i32 1
517   %vecext3 = extractelement <2 x double> %A, i32 0
518   %sub2 = fsub double %vecext2, %vecext3
519   %vecinit2 = insertelement <2 x double> %vecinit, double %sub2, i32 0
520   ret <2 x double> %vecinit2
521 }
522 ; CHECK-LABEL: not_a_hsub_3
523 ; CHECK-NOT: hsubpd
524 ; CHECK: ret
525
526
527 ; Test AVX horizontal add/sub of packed single/double precision
528 ; floating point values from 256-bit vectors.
529
530 define <8 x float> @avx_vhadd_ps(<8 x float> %a, <8 x float> %b) {
531   %vecext = extractelement <8 x float> %a, i32 0
532   %vecext1 = extractelement <8 x float> %a, i32 1
533   %add = fadd float %vecext, %vecext1
534   %vecinit = insertelement <8 x float> undef, float %add, i32 0
535   %vecext2 = extractelement <8 x float> %a, i32 2
536   %vecext3 = extractelement <8 x float> %a, i32 3
537   %add4 = fadd float %vecext2, %vecext3
538   %vecinit5 = insertelement <8 x float> %vecinit, float %add4, i32 1
539   %vecext6 = extractelement <8 x float> %b, i32 0
540   %vecext7 = extractelement <8 x float> %b, i32 1
541   %add8 = fadd float %vecext6, %vecext7
542   %vecinit9 = insertelement <8 x float> %vecinit5, float %add8, i32 2
543   %vecext10 = extractelement <8 x float> %b, i32 2
544   %vecext11 = extractelement <8 x float> %b, i32 3
545   %add12 = fadd float %vecext10, %vecext11
546   %vecinit13 = insertelement <8 x float> %vecinit9, float %add12, i32 3
547   %vecext14 = extractelement <8 x float> %a, i32 4
548   %vecext15 = extractelement <8 x float> %a, i32 5
549   %add16 = fadd float %vecext14, %vecext15
550   %vecinit17 = insertelement <8 x float> %vecinit13, float %add16, i32 4
551   %vecext18 = extractelement <8 x float> %a, i32 6
552   %vecext19 = extractelement <8 x float> %a, i32 7
553   %add20 = fadd float %vecext18, %vecext19
554   %vecinit21 = insertelement <8 x float> %vecinit17, float %add20, i32 5
555   %vecext22 = extractelement <8 x float> %b, i32 4
556   %vecext23 = extractelement <8 x float> %b, i32 5
557   %add24 = fadd float %vecext22, %vecext23
558   %vecinit25 = insertelement <8 x float> %vecinit21, float %add24, i32 6
559   %vecext26 = extractelement <8 x float> %b, i32 6
560   %vecext27 = extractelement <8 x float> %b, i32 7
561   %add28 = fadd float %vecext26, %vecext27
562   %vecinit29 = insertelement <8 x float> %vecinit25, float %add28, i32 7
563   ret <8 x float> %vecinit29
564 }
565 ; CHECK-LABEL: avx_vhadd_ps
566 ; SSE3: haddps
567 ; SSE3-NEXT: haddps
568 ; SSSE3: haddps
569 ; SSSE3-NEXT: haddps
570 ; AVX: vhaddps
571 ; AVX2: vhaddps
572 ; CHECK: ret
573
574
575 define <8 x float> @avx_vhsub_ps(<8 x float> %a, <8 x float> %b) {
576   %vecext = extractelement <8 x float> %a, i32 0
577   %vecext1 = extractelement <8 x float> %a, i32 1
578   %sub = fsub float %vecext, %vecext1
579   %vecinit = insertelement <8 x float> undef, float %sub, i32 0
580   %vecext2 = extractelement <8 x float> %a, i32 2
581   %vecext3 = extractelement <8 x float> %a, i32 3
582   %sub4 = fsub float %vecext2, %vecext3
583   %vecinit5 = insertelement <8 x float> %vecinit, float %sub4, i32 1
584   %vecext6 = extractelement <8 x float> %b, i32 0
585   %vecext7 = extractelement <8 x float> %b, i32 1
586   %sub8 = fsub float %vecext6, %vecext7
587   %vecinit9 = insertelement <8 x float> %vecinit5, float %sub8, i32 2
588   %vecext10 = extractelement <8 x float> %b, i32 2
589   %vecext11 = extractelement <8 x float> %b, i32 3
590   %sub12 = fsub float %vecext10, %vecext11
591   %vecinit13 = insertelement <8 x float> %vecinit9, float %sub12, i32 3
592   %vecext14 = extractelement <8 x float> %a, i32 4
593   %vecext15 = extractelement <8 x float> %a, i32 5
594   %sub16 = fsub float %vecext14, %vecext15
595   %vecinit17 = insertelement <8 x float> %vecinit13, float %sub16, i32 4
596   %vecext18 = extractelement <8 x float> %a, i32 6
597   %vecext19 = extractelement <8 x float> %a, i32 7
598   %sub20 = fsub float %vecext18, %vecext19
599   %vecinit21 = insertelement <8 x float> %vecinit17, float %sub20, i32 5
600   %vecext22 = extractelement <8 x float> %b, i32 4
601   %vecext23 = extractelement <8 x float> %b, i32 5
602   %sub24 = fsub float %vecext22, %vecext23
603   %vecinit25 = insertelement <8 x float> %vecinit21, float %sub24, i32 6
604   %vecext26 = extractelement <8 x float> %b, i32 6
605   %vecext27 = extractelement <8 x float> %b, i32 7
606   %sub28 = fsub float %vecext26, %vecext27
607   %vecinit29 = insertelement <8 x float> %vecinit25, float %sub28, i32 7
608   ret <8 x float> %vecinit29
609 }
610 ; CHECK-LABEL: avx_vhsub_ps
611 ; SSE3: hsubps
612 ; SSE3-NEXT: hsubps
613 ; SSSE3: hsubps
614 ; SSSE3-NEXT: hsubps
615 ; AVX: vhsubps
616 ; AVX2: vhsubps
617 ; CHECK: ret
618
619
620 define <4 x double> @avx_hadd_pd(<4 x double> %a, <4 x double> %b) {
621   %vecext = extractelement <4 x double> %a, i32 0
622   %vecext1 = extractelement <4 x double> %a, i32 1
623   %add = fadd double %vecext, %vecext1
624   %vecinit = insertelement <4 x double> undef, double %add, i32 0
625   %vecext2 = extractelement <4 x double> %b, i32 0
626   %vecext3 = extractelement <4 x double> %b, i32 1
627   %add4 = fadd double %vecext2, %vecext3
628   %vecinit5 = insertelement <4 x double> %vecinit, double %add4, i32 1
629   %vecext6 = extractelement <4 x double> %a, i32 2
630   %vecext7 = extractelement <4 x double> %a, i32 3
631   %add8 = fadd double %vecext6, %vecext7
632   %vecinit9 = insertelement <4 x double> %vecinit5, double %add8, i32 2
633   %vecext10 = extractelement <4 x double> %b, i32 2
634   %vecext11 = extractelement <4 x double> %b, i32 3
635   %add12 = fadd double %vecext10, %vecext11
636   %vecinit13 = insertelement <4 x double> %vecinit9, double %add12, i32 3
637   ret <4 x double> %vecinit13
638 }
639 ; CHECK-LABEL: avx_hadd_pd
640 ; SSE3: haddpd
641 ; SSE3-NEXT: haddpd
642 ; SSSE3: haddpd
643 ; SSSE3-NEXT: haddpd
644 ; AVX: vhaddpd
645 ; AVX2: vhaddpd
646 ; CHECK: ret
647
648
649 define <4 x double> @avx_hsub_pd(<4 x double> %a, <4 x double> %b) {
650   %vecext = extractelement <4 x double> %a, i32 0
651   %vecext1 = extractelement <4 x double> %a, i32 1
652   %sub = fsub double %vecext, %vecext1
653   %vecinit = insertelement <4 x double> undef, double %sub, i32 0
654   %vecext2 = extractelement <4 x double> %b, i32 0
655   %vecext3 = extractelement <4 x double> %b, i32 1
656   %sub4 = fsub double %vecext2, %vecext3
657   %vecinit5 = insertelement <4 x double> %vecinit, double %sub4, i32 1
658   %vecext6 = extractelement <4 x double> %a, i32 2
659   %vecext7 = extractelement <4 x double> %a, i32 3
660   %sub8 = fsub double %vecext6, %vecext7
661   %vecinit9 = insertelement <4 x double> %vecinit5, double %sub8, i32 2
662   %vecext10 = extractelement <4 x double> %b, i32 2
663   %vecext11 = extractelement <4 x double> %b, i32 3
664   %sub12 = fsub double %vecext10, %vecext11
665   %vecinit13 = insertelement <4 x double> %vecinit9, double %sub12, i32 3
666   ret <4 x double> %vecinit13
667 }
668 ; CHECK-LABEL: avx_hsub_pd
669 ; SSE3: hsubpd
670 ; SSE3-NEXT: hsubpd
671 ; SSSE3: hsubpd
672 ; SSSE3-NEXT: hsubpd
673 ; AVX: vhsubpd
674 ; AVX2: vhsubpd
675 ; CHECK: ret
676
677
678 ; Test AVX2 horizontal add of packed integer values from 256-bit vectors.
679
680 define <8 x i32> @avx2_hadd_d(<8 x i32> %a, <8 x i32> %b) {
681   %vecext = extractelement <8 x i32> %a, i32 0
682   %vecext1 = extractelement <8 x i32> %a, i32 1
683   %add = add i32 %vecext, %vecext1
684   %vecinit = insertelement <8 x i32> undef, i32 %add, i32 0
685   %vecext2 = extractelement <8 x i32> %a, i32 2
686   %vecext3 = extractelement <8 x i32> %a, i32 3
687   %add4 = add i32 %vecext2, %vecext3
688   %vecinit5 = insertelement <8 x i32> %vecinit, i32 %add4, i32 1
689   %vecext6 = extractelement <8 x i32> %b, i32 0
690   %vecext7 = extractelement <8 x i32> %b, i32 1
691   %add8 = add i32 %vecext6, %vecext7
692   %vecinit9 = insertelement <8 x i32> %vecinit5, i32 %add8, i32 2
693   %vecext10 = extractelement <8 x i32> %b, i32 2
694   %vecext11 = extractelement <8 x i32> %b, i32 3
695   %add12 = add i32 %vecext10, %vecext11
696   %vecinit13 = insertelement <8 x i32> %vecinit9, i32 %add12, i32 3
697   %vecext14 = extractelement <8 x i32> %a, i32 4
698   %vecext15 = extractelement <8 x i32> %a, i32 5
699   %add16 = add i32 %vecext14, %vecext15
700   %vecinit17 = insertelement <8 x i32> %vecinit13, i32 %add16, i32 4
701   %vecext18 = extractelement <8 x i32> %a, i32 6
702   %vecext19 = extractelement <8 x i32> %a, i32 7
703   %add20 = add i32 %vecext18, %vecext19
704   %vecinit21 = insertelement <8 x i32> %vecinit17, i32 %add20, i32 5
705   %vecext22 = extractelement <8 x i32> %b, i32 4
706   %vecext23 = extractelement <8 x i32> %b, i32 5
707   %add24 = add i32 %vecext22, %vecext23
708   %vecinit25 = insertelement <8 x i32> %vecinit21, i32 %add24, i32 6
709   %vecext26 = extractelement <8 x i32> %b, i32 6
710   %vecext27 = extractelement <8 x i32> %b, i32 7
711   %add28 = add i32 %vecext26, %vecext27
712   %vecinit29 = insertelement <8 x i32> %vecinit25, i32 %add28, i32 7
713   ret <8 x i32> %vecinit29
714 }
715 ; CHECK-LABEL: avx2_hadd_d
716 ; SSE3-NOT: phaddd
717 ; SSSE3: phaddd
718 ; SSSE3-NEXT: phaddd
719 ; AVX: vphaddd
720 ; AVX: vphaddd
721 ; AVX2: vphaddd
722 ; AVX2-NOT: vphaddd
723 ; CHECK: ret
724
725
726 define <16 x i16> @avx2_hadd_w(<16 x i16> %a, <16 x i16> %b) {
727   %vecext = extractelement <16 x i16> %a, i32 0
728   %vecext1 = extractelement <16 x i16> %a, i32 1
729   %add = add i16 %vecext, %vecext1
730   %vecinit = insertelement <16 x i16> undef, i16 %add, i32 0
731   %vecext4 = extractelement <16 x i16> %a, i32 2
732   %vecext6 = extractelement <16 x i16> %a, i32 3
733   %add8 = add i16 %vecext4, %vecext6
734   %vecinit10 = insertelement <16 x i16> %vecinit, i16 %add8, i32 1
735   %vecext11 = extractelement <16 x i16> %a, i32 4
736   %vecext13 = extractelement <16 x i16> %a, i32 5
737   %add15 = add i16 %vecext11, %vecext13
738   %vecinit17 = insertelement <16 x i16> %vecinit10, i16 %add15, i32 2
739   %vecext18 = extractelement <16 x i16> %a, i32 6
740   %vecext20 = extractelement <16 x i16> %a, i32 7
741   %add22 = add i16 %vecext18, %vecext20
742   %vecinit24 = insertelement <16 x i16> %vecinit17, i16 %add22, i32 3
743   %vecext25 = extractelement <16 x i16> %a, i32 8
744   %vecext27 = extractelement <16 x i16> %a, i32 9
745   %add29 = add i16 %vecext25, %vecext27
746   %vecinit31 = insertelement <16 x i16> %vecinit24, i16 %add29, i32 8
747   %vecext32 = extractelement <16 x i16> %a, i32 10
748   %vecext34 = extractelement <16 x i16> %a, i32 11
749   %add36 = add i16 %vecext32, %vecext34
750   %vecinit38 = insertelement <16 x i16> %vecinit31, i16 %add36, i32 9
751   %vecext39 = extractelement <16 x i16> %a, i32 12
752   %vecext41 = extractelement <16 x i16> %a, i32 13
753   %add43 = add i16 %vecext39, %vecext41
754   %vecinit45 = insertelement <16 x i16> %vecinit38, i16 %add43, i32 10
755   %vecext46 = extractelement <16 x i16> %a, i32 14
756   %vecext48 = extractelement <16 x i16> %a, i32 15
757   %add50 = add i16 %vecext46, %vecext48
758   %vecinit52 = insertelement <16 x i16> %vecinit45, i16 %add50, i32 11
759   %vecext53 = extractelement <16 x i16> %b, i32 0
760   %vecext55 = extractelement <16 x i16> %b, i32 1
761   %add57 = add i16 %vecext53, %vecext55
762   %vecinit59 = insertelement <16 x i16> %vecinit52, i16 %add57, i32 4
763   %vecext60 = extractelement <16 x i16> %b, i32 2
764   %vecext62 = extractelement <16 x i16> %b, i32 3
765   %add64 = add i16 %vecext60, %vecext62
766   %vecinit66 = insertelement <16 x i16> %vecinit59, i16 %add64, i32 5
767   %vecext67 = extractelement <16 x i16> %b, i32 4
768   %vecext69 = extractelement <16 x i16> %b, i32 5
769   %add71 = add i16 %vecext67, %vecext69
770   %vecinit73 = insertelement <16 x i16> %vecinit66, i16 %add71, i32 6
771   %vecext74 = extractelement <16 x i16> %b, i32 6
772   %vecext76 = extractelement <16 x i16> %b, i32 7
773   %add78 = add i16 %vecext74, %vecext76
774   %vecinit80 = insertelement <16 x i16> %vecinit73, i16 %add78, i32 7
775   %vecext81 = extractelement <16 x i16> %b, i32 8
776   %vecext83 = extractelement <16 x i16> %b, i32 9
777   %add85 = add i16 %vecext81, %vecext83
778   %vecinit87 = insertelement <16 x i16> %vecinit80, i16 %add85, i32 12
779   %vecext88 = extractelement <16 x i16> %b, i32 10
780   %vecext90 = extractelement <16 x i16> %b, i32 11
781   %add92 = add i16 %vecext88, %vecext90
782   %vecinit94 = insertelement <16 x i16> %vecinit87, i16 %add92, i32 13
783   %vecext95 = extractelement <16 x i16> %b, i32 12
784   %vecext97 = extractelement <16 x i16> %b, i32 13
785   %add99 = add i16 %vecext95, %vecext97
786   %vecinit101 = insertelement <16 x i16> %vecinit94, i16 %add99, i32 14
787   %vecext102 = extractelement <16 x i16> %b, i32 14
788   %vecext104 = extractelement <16 x i16> %b, i32 15
789   %add106 = add i16 %vecext102, %vecext104
790   %vecinit108 = insertelement <16 x i16> %vecinit101, i16 %add106, i32 15
791   ret <16 x i16> %vecinit108
792 }
793 ; CHECK-LABEL: avx2_hadd_w
794 ; SSE3-NOT: phaddw
795 ; SSSE3: phaddw
796 ; SSSE3-NEXT: phaddw
797 ; AVX: vphaddw
798 ; AVX: vphaddw
799 ; AVX2: vphaddw
800 ; AVX2-NOT: vphaddw
801 ; CHECK: ret
802