]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - opencl/llvm.git/blob - test/CodeGen/X86/haddsub-undef.ll
[X86][AVX] Added (V)MOVDDUP / (V)MOVSLDUP / (V)MOVSHDUP memory folding + tests.
[opencl/llvm.git] / test / CodeGen / X86 / haddsub-undef.ll
1 ; RUN: llc < %s -march=x86-64 -mcpu=corei7 -mattr=+ssse3 | FileCheck %s -check-prefix=CHECK -check-prefix=SSE
2 ; RUN: llc < %s -march=x86-64 -mcpu=corei7-avx | FileCheck %s -check-prefix=CHECK -check-prefix=AVX
3 ; RUN: llc < %s -march=x86-64 -mcpu=core-avx2 | FileCheck %s -check-prefix=CHECK -check-prefix=AVX2
5 ; Verify that we correctly fold horizontal binop even in the presence of UNDEFs.
7 define <4 x float> @test1_undef(<4 x float> %a, <4 x float> %b) {
8   %vecext = extractelement <4 x float> %a, i32 0
9   %vecext1 = extractelement <4 x float> %a, i32 1
10   %add = fadd float %vecext, %vecext1
11   %vecinit = insertelement <4 x float> undef, float %add, i32 0
12   %vecext2 = extractelement <4 x float> %a, i32 2
13   %vecext3 = extractelement <4 x float> %a, i32 3
14   %add4 = fadd float %vecext2, %vecext3
15   %vecinit5 = insertelement <4 x float> %vecinit, float %add4, i32 1
16   %vecext10 = extractelement <4 x float> %b, i32 2
17   %vecext11 = extractelement <4 x float> %b, i32 3
18   %add12 = fadd float %vecext10, %vecext11
19   %vecinit13 = insertelement <4 x float> %vecinit5, float %add12, i32 3
20   ret <4 x float> %vecinit13
21 }
22 ; CHECK-LABEL: test1_undef
23 ; SSE: haddps
24 ; AVX: vhaddps
25 ; AVX2: vhaddps
26 ; CHECK-NEXT: ret
29 define <4 x float> @test2_undef(<4 x float> %a, <4 x float> %b) {
30   %vecext = extractelement <4 x float> %a, i32 0
31   %vecext1 = extractelement <4 x float> %a, i32 1
32   %add = fadd float %vecext, %vecext1
33   %vecinit = insertelement <4 x float> undef, float %add, i32 0
34   %vecext6 = extractelement <4 x float> %b, i32 0
35   %vecext7 = extractelement <4 x float> %b, i32 1
36   %add8 = fadd float %vecext6, %vecext7
37   %vecinit9 = insertelement <4 x float> %vecinit, float %add8, i32 2
38   %vecext10 = extractelement <4 x float> %b, i32 2
39   %vecext11 = extractelement <4 x float> %b, i32 3
40   %add12 = fadd float %vecext10, %vecext11
41   %vecinit13 = insertelement <4 x float> %vecinit9, float %add12, i32 3
42   ret <4 x float> %vecinit13
43 }
44 ; CHECK-LABEL: test2_undef
45 ; SSE: haddps
46 ; AVX: vhaddps
47 ; AVX2: vhaddps
48 ; CHECK-NEXT: ret
51 define <4 x float> @test3_undef(<4 x float> %a, <4 x float> %b) {
52   %vecext = extractelement <4 x float> %a, i32 0
53   %vecext1 = extractelement <4 x float> %a, i32 1
54   %add = fadd float %vecext, %vecext1
55   %vecinit = insertelement <4 x float> undef, float %add, i32 0
56   %vecext2 = extractelement <4 x float> %a, i32 2
57   %vecext3 = extractelement <4 x float> %a, i32 3
58   %add4 = fadd float %vecext2, %vecext3
59   %vecinit5 = insertelement <4 x float> %vecinit, float %add4, i32 1
60   %vecext6 = extractelement <4 x float> %b, i32 0
61   %vecext7 = extractelement <4 x float> %b, i32 1
62   %add8 = fadd float %vecext6, %vecext7
63   %vecinit9 = insertelement <4 x float> %vecinit5, float %add8, i32 2
64   ret <4 x float> %vecinit9
65 }
66 ; CHECK-LABEL: test3_undef
67 ; SSE: haddps
68 ; AVX: vhaddps
69 ; AVX2: vhaddps
70 ; CHECK-NEXT: ret
73 define <4 x float> @test4_undef(<4 x float> %a, <4 x float> %b) {
74   %vecext = extractelement <4 x float> %a, i32 0
75   %vecext1 = extractelement <4 x float> %a, i32 1
76   %add = fadd float %vecext, %vecext1
77   %vecinit = insertelement <4 x float> undef, float %add, i32 0
78   ret <4 x float> %vecinit
79 }
80 ; CHECK-LABEL: test4_undef
81 ; CHECK-NOT: haddps
82 ; CHECK: ret
85 define <2 x double> @test5_undef(<2 x double> %a, <2 x double> %b) {
86   %vecext = extractelement <2 x double> %a, i32 0
87   %vecext1 = extractelement <2 x double> %a, i32 1
88   %add = fadd double %vecext, %vecext1
89   %vecinit = insertelement <2 x double> undef, double %add, i32 0
90   ret <2 x double> %vecinit
91 }
92 ; CHECK-LABEL: test5_undef
93 ; CHECK-NOT: haddpd
94 ; CHECK: ret
97 define <4 x float> @test6_undef(<4 x float> %a, <4 x float> %b) {
98   %vecext = extractelement <4 x float> %a, i32 0
99   %vecext1 = extractelement <4 x float> %a, i32 1
100   %add = fadd float %vecext, %vecext1
101   %vecinit = insertelement <4 x float> undef, float %add, i32 0
102   %vecext2 = extractelement <4 x float> %a, i32 2
103   %vecext3 = extractelement <4 x float> %a, i32 3
104   %add4 = fadd float %vecext2, %vecext3
105   %vecinit5 = insertelement <4 x float> %vecinit, float %add4, i32 1
106   ret <4 x float> %vecinit5
108 ; CHECK-LABEL: test6_undef
109 ; SSE: haddps
110 ; AVX: vhaddps
111 ; AVX2: vhaddps
112 ; CHECK-NEXT: ret
115 define <4 x float> @test7_undef(<4 x float> %a, <4 x float> %b) {
116   %vecext = extractelement <4 x float> %b, i32 0
117   %vecext1 = extractelement <4 x float> %b, i32 1
118   %add = fadd float %vecext, %vecext1
119   %vecinit = insertelement <4 x float> undef, float %add, i32 2
120   %vecext2 = extractelement <4 x float> %b, i32 2
121   %vecext3 = extractelement <4 x float> %b, i32 3
122   %add4 = fadd float %vecext2, %vecext3
123   %vecinit5 = insertelement <4 x float> %vecinit, float %add4, i32 3
124   ret <4 x float> %vecinit5
126 ; CHECK-LABEL: test7_undef
127 ; SSE: haddps
128 ; AVX: vhaddps
129 ; AVX2: vhaddps
130 ; CHECK-NEXT: ret
133 define <4 x float> @test8_undef(<4 x float> %a, <4 x float> %b) {
134   %vecext = extractelement <4 x float> %a, i32 0
135   %vecext1 = extractelement <4 x float> %a, i32 1
136   %add = fadd float %vecext, %vecext1
137   %vecinit = insertelement <4 x float> undef, float %add, i32 0
138   %vecext2 = extractelement <4 x float> %a, i32 2
139   %vecext3 = extractelement <4 x float> %a, i32 3
140   %add4 = fadd float %vecext2, %vecext3
141   %vecinit5 = insertelement <4 x float> %vecinit, float %add4, i32 2
142   ret <4 x float> %vecinit5
144 ; CHECK-LABEL: test8_undef
145 ; CHECK-NOT: haddps
146 ; CHECK: ret
149 define <4 x float> @test9_undef(<4 x float> %a, <4 x float> %b) {
150   %vecext = extractelement <4 x float> %a, i32 0
151   %vecext1 = extractelement <4 x float> %a, i32 1
152   %add = fadd float %vecext, %vecext1
153   %vecinit = insertelement <4 x float> undef, float %add, i32 0
154   %vecext2 = extractelement <4 x float> %b, i32 2
155   %vecext3 = extractelement <4 x float> %b, i32 3
156   %add4 = fadd float %vecext2, %vecext3
157   %vecinit5 = insertelement <4 x float> %vecinit, float %add4, i32 3
158   ret <4 x float> %vecinit5
160 ; CHECK-LABEL: test9_undef
161 ; CHECK: haddps
162 ; CHECK-NEXT: ret
164 define <8 x float> @test10_undef(<8 x float> %a, <8 x float> %b) {
165   %vecext = extractelement <8 x float> %a, i32 0
166   %vecext1 = extractelement <8 x float> %a, i32 1
167   %add = fadd float %vecext, %vecext1
168   %vecinit = insertelement <8 x float> undef, float %add, i32 0
169   %vecext2 = extractelement <8 x float> %b, i32 2
170   %vecext3 = extractelement <8 x float> %b, i32 3
171   %add4 = fadd float %vecext2, %vecext3
172   %vecinit5 = insertelement <8 x float> %vecinit, float %add4, i32 3
173   ret <8 x float> %vecinit5
175 ; CHECK-LABEL: test10_undef
176 ; SSE: haddps
177 ; AVX: vhaddps
178 ; AVX2: vhaddps
179 ; CHECK-NOT: haddps
180 ; CHECK: ret
182 define <8 x float> @test11_undef(<8 x float> %a, <8 x float> %b) {
183   %vecext = extractelement <8 x float> %a, i32 0
184   %vecext1 = extractelement <8 x float> %a, i32 1
185   %add = fadd float %vecext, %vecext1
186   %vecinit = insertelement <8 x float> undef, float %add, i32 0
187   %vecext2 = extractelement <8 x float> %b, i32 4
188   %vecext3 = extractelement <8 x float> %b, i32 5
189   %add4 = fadd float %vecext2, %vecext3
190   %vecinit5 = insertelement <8 x float> %vecinit, float %add4, i32 6
191   ret <8 x float> %vecinit5
193 ; CHECK-LABEL: test11_undef
194 ; SSE-NOT: haddps
195 ; AVX: vhaddps
196 ; AVX2: vhaddps
197 ; CHECK: ret
199 define <8 x float> @test12_undef(<8 x float> %a, <8 x float> %b) {
200   %vecext = extractelement <8 x float> %a, i32 0
201   %vecext1 = extractelement <8 x float> %a, i32 1
202   %add = fadd float %vecext, %vecext1
203   %vecinit = insertelement <8 x float> undef, float %add, i32 0
204   %vecext2 = extractelement <8 x float> %a, i32 2
205   %vecext3 = extractelement <8 x float> %a, i32 3
206   %add4 = fadd float %vecext2, %vecext3
207   %vecinit5 = insertelement <8 x float> %vecinit, float %add4, i32 1
208   ret <8 x float> %vecinit5
210 ; CHECK-LABEL: test12_undef
211 ; SSE: haddps
212 ; AVX: vhaddps
213 ; AVX2: vhaddps
214 ; CHECK-NOT: haddps
215 ; CHECK: ret
217 define <8 x float> @test13_undef(<8 x float> %a, <8 x float> %b) {
218   %vecext = extractelement <8 x float> %a, i32 0
219   %vecext1 = extractelement <8 x float> %a, i32 1
220   %add1 = fadd float %vecext, %vecext1
221   %vecinit1 = insertelement <8 x float> undef, float %add1, i32 0
222   %vecext2 = extractelement <8 x float> %a, i32 2
223   %vecext3 = extractelement <8 x float> %a, i32 3
224   %add2 = fadd float %vecext2, %vecext3
225   %vecinit2 = insertelement <8 x float> %vecinit1, float %add2, i32 1
226   %vecext4 = extractelement <8 x float> %a, i32 4
227   %vecext5 = extractelement <8 x float> %a, i32 5
228   %add3 = fadd float %vecext4, %vecext5
229   %vecinit3 = insertelement <8 x float> %vecinit2, float %add3, i32 2
230   %vecext6 = extractelement <8 x float> %a, i32 6
231   %vecext7 = extractelement <8 x float> %a, i32 7
232   %add4 = fadd float %vecext6, %vecext7
233   %vecinit4 = insertelement <8 x float> %vecinit3, float %add4, i32 3
234   ret <8 x float> %vecinit4
236 ; CHECK-LABEL: test13_undef
237 ; SSE: haddps
238 ; SSE-NOT: haddps
239 ; AVX: vhaddps
240 ; AVX2: vhaddps
241 ; CHECK-NOT: haddps
242 ; CHECK: ret
244 define <8 x i32> @test14_undef(<8 x i32> %a, <8 x i32> %b) {
245   %vecext = extractelement <8 x i32> %a, i32 0
246   %vecext1 = extractelement <8 x i32> %a, i32 1
247   %add = add i32 %vecext, %vecext1
248   %vecinit = insertelement <8 x i32> undef, i32 %add, i32 0
249   %vecext2 = extractelement <8 x i32> %b, i32 2
250   %vecext3 = extractelement <8 x i32> %b, i32 3
251   %add4 = add i32 %vecext2, %vecext3
252   %vecinit5 = insertelement <8 x i32> %vecinit, i32 %add4, i32 3
253   ret <8 x i32> %vecinit5
255 ; CHECK-LABEL: test14_undef
256 ; SSE: phaddd
257 ; AVX: vphaddd
258 ; AVX2: vphaddd
259 ; CHECK-NOT: phaddd
260 ; CHECK: ret
262 ; On AVX2, the following sequence can be folded into a single horizontal add.
263 ; If the Subtarget doesn't support AVX2, then we avoid emitting two packed 
264 ; integer horizontal adds instead of two scalar adds followed by vector inserts.
265 define <8 x i32> @test15_undef(<8 x i32> %a, <8 x i32> %b) {
266   %vecext = extractelement <8 x i32> %a, i32 0
267   %vecext1 = extractelement <8 x i32> %a, i32 1
268   %add = add i32 %vecext, %vecext1
269   %vecinit = insertelement <8 x i32> undef, i32 %add, i32 0
270   %vecext2 = extractelement <8 x i32> %b, i32 4
271   %vecext3 = extractelement <8 x i32> %b, i32 5
272   %add4 = add i32 %vecext2, %vecext3
273   %vecinit5 = insertelement <8 x i32> %vecinit, i32 %add4, i32 6
274   ret <8 x i32> %vecinit5
276 ; CHECK-LABEL: test15_undef
277 ; SSE-NOT: phaddd
278 ; AVX-NOT: vphaddd
279 ; AVX2: vphaddd
280 ; CHECK: ret
282 define <8 x i32> @test16_undef(<8 x i32> %a, <8 x i32> %b) {
283   %vecext = extractelement <8 x i32> %a, i32 0
284   %vecext1 = extractelement <8 x i32> %a, i32 1
285   %add = add i32 %vecext, %vecext1
286   %vecinit = insertelement <8 x i32> undef, i32 %add, i32 0
287   %vecext2 = extractelement <8 x i32> %a, i32 2
288   %vecext3 = extractelement <8 x i32> %a, i32 3
289   %add4 = add i32 %vecext2, %vecext3
290   %vecinit5 = insertelement <8 x i32> %vecinit, i32 %add4, i32 1
291   ret <8 x i32> %vecinit5
293 ; CHECK-LABEL: test16_undef
294 ; SSE: phaddd
295 ; AVX: vphaddd
296 ; AVX2: vphaddd
297 ; CHECK-NOT: haddps
298 ; CHECK: ret
300 define <8 x i32> @test17_undef(<8 x i32> %a, <8 x i32> %b) {
301   %vecext = extractelement <8 x i32> %a, i32 0
302   %vecext1 = extractelement <8 x i32> %a, i32 1
303   %add1 = add i32 %vecext, %vecext1
304   %vecinit1 = insertelement <8 x i32> undef, i32 %add1, i32 0
305   %vecext2 = extractelement <8 x i32> %a, i32 2
306   %vecext3 = extractelement <8 x i32> %a, i32 3
307   %add2 = add i32 %vecext2, %vecext3
308   %vecinit2 = insertelement <8 x i32> %vecinit1, i32 %add2, i32 1
309   %vecext4 = extractelement <8 x i32> %a, i32 4
310   %vecext5 = extractelement <8 x i32> %a, i32 5
311   %add3 = add i32 %vecext4, %vecext5
312   %vecinit3 = insertelement <8 x i32> %vecinit2, i32 %add3, i32 2
313   %vecext6 = extractelement <8 x i32> %a, i32 6
314   %vecext7 = extractelement <8 x i32> %a, i32 7
315   %add4 = add i32 %vecext6, %vecext7
316   %vecinit4 = insertelement <8 x i32> %vecinit3, i32 %add4, i32 3
317   ret <8 x i32> %vecinit4
319 ; CHECK-LABEL: test17_undef
320 ; SSE: phaddd
321 ; AVX: vphaddd
322 ; AVX2: vphaddd
323 ; CHECK-NOT: haddps
324 ; CHECK: ret