[DAGCombiner] Eliminate dead stores to stack.
[llvm-complete.git] / test / CodeGen / X86 / phaddsub-extract.ll
blob2ec1f254c354c51a2499796484655a2f25e60628
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+ssse3              | FileCheck %s --check-prefixes=SSE3,SSE3-SLOW
3 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+ssse3,fast-hops    | FileCheck %s --check-prefixes=SSE3,SSE3-FAST
4 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx                | FileCheck %s --check-prefixes=AVX,AVX-SLOW,AVX1-SLOW
5 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx,fast-hops      | FileCheck %s --check-prefixes=AVX,AVX-FAST,AVX1-FAST
6 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx2               | FileCheck %s --check-prefixes=AVX,AVX-SLOW,AVX2-SLOW
7 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx2,fast-hops     | FileCheck %s --check-prefixes=AVX,AVX-FAST,AVX2-FAST
8 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx512vl           | FileCheck %s --check-prefixes=AVX,AVX-SLOW,AVX512-SLOW
9 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx512vl,fast-hops | FileCheck %s --check-prefixes=AVX,AVX-FAST,AVX512-FAST
11 ; 128-bit vectors, 16/32-bit, add/sub
13 define i32 @extract_extract_v4i32_add_i32(<4 x i32> %x) {
14 ; SSE3-SLOW-LABEL: extract_extract_v4i32_add_i32:
15 ; SSE3-SLOW:       # %bb.0:
16 ; SSE3-SLOW-NEXT:    movd %xmm0, %ecx
17 ; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
18 ; SSE3-SLOW-NEXT:    movd %xmm0, %eax
19 ; SSE3-SLOW-NEXT:    addl %ecx, %eax
20 ; SSE3-SLOW-NEXT:    retq
22 ; SSE3-FAST-LABEL: extract_extract_v4i32_add_i32:
23 ; SSE3-FAST:       # %bb.0:
24 ; SSE3-FAST-NEXT:    phaddd %xmm0, %xmm0
25 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
26 ; SSE3-FAST-NEXT:    retq
28 ; AVX-SLOW-LABEL: extract_extract_v4i32_add_i32:
29 ; AVX-SLOW:       # %bb.0:
30 ; AVX-SLOW-NEXT:    vmovd %xmm0, %ecx
31 ; AVX-SLOW-NEXT:    vpextrd $1, %xmm0, %eax
32 ; AVX-SLOW-NEXT:    addl %ecx, %eax
33 ; AVX-SLOW-NEXT:    retq
35 ; AVX-FAST-LABEL: extract_extract_v4i32_add_i32:
36 ; AVX-FAST:       # %bb.0:
37 ; AVX-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
38 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
39 ; AVX-FAST-NEXT:    retq
40   %x0 = extractelement <4 x i32> %x, i32 0
41   %x1 = extractelement <4 x i32> %x, i32 1
42   %x01 = add i32 %x0, %x1
43   ret i32 %x01
46 define i32 @extract_extract_v4i32_add_i32_commute(<4 x i32> %x) {
47 ; SSE3-SLOW-LABEL: extract_extract_v4i32_add_i32_commute:
48 ; SSE3-SLOW:       # %bb.0:
49 ; SSE3-SLOW-NEXT:    movd %xmm0, %ecx
50 ; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
51 ; SSE3-SLOW-NEXT:    movd %xmm0, %eax
52 ; SSE3-SLOW-NEXT:    addl %ecx, %eax
53 ; SSE3-SLOW-NEXT:    retq
55 ; SSE3-FAST-LABEL: extract_extract_v4i32_add_i32_commute:
56 ; SSE3-FAST:       # %bb.0:
57 ; SSE3-FAST-NEXT:    phaddd %xmm0, %xmm0
58 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
59 ; SSE3-FAST-NEXT:    retq
61 ; AVX-SLOW-LABEL: extract_extract_v4i32_add_i32_commute:
62 ; AVX-SLOW:       # %bb.0:
63 ; AVX-SLOW-NEXT:    vmovd %xmm0, %ecx
64 ; AVX-SLOW-NEXT:    vpextrd $1, %xmm0, %eax
65 ; AVX-SLOW-NEXT:    addl %ecx, %eax
66 ; AVX-SLOW-NEXT:    retq
68 ; AVX-FAST-LABEL: extract_extract_v4i32_add_i32_commute:
69 ; AVX-FAST:       # %bb.0:
70 ; AVX-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
71 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
72 ; AVX-FAST-NEXT:    retq
73   %x0 = extractelement <4 x i32> %x, i32 0
74   %x1 = extractelement <4 x i32> %x, i32 1
75   %x01 = add i32 %x1, %x0
76   ret i32 %x01
79 define i16 @extract_extract_v8i16_add_i16(<8 x i16> %x) {
80 ; SSE3-SLOW-LABEL: extract_extract_v8i16_add_i16:
81 ; SSE3-SLOW:       # %bb.0:
82 ; SSE3-SLOW-NEXT:    movd %xmm0, %ecx
83 ; SSE3-SLOW-NEXT:    pextrw $1, %xmm0, %eax
84 ; SSE3-SLOW-NEXT:    addl %ecx, %eax
85 ; SSE3-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
86 ; SSE3-SLOW-NEXT:    retq
88 ; SSE3-FAST-LABEL: extract_extract_v8i16_add_i16:
89 ; SSE3-FAST:       # %bb.0:
90 ; SSE3-FAST-NEXT:    phaddw %xmm0, %xmm0
91 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
92 ; SSE3-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
93 ; SSE3-FAST-NEXT:    retq
95 ; AVX-SLOW-LABEL: extract_extract_v8i16_add_i16:
96 ; AVX-SLOW:       # %bb.0:
97 ; AVX-SLOW-NEXT:    vmovd %xmm0, %ecx
98 ; AVX-SLOW-NEXT:    vpextrw $1, %xmm0, %eax
99 ; AVX-SLOW-NEXT:    addl %ecx, %eax
100 ; AVX-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
101 ; AVX-SLOW-NEXT:    retq
103 ; AVX-FAST-LABEL: extract_extract_v8i16_add_i16:
104 ; AVX-FAST:       # %bb.0:
105 ; AVX-FAST-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
106 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
107 ; AVX-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
108 ; AVX-FAST-NEXT:    retq
109   %x0 = extractelement <8 x i16> %x, i32 0
110   %x1 = extractelement <8 x i16> %x, i32 1
111   %x01 = add i16 %x0, %x1
112   ret i16 %x01
115 define i16 @extract_extract_v8i16_add_i16_commute(<8 x i16> %x) {
116 ; SSE3-SLOW-LABEL: extract_extract_v8i16_add_i16_commute:
117 ; SSE3-SLOW:       # %bb.0:
118 ; SSE3-SLOW-NEXT:    movd %xmm0, %ecx
119 ; SSE3-SLOW-NEXT:    pextrw $1, %xmm0, %eax
120 ; SSE3-SLOW-NEXT:    addl %ecx, %eax
121 ; SSE3-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
122 ; SSE3-SLOW-NEXT:    retq
124 ; SSE3-FAST-LABEL: extract_extract_v8i16_add_i16_commute:
125 ; SSE3-FAST:       # %bb.0:
126 ; SSE3-FAST-NEXT:    phaddw %xmm0, %xmm0
127 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
128 ; SSE3-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
129 ; SSE3-FAST-NEXT:    retq
131 ; AVX-SLOW-LABEL: extract_extract_v8i16_add_i16_commute:
132 ; AVX-SLOW:       # %bb.0:
133 ; AVX-SLOW-NEXT:    vmovd %xmm0, %ecx
134 ; AVX-SLOW-NEXT:    vpextrw $1, %xmm0, %eax
135 ; AVX-SLOW-NEXT:    addl %ecx, %eax
136 ; AVX-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
137 ; AVX-SLOW-NEXT:    retq
139 ; AVX-FAST-LABEL: extract_extract_v8i16_add_i16_commute:
140 ; AVX-FAST:       # %bb.0:
141 ; AVX-FAST-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
142 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
143 ; AVX-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
144 ; AVX-FAST-NEXT:    retq
145   %x0 = extractelement <8 x i16> %x, i32 0
146   %x1 = extractelement <8 x i16> %x, i32 1
147   %x01 = add i16 %x1, %x0
148   ret i16 %x01
151 define i32 @extract_extract_v4i32_sub_i32(<4 x i32> %x) {
152 ; SSE3-SLOW-LABEL: extract_extract_v4i32_sub_i32:
153 ; SSE3-SLOW:       # %bb.0:
154 ; SSE3-SLOW-NEXT:    movd %xmm0, %eax
155 ; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
156 ; SSE3-SLOW-NEXT:    movd %xmm0, %ecx
157 ; SSE3-SLOW-NEXT:    subl %ecx, %eax
158 ; SSE3-SLOW-NEXT:    retq
160 ; SSE3-FAST-LABEL: extract_extract_v4i32_sub_i32:
161 ; SSE3-FAST:       # %bb.0:
162 ; SSE3-FAST-NEXT:    phsubd %xmm0, %xmm0
163 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
164 ; SSE3-FAST-NEXT:    retq
166 ; AVX-SLOW-LABEL: extract_extract_v4i32_sub_i32:
167 ; AVX-SLOW:       # %bb.0:
168 ; AVX-SLOW-NEXT:    vmovd %xmm0, %eax
169 ; AVX-SLOW-NEXT:    vpextrd $1, %xmm0, %ecx
170 ; AVX-SLOW-NEXT:    subl %ecx, %eax
171 ; AVX-SLOW-NEXT:    retq
173 ; AVX-FAST-LABEL: extract_extract_v4i32_sub_i32:
174 ; AVX-FAST:       # %bb.0:
175 ; AVX-FAST-NEXT:    vphsubd %xmm0, %xmm0, %xmm0
176 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
177 ; AVX-FAST-NEXT:    retq
178   %x0 = extractelement <4 x i32> %x, i32 0
179   %x1 = extractelement <4 x i32> %x, i32 1
180   %x01 = sub i32 %x0, %x1
181   ret i32 %x01
184 define i32 @extract_extract_v4i32_sub_i32_commute(<4 x i32> %x) {
185 ; SSE3-LABEL: extract_extract_v4i32_sub_i32_commute:
186 ; SSE3:       # %bb.0:
187 ; SSE3-NEXT:    movd %xmm0, %ecx
188 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
189 ; SSE3-NEXT:    movd %xmm0, %eax
190 ; SSE3-NEXT:    subl %ecx, %eax
191 ; SSE3-NEXT:    retq
193 ; AVX-LABEL: extract_extract_v4i32_sub_i32_commute:
194 ; AVX:       # %bb.0:
195 ; AVX-NEXT:    vmovd %xmm0, %ecx
196 ; AVX-NEXT:    vpextrd $1, %xmm0, %eax
197 ; AVX-NEXT:    subl %ecx, %eax
198 ; AVX-NEXT:    retq
199   %x0 = extractelement <4 x i32> %x, i32 0
200   %x1 = extractelement <4 x i32> %x, i32 1
201   %x01 = sub i32 %x1, %x0
202   ret i32 %x01
205 define i16 @extract_extract_v8i16_sub_i16(<8 x i16> %x) {
206 ; SSE3-SLOW-LABEL: extract_extract_v8i16_sub_i16:
207 ; SSE3-SLOW:       # %bb.0:
208 ; SSE3-SLOW-NEXT:    movd %xmm0, %eax
209 ; SSE3-SLOW-NEXT:    pextrw $1, %xmm0, %ecx
210 ; SSE3-SLOW-NEXT:    subl %ecx, %eax
211 ; SSE3-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
212 ; SSE3-SLOW-NEXT:    retq
214 ; SSE3-FAST-LABEL: extract_extract_v8i16_sub_i16:
215 ; SSE3-FAST:       # %bb.0:
216 ; SSE3-FAST-NEXT:    phsubw %xmm0, %xmm0
217 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
218 ; SSE3-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
219 ; SSE3-FAST-NEXT:    retq
221 ; AVX-SLOW-LABEL: extract_extract_v8i16_sub_i16:
222 ; AVX-SLOW:       # %bb.0:
223 ; AVX-SLOW-NEXT:    vmovd %xmm0, %eax
224 ; AVX-SLOW-NEXT:    vpextrw $1, %xmm0, %ecx
225 ; AVX-SLOW-NEXT:    subl %ecx, %eax
226 ; AVX-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
227 ; AVX-SLOW-NEXT:    retq
229 ; AVX-FAST-LABEL: extract_extract_v8i16_sub_i16:
230 ; AVX-FAST:       # %bb.0:
231 ; AVX-FAST-NEXT:    vphsubw %xmm0, %xmm0, %xmm0
232 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
233 ; AVX-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
234 ; AVX-FAST-NEXT:    retq
235   %x0 = extractelement <8 x i16> %x, i32 0
236   %x1 = extractelement <8 x i16> %x, i32 1
237   %x01 = sub i16 %x0, %x1
238   ret i16 %x01
241 define i16 @extract_extract_v8i16_sub_i16_commute(<8 x i16> %x) {
242 ; SSE3-LABEL: extract_extract_v8i16_sub_i16_commute:
243 ; SSE3:       # %bb.0:
244 ; SSE3-NEXT:    movd %xmm0, %ecx
245 ; SSE3-NEXT:    pextrw $1, %xmm0, %eax
246 ; SSE3-NEXT:    subl %ecx, %eax
247 ; SSE3-NEXT:    # kill: def $ax killed $ax killed $eax
248 ; SSE3-NEXT:    retq
250 ; AVX-LABEL: extract_extract_v8i16_sub_i16_commute:
251 ; AVX:       # %bb.0:
252 ; AVX-NEXT:    vmovd %xmm0, %ecx
253 ; AVX-NEXT:    vpextrw $1, %xmm0, %eax
254 ; AVX-NEXT:    subl %ecx, %eax
255 ; AVX-NEXT:    # kill: def $ax killed $ax killed $eax
256 ; AVX-NEXT:    retq
257   %x0 = extractelement <8 x i16> %x, i32 0
258   %x1 = extractelement <8 x i16> %x, i32 1
259   %x01 = sub i16 %x1, %x0
260   ret i16 %x01
263 ; 256-bit vectors, i32/i16, add/sub
265 define i32 @extract_extract_v8i32_add_i32(<8 x i32> %x) {
266 ; SSE3-SLOW-LABEL: extract_extract_v8i32_add_i32:
267 ; SSE3-SLOW:       # %bb.0:
268 ; SSE3-SLOW-NEXT:    movd %xmm0, %ecx
269 ; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
270 ; SSE3-SLOW-NEXT:    movd %xmm0, %eax
271 ; SSE3-SLOW-NEXT:    addl %ecx, %eax
272 ; SSE3-SLOW-NEXT:    retq
274 ; SSE3-FAST-LABEL: extract_extract_v8i32_add_i32:
275 ; SSE3-FAST:       # %bb.0:
276 ; SSE3-FAST-NEXT:    phaddd %xmm0, %xmm0
277 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
278 ; SSE3-FAST-NEXT:    retq
280 ; AVX-SLOW-LABEL: extract_extract_v8i32_add_i32:
281 ; AVX-SLOW:       # %bb.0:
282 ; AVX-SLOW-NEXT:    vmovd %xmm0, %ecx
283 ; AVX-SLOW-NEXT:    vpextrd $1, %xmm0, %eax
284 ; AVX-SLOW-NEXT:    addl %ecx, %eax
285 ; AVX-SLOW-NEXT:    vzeroupper
286 ; AVX-SLOW-NEXT:    retq
288 ; AVX-FAST-LABEL: extract_extract_v8i32_add_i32:
289 ; AVX-FAST:       # %bb.0:
290 ; AVX-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
291 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
292 ; AVX-FAST-NEXT:    vzeroupper
293 ; AVX-FAST-NEXT:    retq
294   %x0 = extractelement <8 x i32> %x, i32 0
295   %x1 = extractelement <8 x i32> %x, i32 1
296   %x01 = add i32 %x0, %x1
297   ret i32 %x01
300 define i32 @extract_extract_v8i32_add_i32_commute(<8 x i32> %x) {
301 ; SSE3-SLOW-LABEL: extract_extract_v8i32_add_i32_commute:
302 ; SSE3-SLOW:       # %bb.0:
303 ; SSE3-SLOW-NEXT:    movd %xmm0, %ecx
304 ; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
305 ; SSE3-SLOW-NEXT:    movd %xmm0, %eax
306 ; SSE3-SLOW-NEXT:    addl %ecx, %eax
307 ; SSE3-SLOW-NEXT:    retq
309 ; SSE3-FAST-LABEL: extract_extract_v8i32_add_i32_commute:
310 ; SSE3-FAST:       # %bb.0:
311 ; SSE3-FAST-NEXT:    phaddd %xmm0, %xmm0
312 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
313 ; SSE3-FAST-NEXT:    retq
315 ; AVX-SLOW-LABEL: extract_extract_v8i32_add_i32_commute:
316 ; AVX-SLOW:       # %bb.0:
317 ; AVX-SLOW-NEXT:    vmovd %xmm0, %ecx
318 ; AVX-SLOW-NEXT:    vpextrd $1, %xmm0, %eax
319 ; AVX-SLOW-NEXT:    addl %ecx, %eax
320 ; AVX-SLOW-NEXT:    vzeroupper
321 ; AVX-SLOW-NEXT:    retq
323 ; AVX-FAST-LABEL: extract_extract_v8i32_add_i32_commute:
324 ; AVX-FAST:       # %bb.0:
325 ; AVX-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
326 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
327 ; AVX-FAST-NEXT:    vzeroupper
328 ; AVX-FAST-NEXT:    retq
329   %x0 = extractelement <8 x i32> %x, i32 0
330   %x1 = extractelement <8 x i32> %x, i32 1
331   %x01 = add i32 %x1, %x0
332   ret i32 %x01
335 define i16 @extract_extract_v16i16_add_i16(<16 x i16> %x) {
336 ; SSE3-SLOW-LABEL: extract_extract_v16i16_add_i16:
337 ; SSE3-SLOW:       # %bb.0:
338 ; SSE3-SLOW-NEXT:    movd %xmm0, %ecx
339 ; SSE3-SLOW-NEXT:    pextrw $1, %xmm0, %eax
340 ; SSE3-SLOW-NEXT:    addl %ecx, %eax
341 ; SSE3-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
342 ; SSE3-SLOW-NEXT:    retq
344 ; SSE3-FAST-LABEL: extract_extract_v16i16_add_i16:
345 ; SSE3-FAST:       # %bb.0:
346 ; SSE3-FAST-NEXT:    phaddw %xmm0, %xmm0
347 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
348 ; SSE3-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
349 ; SSE3-FAST-NEXT:    retq
351 ; AVX-SLOW-LABEL: extract_extract_v16i16_add_i16:
352 ; AVX-SLOW:       # %bb.0:
353 ; AVX-SLOW-NEXT:    vmovd %xmm0, %ecx
354 ; AVX-SLOW-NEXT:    vpextrw $1, %xmm0, %eax
355 ; AVX-SLOW-NEXT:    addl %ecx, %eax
356 ; AVX-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
357 ; AVX-SLOW-NEXT:    vzeroupper
358 ; AVX-SLOW-NEXT:    retq
360 ; AVX-FAST-LABEL: extract_extract_v16i16_add_i16:
361 ; AVX-FAST:       # %bb.0:
362 ; AVX-FAST-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
363 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
364 ; AVX-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
365 ; AVX-FAST-NEXT:    vzeroupper
366 ; AVX-FAST-NEXT:    retq
367   %x0 = extractelement <16 x i16> %x, i32 0
368   %x1 = extractelement <16 x i16> %x, i32 1
369   %x01 = add i16 %x0, %x1
370   ret i16 %x01
373 define i16 @extract_extract_v16i16_add_i16_commute(<16 x i16> %x) {
374 ; SSE3-SLOW-LABEL: extract_extract_v16i16_add_i16_commute:
375 ; SSE3-SLOW:       # %bb.0:
376 ; SSE3-SLOW-NEXT:    movd %xmm0, %ecx
377 ; SSE3-SLOW-NEXT:    pextrw $1, %xmm0, %eax
378 ; SSE3-SLOW-NEXT:    addl %ecx, %eax
379 ; SSE3-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
380 ; SSE3-SLOW-NEXT:    retq
382 ; SSE3-FAST-LABEL: extract_extract_v16i16_add_i16_commute:
383 ; SSE3-FAST:       # %bb.0:
384 ; SSE3-FAST-NEXT:    phaddw %xmm0, %xmm0
385 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
386 ; SSE3-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
387 ; SSE3-FAST-NEXT:    retq
389 ; AVX-SLOW-LABEL: extract_extract_v16i16_add_i16_commute:
390 ; AVX-SLOW:       # %bb.0:
391 ; AVX-SLOW-NEXT:    vmovd %xmm0, %ecx
392 ; AVX-SLOW-NEXT:    vpextrw $1, %xmm0, %eax
393 ; AVX-SLOW-NEXT:    addl %ecx, %eax
394 ; AVX-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
395 ; AVX-SLOW-NEXT:    vzeroupper
396 ; AVX-SLOW-NEXT:    retq
398 ; AVX-FAST-LABEL: extract_extract_v16i16_add_i16_commute:
399 ; AVX-FAST:       # %bb.0:
400 ; AVX-FAST-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
401 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
402 ; AVX-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
403 ; AVX-FAST-NEXT:    vzeroupper
404 ; AVX-FAST-NEXT:    retq
405   %x0 = extractelement <16 x i16> %x, i32 0
406   %x1 = extractelement <16 x i16> %x, i32 1
407   %x01 = add i16 %x1, %x0
408   ret i16 %x01
411 define i32 @extract_extract_v8i32_sub_i32(<8 x i32> %x) {
412 ; SSE3-SLOW-LABEL: extract_extract_v8i32_sub_i32:
413 ; SSE3-SLOW:       # %bb.0:
414 ; SSE3-SLOW-NEXT:    movd %xmm0, %eax
415 ; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
416 ; SSE3-SLOW-NEXT:    movd %xmm0, %ecx
417 ; SSE3-SLOW-NEXT:    subl %ecx, %eax
418 ; SSE3-SLOW-NEXT:    retq
420 ; SSE3-FAST-LABEL: extract_extract_v8i32_sub_i32:
421 ; SSE3-FAST:       # %bb.0:
422 ; SSE3-FAST-NEXT:    phsubd %xmm0, %xmm0
423 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
424 ; SSE3-FAST-NEXT:    retq
426 ; AVX-SLOW-LABEL: extract_extract_v8i32_sub_i32:
427 ; AVX-SLOW:       # %bb.0:
428 ; AVX-SLOW-NEXT:    vmovd %xmm0, %eax
429 ; AVX-SLOW-NEXT:    vpextrd $1, %xmm0, %ecx
430 ; AVX-SLOW-NEXT:    subl %ecx, %eax
431 ; AVX-SLOW-NEXT:    vzeroupper
432 ; AVX-SLOW-NEXT:    retq
434 ; AVX-FAST-LABEL: extract_extract_v8i32_sub_i32:
435 ; AVX-FAST:       # %bb.0:
436 ; AVX-FAST-NEXT:    vphsubd %xmm0, %xmm0, %xmm0
437 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
438 ; AVX-FAST-NEXT:    vzeroupper
439 ; AVX-FAST-NEXT:    retq
440   %x0 = extractelement <8 x i32> %x, i32 0
441   %x1 = extractelement <8 x i32> %x, i32 1
442   %x01 = sub i32 %x0, %x1
443   ret i32 %x01
446 ; Negative test...or get hoppy and negate?
448 define i32 @extract_extract_v8i32_sub_i32_commute(<8 x i32> %x) {
449 ; SSE3-LABEL: extract_extract_v8i32_sub_i32_commute:
450 ; SSE3:       # %bb.0:
451 ; SSE3-NEXT:    movd %xmm0, %ecx
452 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
453 ; SSE3-NEXT:    movd %xmm0, %eax
454 ; SSE3-NEXT:    subl %ecx, %eax
455 ; SSE3-NEXT:    retq
457 ; AVX-LABEL: extract_extract_v8i32_sub_i32_commute:
458 ; AVX:       # %bb.0:
459 ; AVX-NEXT:    vmovd %xmm0, %ecx
460 ; AVX-NEXT:    vpextrd $1, %xmm0, %eax
461 ; AVX-NEXT:    subl %ecx, %eax
462 ; AVX-NEXT:    vzeroupper
463 ; AVX-NEXT:    retq
464   %x0 = extractelement <8 x i32> %x, i32 0
465   %x1 = extractelement <8 x i32> %x, i32 1
466   %x01 = sub i32 %x1, %x0
467   ret i32 %x01
470 define i16 @extract_extract_v16i16_sub_i16(<16 x i16> %x) {
471 ; SSE3-SLOW-LABEL: extract_extract_v16i16_sub_i16:
472 ; SSE3-SLOW:       # %bb.0:
473 ; SSE3-SLOW-NEXT:    movd %xmm0, %eax
474 ; SSE3-SLOW-NEXT:    pextrw $1, %xmm0, %ecx
475 ; SSE3-SLOW-NEXT:    subl %ecx, %eax
476 ; SSE3-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
477 ; SSE3-SLOW-NEXT:    retq
479 ; SSE3-FAST-LABEL: extract_extract_v16i16_sub_i16:
480 ; SSE3-FAST:       # %bb.0:
481 ; SSE3-FAST-NEXT:    phsubw %xmm0, %xmm0
482 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
483 ; SSE3-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
484 ; SSE3-FAST-NEXT:    retq
486 ; AVX-SLOW-LABEL: extract_extract_v16i16_sub_i16:
487 ; AVX-SLOW:       # %bb.0:
488 ; AVX-SLOW-NEXT:    vmovd %xmm0, %eax
489 ; AVX-SLOW-NEXT:    vpextrw $1, %xmm0, %ecx
490 ; AVX-SLOW-NEXT:    subl %ecx, %eax
491 ; AVX-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
492 ; AVX-SLOW-NEXT:    vzeroupper
493 ; AVX-SLOW-NEXT:    retq
495 ; AVX-FAST-LABEL: extract_extract_v16i16_sub_i16:
496 ; AVX-FAST:       # %bb.0:
497 ; AVX-FAST-NEXT:    vphsubw %xmm0, %xmm0, %xmm0
498 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
499 ; AVX-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
500 ; AVX-FAST-NEXT:    vzeroupper
501 ; AVX-FAST-NEXT:    retq
502   %x0 = extractelement <16 x i16> %x, i32 0
503   %x1 = extractelement <16 x i16> %x, i32 1
504   %x01 = sub i16 %x0, %x1
505   ret i16 %x01
508 ; Negative test...or get hoppy and negate?
510 define i16 @extract_extract_v16i16_sub_i16_commute(<16 x i16> %x) {
511 ; SSE3-LABEL: extract_extract_v16i16_sub_i16_commute:
512 ; SSE3:       # %bb.0:
513 ; SSE3-NEXT:    movd %xmm0, %ecx
514 ; SSE3-NEXT:    pextrw $1, %xmm0, %eax
515 ; SSE3-NEXT:    subl %ecx, %eax
516 ; SSE3-NEXT:    # kill: def $ax killed $ax killed $eax
517 ; SSE3-NEXT:    retq
519 ; AVX-LABEL: extract_extract_v16i16_sub_i16_commute:
520 ; AVX:       # %bb.0:
521 ; AVX-NEXT:    vmovd %xmm0, %ecx
522 ; AVX-NEXT:    vpextrw $1, %xmm0, %eax
523 ; AVX-NEXT:    subl %ecx, %eax
524 ; AVX-NEXT:    # kill: def $ax killed $ax killed $eax
525 ; AVX-NEXT:    vzeroupper
526 ; AVX-NEXT:    retq
527   %x0 = extractelement <16 x i16> %x, i32 0
528   %x1 = extractelement <16 x i16> %x, i32 1
529   %x01 = sub i16 %x1, %x0
530   ret i16 %x01
533 ; 512-bit vectors, i32/i16, add/sub
535 define i32 @extract_extract_v16i32_add_i32(<16 x i32> %x) {
536 ; SSE3-SLOW-LABEL: extract_extract_v16i32_add_i32:
537 ; SSE3-SLOW:       # %bb.0:
538 ; SSE3-SLOW-NEXT:    movd %xmm0, %ecx
539 ; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
540 ; SSE3-SLOW-NEXT:    movd %xmm0, %eax
541 ; SSE3-SLOW-NEXT:    addl %ecx, %eax
542 ; SSE3-SLOW-NEXT:    retq
544 ; SSE3-FAST-LABEL: extract_extract_v16i32_add_i32:
545 ; SSE3-FAST:       # %bb.0:
546 ; SSE3-FAST-NEXT:    phaddd %xmm0, %xmm0
547 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
548 ; SSE3-FAST-NEXT:    retq
550 ; AVX-SLOW-LABEL: extract_extract_v16i32_add_i32:
551 ; AVX-SLOW:       # %bb.0:
552 ; AVX-SLOW-NEXT:    vmovd %xmm0, %ecx
553 ; AVX-SLOW-NEXT:    vpextrd $1, %xmm0, %eax
554 ; AVX-SLOW-NEXT:    addl %ecx, %eax
555 ; AVX-SLOW-NEXT:    vzeroupper
556 ; AVX-SLOW-NEXT:    retq
558 ; AVX-FAST-LABEL: extract_extract_v16i32_add_i32:
559 ; AVX-FAST:       # %bb.0:
560 ; AVX-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
561 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
562 ; AVX-FAST-NEXT:    vzeroupper
563 ; AVX-FAST-NEXT:    retq
564   %x0 = extractelement <16 x i32> %x, i32 0
565   %x1 = extractelement <16 x i32> %x, i32 1
566   %x01 = add i32 %x0, %x1
567   ret i32 %x01
570 define i32 @extract_extract_v16i32_add_i32_commute(<16 x i32> %x) {
571 ; SSE3-SLOW-LABEL: extract_extract_v16i32_add_i32_commute:
572 ; SSE3-SLOW:       # %bb.0:
573 ; SSE3-SLOW-NEXT:    movd %xmm0, %ecx
574 ; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
575 ; SSE3-SLOW-NEXT:    movd %xmm0, %eax
576 ; SSE3-SLOW-NEXT:    addl %ecx, %eax
577 ; SSE3-SLOW-NEXT:    retq
579 ; SSE3-FAST-LABEL: extract_extract_v16i32_add_i32_commute:
580 ; SSE3-FAST:       # %bb.0:
581 ; SSE3-FAST-NEXT:    phaddd %xmm0, %xmm0
582 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
583 ; SSE3-FAST-NEXT:    retq
585 ; AVX-SLOW-LABEL: extract_extract_v16i32_add_i32_commute:
586 ; AVX-SLOW:       # %bb.0:
587 ; AVX-SLOW-NEXT:    vmovd %xmm0, %ecx
588 ; AVX-SLOW-NEXT:    vpextrd $1, %xmm0, %eax
589 ; AVX-SLOW-NEXT:    addl %ecx, %eax
590 ; AVX-SLOW-NEXT:    vzeroupper
591 ; AVX-SLOW-NEXT:    retq
593 ; AVX-FAST-LABEL: extract_extract_v16i32_add_i32_commute:
594 ; AVX-FAST:       # %bb.0:
595 ; AVX-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
596 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
597 ; AVX-FAST-NEXT:    vzeroupper
598 ; AVX-FAST-NEXT:    retq
599   %x0 = extractelement <16 x i32> %x, i32 0
600   %x1 = extractelement <16 x i32> %x, i32 1
601   %x01 = add i32 %x1, %x0
602   ret i32 %x01
605 define i16 @extract_extract_v32i16_add_i16(<32 x i16> %x) {
606 ; SSE3-SLOW-LABEL: extract_extract_v32i16_add_i16:
607 ; SSE3-SLOW:       # %bb.0:
608 ; SSE3-SLOW-NEXT:    movd %xmm0, %ecx
609 ; SSE3-SLOW-NEXT:    pextrw $1, %xmm0, %eax
610 ; SSE3-SLOW-NEXT:    addl %ecx, %eax
611 ; SSE3-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
612 ; SSE3-SLOW-NEXT:    retq
614 ; SSE3-FAST-LABEL: extract_extract_v32i16_add_i16:
615 ; SSE3-FAST:       # %bb.0:
616 ; SSE3-FAST-NEXT:    phaddw %xmm0, %xmm0
617 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
618 ; SSE3-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
619 ; SSE3-FAST-NEXT:    retq
621 ; AVX-SLOW-LABEL: extract_extract_v32i16_add_i16:
622 ; AVX-SLOW:       # %bb.0:
623 ; AVX-SLOW-NEXT:    vmovd %xmm0, %ecx
624 ; AVX-SLOW-NEXT:    vpextrw $1, %xmm0, %eax
625 ; AVX-SLOW-NEXT:    addl %ecx, %eax
626 ; AVX-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
627 ; AVX-SLOW-NEXT:    vzeroupper
628 ; AVX-SLOW-NEXT:    retq
630 ; AVX-FAST-LABEL: extract_extract_v32i16_add_i16:
631 ; AVX-FAST:       # %bb.0:
632 ; AVX-FAST-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
633 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
634 ; AVX-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
635 ; AVX-FAST-NEXT:    vzeroupper
636 ; AVX-FAST-NEXT:    retq
637   %x0 = extractelement <32 x i16> %x, i32 0
638   %x1 = extractelement <32 x i16> %x, i32 1
639   %x01 = add i16 %x0, %x1
640   ret i16 %x01
643 define i16 @extract_extract_v32i16_add_i16_commute(<32 x i16> %x) {
644 ; SSE3-SLOW-LABEL: extract_extract_v32i16_add_i16_commute:
645 ; SSE3-SLOW:       # %bb.0:
646 ; SSE3-SLOW-NEXT:    movd %xmm0, %ecx
647 ; SSE3-SLOW-NEXT:    pextrw $1, %xmm0, %eax
648 ; SSE3-SLOW-NEXT:    addl %ecx, %eax
649 ; SSE3-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
650 ; SSE3-SLOW-NEXT:    retq
652 ; SSE3-FAST-LABEL: extract_extract_v32i16_add_i16_commute:
653 ; SSE3-FAST:       # %bb.0:
654 ; SSE3-FAST-NEXT:    phaddw %xmm0, %xmm0
655 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
656 ; SSE3-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
657 ; SSE3-FAST-NEXT:    retq
659 ; AVX-SLOW-LABEL: extract_extract_v32i16_add_i16_commute:
660 ; AVX-SLOW:       # %bb.0:
661 ; AVX-SLOW-NEXT:    vmovd %xmm0, %ecx
662 ; AVX-SLOW-NEXT:    vpextrw $1, %xmm0, %eax
663 ; AVX-SLOW-NEXT:    addl %ecx, %eax
664 ; AVX-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
665 ; AVX-SLOW-NEXT:    vzeroupper
666 ; AVX-SLOW-NEXT:    retq
668 ; AVX-FAST-LABEL: extract_extract_v32i16_add_i16_commute:
669 ; AVX-FAST:       # %bb.0:
670 ; AVX-FAST-NEXT:    vphaddw %xmm0, %xmm0, %xmm0
671 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
672 ; AVX-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
673 ; AVX-FAST-NEXT:    vzeroupper
674 ; AVX-FAST-NEXT:    retq
675   %x0 = extractelement <32 x i16> %x, i32 0
676   %x1 = extractelement <32 x i16> %x, i32 1
677   %x01 = add i16 %x1, %x0
678   ret i16 %x01
681 define i32 @extract_extract_v16i32_sub_i32(<16 x i32> %x) {
682 ; SSE3-SLOW-LABEL: extract_extract_v16i32_sub_i32:
683 ; SSE3-SLOW:       # %bb.0:
684 ; SSE3-SLOW-NEXT:    movd %xmm0, %eax
685 ; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
686 ; SSE3-SLOW-NEXT:    movd %xmm0, %ecx
687 ; SSE3-SLOW-NEXT:    subl %ecx, %eax
688 ; SSE3-SLOW-NEXT:    retq
690 ; SSE3-FAST-LABEL: extract_extract_v16i32_sub_i32:
691 ; SSE3-FAST:       # %bb.0:
692 ; SSE3-FAST-NEXT:    phsubd %xmm0, %xmm0
693 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
694 ; SSE3-FAST-NEXT:    retq
696 ; AVX-SLOW-LABEL: extract_extract_v16i32_sub_i32:
697 ; AVX-SLOW:       # %bb.0:
698 ; AVX-SLOW-NEXT:    vmovd %xmm0, %eax
699 ; AVX-SLOW-NEXT:    vpextrd $1, %xmm0, %ecx
700 ; AVX-SLOW-NEXT:    subl %ecx, %eax
701 ; AVX-SLOW-NEXT:    vzeroupper
702 ; AVX-SLOW-NEXT:    retq
704 ; AVX-FAST-LABEL: extract_extract_v16i32_sub_i32:
705 ; AVX-FAST:       # %bb.0:
706 ; AVX-FAST-NEXT:    vphsubd %xmm0, %xmm0, %xmm0
707 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
708 ; AVX-FAST-NEXT:    vzeroupper
709 ; AVX-FAST-NEXT:    retq
710   %x0 = extractelement <16 x i32> %x, i32 0
711   %x1 = extractelement <16 x i32> %x, i32 1
712   %x01 = sub i32 %x0, %x1
713   ret i32 %x01
716 define i32 @extract_extract_v16i32_sub_i32_commute(<16 x i32> %x) {
717 ; SSE3-LABEL: extract_extract_v16i32_sub_i32_commute:
718 ; SSE3:       # %bb.0:
719 ; SSE3-NEXT:    movd %xmm0, %ecx
720 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
721 ; SSE3-NEXT:    movd %xmm0, %eax
722 ; SSE3-NEXT:    subl %ecx, %eax
723 ; SSE3-NEXT:    retq
725 ; AVX-LABEL: extract_extract_v16i32_sub_i32_commute:
726 ; AVX:       # %bb.0:
727 ; AVX-NEXT:    vmovd %xmm0, %ecx
728 ; AVX-NEXT:    vpextrd $1, %xmm0, %eax
729 ; AVX-NEXT:    subl %ecx, %eax
730 ; AVX-NEXT:    vzeroupper
731 ; AVX-NEXT:    retq
732   %x0 = extractelement <16 x i32> %x, i32 0
733   %x1 = extractelement <16 x i32> %x, i32 1
734   %x01 = sub i32 %x1, %x0
735   ret i32 %x01
738 define i16 @extract_extract_v32i16_sub_i16(<32 x i16> %x) {
739 ; SSE3-SLOW-LABEL: extract_extract_v32i16_sub_i16:
740 ; SSE3-SLOW:       # %bb.0:
741 ; SSE3-SLOW-NEXT:    movd %xmm0, %eax
742 ; SSE3-SLOW-NEXT:    pextrw $1, %xmm0, %ecx
743 ; SSE3-SLOW-NEXT:    subl %ecx, %eax
744 ; SSE3-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
745 ; SSE3-SLOW-NEXT:    retq
747 ; SSE3-FAST-LABEL: extract_extract_v32i16_sub_i16:
748 ; SSE3-FAST:       # %bb.0:
749 ; SSE3-FAST-NEXT:    phsubw %xmm0, %xmm0
750 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
751 ; SSE3-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
752 ; SSE3-FAST-NEXT:    retq
754 ; AVX-SLOW-LABEL: extract_extract_v32i16_sub_i16:
755 ; AVX-SLOW:       # %bb.0:
756 ; AVX-SLOW-NEXT:    vmovd %xmm0, %eax
757 ; AVX-SLOW-NEXT:    vpextrw $1, %xmm0, %ecx
758 ; AVX-SLOW-NEXT:    subl %ecx, %eax
759 ; AVX-SLOW-NEXT:    # kill: def $ax killed $ax killed $eax
760 ; AVX-SLOW-NEXT:    vzeroupper
761 ; AVX-SLOW-NEXT:    retq
763 ; AVX-FAST-LABEL: extract_extract_v32i16_sub_i16:
764 ; AVX-FAST:       # %bb.0:
765 ; AVX-FAST-NEXT:    vphsubw %xmm0, %xmm0, %xmm0
766 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
767 ; AVX-FAST-NEXT:    # kill: def $ax killed $ax killed $eax
768 ; AVX-FAST-NEXT:    vzeroupper
769 ; AVX-FAST-NEXT:    retq
770   %x0 = extractelement <32 x i16> %x, i32 0
771   %x1 = extractelement <32 x i16> %x, i32 1
772   %x01 = sub i16 %x0, %x1
773   ret i16 %x01
776 define i16 @extract_extract_v32i16_sub_i16_commute(<32 x i16> %x) {
777 ; SSE3-LABEL: extract_extract_v32i16_sub_i16_commute:
778 ; SSE3:       # %bb.0:
779 ; SSE3-NEXT:    movd %xmm0, %ecx
780 ; SSE3-NEXT:    pextrw $1, %xmm0, %eax
781 ; SSE3-NEXT:    subl %ecx, %eax
782 ; SSE3-NEXT:    # kill: def $ax killed $ax killed $eax
783 ; SSE3-NEXT:    retq
785 ; AVX-LABEL: extract_extract_v32i16_sub_i16_commute:
786 ; AVX:       # %bb.0:
787 ; AVX-NEXT:    vmovd %xmm0, %ecx
788 ; AVX-NEXT:    vpextrw $1, %xmm0, %eax
789 ; AVX-NEXT:    subl %ecx, %eax
790 ; AVX-NEXT:    # kill: def $ax killed $ax killed $eax
791 ; AVX-NEXT:    vzeroupper
792 ; AVX-NEXT:    retq
793   %x0 = extractelement <32 x i16> %x, i32 0
794   %x1 = extractelement <32 x i16> %x, i32 1
795   %x01 = sub i16 %x1, %x0
796   ret i16 %x01
799 ; Check output when 1 or both extracts have extra uses.
801 define i32 @extract_extract_v4i32_add_i32_uses1(<4 x i32> %x, i32* %p) {
802 ; SSE3-SLOW-LABEL: extract_extract_v4i32_add_i32_uses1:
803 ; SSE3-SLOW:       # %bb.0:
804 ; SSE3-SLOW-NEXT:    movd %xmm0, %ecx
805 ; SSE3-SLOW-NEXT:    movd %xmm0, (%rdi)
806 ; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
807 ; SSE3-SLOW-NEXT:    movd %xmm0, %eax
808 ; SSE3-SLOW-NEXT:    addl %ecx, %eax
809 ; SSE3-SLOW-NEXT:    retq
811 ; SSE3-FAST-LABEL: extract_extract_v4i32_add_i32_uses1:
812 ; SSE3-FAST:       # %bb.0:
813 ; SSE3-FAST-NEXT:    movd %xmm0, (%rdi)
814 ; SSE3-FAST-NEXT:    phaddd %xmm0, %xmm0
815 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
816 ; SSE3-FAST-NEXT:    retq
818 ; AVX-SLOW-LABEL: extract_extract_v4i32_add_i32_uses1:
819 ; AVX-SLOW:       # %bb.0:
820 ; AVX-SLOW-NEXT:    vmovd %xmm0, %ecx
821 ; AVX-SLOW-NEXT:    vmovd %xmm0, (%rdi)
822 ; AVX-SLOW-NEXT:    vpextrd $1, %xmm0, %eax
823 ; AVX-SLOW-NEXT:    addl %ecx, %eax
824 ; AVX-SLOW-NEXT:    retq
826 ; AVX-FAST-LABEL: extract_extract_v4i32_add_i32_uses1:
827 ; AVX-FAST:       # %bb.0:
828 ; AVX-FAST-NEXT:    vmovd %xmm0, (%rdi)
829 ; AVX-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
830 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
831 ; AVX-FAST-NEXT:    retq
832   %x0 = extractelement <4 x i32> %x, i32 0
833   store i32 %x0, i32* %p
834   %x1 = extractelement <4 x i32> %x, i32 1
835   %x01 = add i32 %x0, %x1
836   ret i32 %x01
839 define i32 @extract_extract_v4i32_add_i32_uses2(<4 x i32> %x, i32* %p) {
840 ; SSE3-SLOW-LABEL: extract_extract_v4i32_add_i32_uses2:
841 ; SSE3-SLOW:       # %bb.0:
842 ; SSE3-SLOW-NEXT:    movd %xmm0, %ecx
843 ; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
844 ; SSE3-SLOW-NEXT:    movd %xmm0, %eax
845 ; SSE3-SLOW-NEXT:    addl %ecx, %eax
846 ; SSE3-SLOW-NEXT:    movd %xmm0, (%rdi)
847 ; SSE3-SLOW-NEXT:    retq
849 ; SSE3-FAST-LABEL: extract_extract_v4i32_add_i32_uses2:
850 ; SSE3-FAST:       # %bb.0:
851 ; SSE3-FAST-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[1,1,2,3]
852 ; SSE3-FAST-NEXT:    movd %xmm1, (%rdi)
853 ; SSE3-FAST-NEXT:    phaddd %xmm0, %xmm0
854 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
855 ; SSE3-FAST-NEXT:    retq
857 ; AVX-SLOW-LABEL: extract_extract_v4i32_add_i32_uses2:
858 ; AVX-SLOW:       # %bb.0:
859 ; AVX-SLOW-NEXT:    vmovd %xmm0, %ecx
860 ; AVX-SLOW-NEXT:    vpextrd $1, %xmm0, %eax
861 ; AVX-SLOW-NEXT:    addl %ecx, %eax
862 ; AVX-SLOW-NEXT:    vpextrd $1, %xmm0, (%rdi)
863 ; AVX-SLOW-NEXT:    retq
865 ; AVX-FAST-LABEL: extract_extract_v4i32_add_i32_uses2:
866 ; AVX-FAST:       # %bb.0:
867 ; AVX-FAST-NEXT:    vpextrd $1, %xmm0, (%rdi)
868 ; AVX-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
869 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
870 ; AVX-FAST-NEXT:    retq
871   %x0 = extractelement <4 x i32> %x, i32 0
872   %x1 = extractelement <4 x i32> %x, i32 1
873   store i32 %x1, i32* %p
874   %x01 = add i32 %x0, %x1
875   ret i32 %x01
878 define i32 @extract_extract_v4i32_add_i32_uses3(<4 x i32> %x, i32* %p1, i32* %p2) {
879 ; SSE3-LABEL: extract_extract_v4i32_add_i32_uses3:
880 ; SSE3:       # %bb.0:
881 ; SSE3-NEXT:    movd %xmm0, %ecx
882 ; SSE3-NEXT:    movd %xmm0, (%rdi)
883 ; SSE3-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
884 ; SSE3-NEXT:    movd %xmm0, %eax
885 ; SSE3-NEXT:    addl %ecx, %eax
886 ; SSE3-NEXT:    movd %xmm0, (%rsi)
887 ; SSE3-NEXT:    retq
889 ; AVX-LABEL: extract_extract_v4i32_add_i32_uses3:
890 ; AVX:       # %bb.0:
891 ; AVX-NEXT:    vmovd %xmm0, %ecx
892 ; AVX-NEXT:    vmovd %xmm0, (%rdi)
893 ; AVX-NEXT:    vpextrd $1, %xmm0, %eax
894 ; AVX-NEXT:    addl %ecx, %eax
895 ; AVX-NEXT:    vpextrd $1, %xmm0, (%rsi)
896 ; AVX-NEXT:    retq
897   %x0 = extractelement <4 x i32> %x, i32 0
898   store i32 %x0, i32* %p1
899   %x1 = extractelement <4 x i32> %x, i32 1
900   store i32 %x1, i32* %p2
901   %x01 = add i32 %x0, %x1
902   ret i32 %x01
905 ; PR33758: https://bugs.llvm.org/show_bug.cgi?id=33758
907 define i32 @partial_reduction_add_v8i32(<8 x i32> %x) {
908 ; SSE3-SLOW-LABEL: partial_reduction_add_v8i32:
909 ; SSE3-SLOW:       # %bb.0:
910 ; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
911 ; SSE3-SLOW-NEXT:    paddd %xmm0, %xmm1
912 ; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,2,3]
913 ; SSE3-SLOW-NEXT:    paddd %xmm1, %xmm0
914 ; SSE3-SLOW-NEXT:    movd %xmm0, %eax
915 ; SSE3-SLOW-NEXT:    retq
917 ; SSE3-FAST-LABEL: partial_reduction_add_v8i32:
918 ; SSE3-FAST:       # %bb.0:
919 ; SSE3-FAST-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
920 ; SSE3-FAST-NEXT:    paddd %xmm0, %xmm1
921 ; SSE3-FAST-NEXT:    phaddd %xmm1, %xmm1
922 ; SSE3-FAST-NEXT:    movd %xmm1, %eax
923 ; SSE3-FAST-NEXT:    retq
925 ; AVX-SLOW-LABEL: partial_reduction_add_v8i32:
926 ; AVX-SLOW:       # %bb.0:
927 ; AVX-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
928 ; AVX-SLOW-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
929 ; AVX-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[1,1,2,3]
930 ; AVX-SLOW-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
931 ; AVX-SLOW-NEXT:    vmovd %xmm0, %eax
932 ; AVX-SLOW-NEXT:    vzeroupper
933 ; AVX-SLOW-NEXT:    retq
935 ; AVX-FAST-LABEL: partial_reduction_add_v8i32:
936 ; AVX-FAST:       # %bb.0:
937 ; AVX-FAST-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
938 ; AVX-FAST-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
939 ; AVX-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
940 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
941 ; AVX-FAST-NEXT:    vzeroupper
942 ; AVX-FAST-NEXT:    retq
943   %x23 = shufflevector <8 x i32> %x, <8 x i32> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
944   %x0213 = add <8 x i32> %x, %x23
945   %x13 = shufflevector <8 x i32> %x0213, <8 x i32> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
946   %x0123 = add <8 x i32> %x0213, %x13
947   %r = extractelement <8 x i32> %x0123, i32 0
948   ret i32 %r
951 define i32 @partial_reduction_add_v16i32(<16 x i32> %x) {
952 ; SSE3-SLOW-LABEL: partial_reduction_add_v16i32:
953 ; SSE3-SLOW:       # %bb.0:
954 ; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
955 ; SSE3-SLOW-NEXT:    paddd %xmm0, %xmm1
956 ; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[1,1,2,3]
957 ; SSE3-SLOW-NEXT:    paddd %xmm1, %xmm0
958 ; SSE3-SLOW-NEXT:    movd %xmm0, %eax
959 ; SSE3-SLOW-NEXT:    retq
961 ; SSE3-FAST-LABEL: partial_reduction_add_v16i32:
962 ; SSE3-FAST:       # %bb.0:
963 ; SSE3-FAST-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
964 ; SSE3-FAST-NEXT:    paddd %xmm0, %xmm1
965 ; SSE3-FAST-NEXT:    phaddd %xmm1, %xmm1
966 ; SSE3-FAST-NEXT:    movd %xmm1, %eax
967 ; SSE3-FAST-NEXT:    retq
969 ; AVX-SLOW-LABEL: partial_reduction_add_v16i32:
970 ; AVX-SLOW:       # %bb.0:
971 ; AVX-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
972 ; AVX-SLOW-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
973 ; AVX-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[1,1,2,3]
974 ; AVX-SLOW-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
975 ; AVX-SLOW-NEXT:    vmovd %xmm0, %eax
976 ; AVX-SLOW-NEXT:    vzeroupper
977 ; AVX-SLOW-NEXT:    retq
979 ; AVX1-FAST-LABEL: partial_reduction_add_v16i32:
980 ; AVX1-FAST:       # %bb.0:
981 ; AVX1-FAST-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
982 ; AVX1-FAST-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
983 ; AVX1-FAST-NEXT:    vphaddd %xmm0, %xmm0, %xmm0
984 ; AVX1-FAST-NEXT:    vmovd %xmm0, %eax
985 ; AVX1-FAST-NEXT:    vzeroupper
986 ; AVX1-FAST-NEXT:    retq
988 ; AVX2-FAST-LABEL: partial_reduction_add_v16i32:
989 ; AVX2-FAST:       # %bb.0:
990 ; AVX2-FAST-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
991 ; AVX2-FAST-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
992 ; AVX2-FAST-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[1,1,2,3]
993 ; AVX2-FAST-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
994 ; AVX2-FAST-NEXT:    vmovd %xmm0, %eax
995 ; AVX2-FAST-NEXT:    vzeroupper
996 ; AVX2-FAST-NEXT:    retq
998 ; AVX512-FAST-LABEL: partial_reduction_add_v16i32:
999 ; AVX512-FAST:       # %bb.0:
1000 ; AVX512-FAST-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
1001 ; AVX512-FAST-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
1002 ; AVX512-FAST-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[1,1,2,3]
1003 ; AVX512-FAST-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
1004 ; AVX512-FAST-NEXT:    vmovd %xmm0, %eax
1005 ; AVX512-FAST-NEXT:    vzeroupper
1006 ; AVX512-FAST-NEXT:    retq
1007   %x23 = shufflevector <16 x i32> %x, <16 x i32> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1008   %x0213 = add <16 x i32> %x, %x23
1009   %x13 = shufflevector <16 x i32> %x0213, <16 x i32> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1010   %x0123 = add <16 x i32> %x0213, %x13
1011   %r = extractelement <16 x i32> %x0123, i32 0
1012   ret i32 %r
1015 define i32 @partial_reduction_sub_v8i32(<8 x i32> %x) {
1016 ; SSE3-SLOW-LABEL: partial_reduction_sub_v8i32:
1017 ; SSE3-SLOW:       # %bb.0:
1018 ; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
1019 ; SSE3-SLOW-NEXT:    psubd %xmm1, %xmm0
1020 ; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[1,1,2,3]
1021 ; SSE3-SLOW-NEXT:    psubd %xmm1, %xmm0
1022 ; SSE3-SLOW-NEXT:    movd %xmm0, %eax
1023 ; SSE3-SLOW-NEXT:    retq
1025 ; SSE3-FAST-LABEL: partial_reduction_sub_v8i32:
1026 ; SSE3-FAST:       # %bb.0:
1027 ; SSE3-FAST-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
1028 ; SSE3-FAST-NEXT:    psubd %xmm1, %xmm0
1029 ; SSE3-FAST-NEXT:    phsubd %xmm0, %xmm0
1030 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
1031 ; SSE3-FAST-NEXT:    retq
1033 ; AVX-SLOW-LABEL: partial_reduction_sub_v8i32:
1034 ; AVX-SLOW:       # %bb.0:
1035 ; AVX-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
1036 ; AVX-SLOW-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
1037 ; AVX-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[1,1,2,3]
1038 ; AVX-SLOW-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
1039 ; AVX-SLOW-NEXT:    vmovd %xmm0, %eax
1040 ; AVX-SLOW-NEXT:    vzeroupper
1041 ; AVX-SLOW-NEXT:    retq
1043 ; AVX-FAST-LABEL: partial_reduction_sub_v8i32:
1044 ; AVX-FAST:       # %bb.0:
1045 ; AVX-FAST-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
1046 ; AVX-FAST-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
1047 ; AVX-FAST-NEXT:    vphsubd %xmm0, %xmm0, %xmm0
1048 ; AVX-FAST-NEXT:    vmovd %xmm0, %eax
1049 ; AVX-FAST-NEXT:    vzeroupper
1050 ; AVX-FAST-NEXT:    retq
1051   %x23 = shufflevector <8 x i32> %x, <8 x i32> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1052   %x0213 = sub <8 x i32> %x, %x23
1053   %x13 = shufflevector <8 x i32> %x0213, <8 x i32> undef, <8 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1054   %x0123 = sub <8 x i32> %x0213, %x13
1055   %r = extractelement <8 x i32> %x0123, i32 0
1056   ret i32 %r
1059 define i32 @partial_reduction_sub_v16i32(<16 x i32> %x) {
1060 ; SSE3-SLOW-LABEL: partial_reduction_sub_v16i32:
1061 ; SSE3-SLOW:       # %bb.0:
1062 ; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
1063 ; SSE3-SLOW-NEXT:    psubd %xmm1, %xmm0
1064 ; SSE3-SLOW-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[1,1,2,3]
1065 ; SSE3-SLOW-NEXT:    psubd %xmm1, %xmm0
1066 ; SSE3-SLOW-NEXT:    movd %xmm0, %eax
1067 ; SSE3-SLOW-NEXT:    retq
1069 ; SSE3-FAST-LABEL: partial_reduction_sub_v16i32:
1070 ; SSE3-FAST:       # %bb.0:
1071 ; SSE3-FAST-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
1072 ; SSE3-FAST-NEXT:    psubd %xmm1, %xmm0
1073 ; SSE3-FAST-NEXT:    phsubd %xmm0, %xmm0
1074 ; SSE3-FAST-NEXT:    movd %xmm0, %eax
1075 ; SSE3-FAST-NEXT:    retq
1077 ; AVX-SLOW-LABEL: partial_reduction_sub_v16i32:
1078 ; AVX-SLOW:       # %bb.0:
1079 ; AVX-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
1080 ; AVX-SLOW-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
1081 ; AVX-SLOW-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[1,1,2,3]
1082 ; AVX-SLOW-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
1083 ; AVX-SLOW-NEXT:    vmovd %xmm0, %eax
1084 ; AVX-SLOW-NEXT:    vzeroupper
1085 ; AVX-SLOW-NEXT:    retq
1087 ; AVX1-FAST-LABEL: partial_reduction_sub_v16i32:
1088 ; AVX1-FAST:       # %bb.0:
1089 ; AVX1-FAST-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
1090 ; AVX1-FAST-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
1091 ; AVX1-FAST-NEXT:    vphsubd %xmm0, %xmm0, %xmm0
1092 ; AVX1-FAST-NEXT:    vmovd %xmm0, %eax
1093 ; AVX1-FAST-NEXT:    vzeroupper
1094 ; AVX1-FAST-NEXT:    retq
1096 ; AVX2-FAST-LABEL: partial_reduction_sub_v16i32:
1097 ; AVX2-FAST:       # %bb.0:
1098 ; AVX2-FAST-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
1099 ; AVX2-FAST-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
1100 ; AVX2-FAST-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[1,1,2,3]
1101 ; AVX2-FAST-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
1102 ; AVX2-FAST-NEXT:    vmovd %xmm0, %eax
1103 ; AVX2-FAST-NEXT:    vzeroupper
1104 ; AVX2-FAST-NEXT:    retq
1106 ; AVX512-FAST-LABEL: partial_reduction_sub_v16i32:
1107 ; AVX512-FAST:       # %bb.0:
1108 ; AVX512-FAST-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[2,3,0,1]
1109 ; AVX512-FAST-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
1110 ; AVX512-FAST-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[1,1,2,3]
1111 ; AVX512-FAST-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
1112 ; AVX512-FAST-NEXT:    vmovd %xmm0, %eax
1113 ; AVX512-FAST-NEXT:    vzeroupper
1114 ; AVX512-FAST-NEXT:    retq
1115   %x23 = shufflevector <16 x i32> %x, <16 x i32> undef, <16 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1116   %x0213 = sub <16 x i32> %x, %x23
1117   %x13 = shufflevector <16 x i32> %x0213, <16 x i32> undef, <16 x i32> <i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
1118   %x0123 = sub <16 x i32> %x0213, %x13
1119   %r = extractelement <16 x i32> %x0123, i32 0
1120   ret i32 %r