Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / test / CodeGen / X86 / merge-consecutive-loads-256.ll
blob2feb9742c60952dd885e2d3559b64b5254dc362c
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX1
3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=AVX --check-prefix=AVX2
4 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f | FileCheck %s --check-prefix=AVX --check-prefix=AVX512F
6 ; Just one 32-bit run to make sure we do reasonable things.
7 ; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=X32-AVX
9 define <4 x double> @merge_4f64_2f64_23(<2 x double>* %ptr) nounwind uwtable noinline ssp {
10 ; AVX-LABEL: merge_4f64_2f64_23:
11 ; AVX:       # %bb.0:
12 ; AVX-NEXT:    vmovups 32(%rdi), %ymm0
13 ; AVX-NEXT:    retq
15 ; X32-AVX-LABEL: merge_4f64_2f64_23:
16 ; X32-AVX:       # %bb.0:
17 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
18 ; X32-AVX-NEXT:    vmovups 32(%eax), %ymm0
19 ; X32-AVX-NEXT:    retl
20   %ptr0 = getelementptr inbounds <2 x double>, <2 x double>* %ptr, i64 2
21   %ptr1 = getelementptr inbounds <2 x double>, <2 x double>* %ptr, i64 3
22   %val0 = load <2 x double>, <2 x double>* %ptr0
23   %val1 = load <2 x double>, <2 x double>* %ptr1
24   %res = shufflevector <2 x double> %val0, <2 x double> %val1, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
25   ret <4 x double> %res
28 define <4 x double> @merge_4f64_2f64_2z(<2 x double>* %ptr) nounwind uwtable noinline ssp {
29 ; AVX-LABEL: merge_4f64_2f64_2z:
30 ; AVX:       # %bb.0:
31 ; AVX-NEXT:    vmovaps 32(%rdi), %xmm0
32 ; AVX-NEXT:    retq
34 ; X32-AVX-LABEL: merge_4f64_2f64_2z:
35 ; X32-AVX:       # %bb.0:
36 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
37 ; X32-AVX-NEXT:    vmovaps 32(%eax), %xmm0
38 ; X32-AVX-NEXT:    retl
39   %ptr0 = getelementptr inbounds <2 x double>, <2 x double>* %ptr, i64 2
40   %val0 = load <2 x double>, <2 x double>* %ptr0
41   %res = shufflevector <2 x double> %val0, <2 x double> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
42   ret <4 x double> %res
45 define <4 x double> @merge_4f64_f64_2345(double* %ptr) nounwind uwtable noinline ssp {
46 ; AVX-LABEL: merge_4f64_f64_2345:
47 ; AVX:       # %bb.0:
48 ; AVX-NEXT:    vmovups 16(%rdi), %ymm0
49 ; AVX-NEXT:    retq
51 ; X32-AVX-LABEL: merge_4f64_f64_2345:
52 ; X32-AVX:       # %bb.0:
53 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
54 ; X32-AVX-NEXT:    vmovups 16(%eax), %ymm0
55 ; X32-AVX-NEXT:    retl
56   %ptr0 = getelementptr inbounds double, double* %ptr, i64 2
57   %ptr1 = getelementptr inbounds double, double* %ptr, i64 3
58   %ptr2 = getelementptr inbounds double, double* %ptr, i64 4
59   %ptr3 = getelementptr inbounds double, double* %ptr, i64 5
60   %val0 = load double, double* %ptr0
61   %val1 = load double, double* %ptr1
62   %val2 = load double, double* %ptr2
63   %val3 = load double, double* %ptr3
64   %res0 = insertelement <4 x double> undef, double %val0, i32 0
65   %res1 = insertelement <4 x double> %res0, double %val1, i32 1
66   %res2 = insertelement <4 x double> %res1, double %val2, i32 2
67   %res3 = insertelement <4 x double> %res2, double %val3, i32 3
68   ret <4 x double> %res3
71 define <4 x double> @merge_4f64_f64_3zuu(double* %ptr) nounwind uwtable noinline ssp {
72 ; AVX-LABEL: merge_4f64_f64_3zuu:
73 ; AVX:       # %bb.0:
74 ; AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
75 ; AVX-NEXT:    retq
77 ; X32-AVX-LABEL: merge_4f64_f64_3zuu:
78 ; X32-AVX:       # %bb.0:
79 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
80 ; X32-AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
81 ; X32-AVX-NEXT:    retl
82   %ptr0 = getelementptr inbounds double, double* %ptr, i64 3
83   %val0 = load double, double* %ptr0
84   %res0 = insertelement <4 x double> undef, double %val0, i32 0
85   %res1 = insertelement <4 x double> %res0, double 0.0, i32 1
86   ret <4 x double> %res1
89 define <4 x double> @merge_4f64_f64_34uu(double* %ptr) nounwind uwtable noinline ssp {
90 ; AVX-LABEL: merge_4f64_f64_34uu:
91 ; AVX:       # %bb.0:
92 ; AVX-NEXT:    vmovups 24(%rdi), %xmm0
93 ; AVX-NEXT:    retq
95 ; X32-AVX-LABEL: merge_4f64_f64_34uu:
96 ; X32-AVX:       # %bb.0:
97 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
98 ; X32-AVX-NEXT:    vmovups 24(%eax), %xmm0
99 ; X32-AVX-NEXT:    retl
100   %ptr0 = getelementptr inbounds double, double* %ptr, i64 3
101   %ptr1 = getelementptr inbounds double, double* %ptr, i64 4
102   %val0 = load double, double* %ptr0
103   %val1 = load double, double* %ptr1
104   %res0 = insertelement <4 x double> undef, double %val0, i32 0
105   %res1 = insertelement <4 x double> %res0, double %val1, i32 1
106   ret <4 x double> %res1
109 define <4 x double> @merge_4f64_f64_45zz(double* %ptr) nounwind uwtable noinline ssp {
110 ; AVX-LABEL: merge_4f64_f64_45zz:
111 ; AVX:       # %bb.0:
112 ; AVX-NEXT:    vmovups 32(%rdi), %xmm0
113 ; AVX-NEXT:    retq
115 ; X32-AVX-LABEL: merge_4f64_f64_45zz:
116 ; X32-AVX:       # %bb.0:
117 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
118 ; X32-AVX-NEXT:    vmovups 32(%eax), %xmm0
119 ; X32-AVX-NEXT:    retl
120   %ptr0 = getelementptr inbounds double, double* %ptr, i64 4
121   %ptr1 = getelementptr inbounds double, double* %ptr, i64 5
122   %val0 = load double, double* %ptr0
123   %val1 = load double, double* %ptr1
124   %res0 = insertelement <4 x double> zeroinitializer, double %val0, i32 0
125   %res1 = insertelement <4 x double> %res0, double %val1, i32 1
126   ret <4 x double> %res1
129 define <4 x double> @merge_4f64_f64_34z6(double* %ptr) nounwind uwtable noinline ssp {
130 ; AVX-LABEL: merge_4f64_f64_34z6:
131 ; AVX:       # %bb.0:
132 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
133 ; AVX-NEXT:    vblendps {{.*#+}} ymm0 = mem[0,1,2,3],ymm0[4,5],mem[6,7]
134 ; AVX-NEXT:    retq
136 ; X32-AVX-LABEL: merge_4f64_f64_34z6:
137 ; X32-AVX:       # %bb.0:
138 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
139 ; X32-AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
140 ; X32-AVX-NEXT:    vblendps {{.*#+}} ymm0 = mem[0,1,2,3],ymm0[4,5],mem[6,7]
141 ; X32-AVX-NEXT:    retl
142   %ptr0 = getelementptr inbounds double, double* %ptr, i64 3
143   %ptr1 = getelementptr inbounds double, double* %ptr, i64 4
144   %ptr3 = getelementptr inbounds double, double* %ptr, i64 6
145   %val0 = load double, double* %ptr0
146   %val1 = load double, double* %ptr1
147   %val3 = load double, double* %ptr3
148   %res0 = insertelement <4 x double> undef, double %val0, i32 0
149   %res1 = insertelement <4 x double> %res0, double %val1, i32 1
150   %res2 = insertelement <4 x double> %res1, double   0.0, i32 2
151   %res3 = insertelement <4 x double> %res2, double %val3, i32 3
152   ret <4 x double> %res3
155 define <4 x i64> @merge_4i64_2i64_3z(<2 x i64>* %ptr) nounwind uwtable noinline ssp {
156 ; AVX-LABEL: merge_4i64_2i64_3z:
157 ; AVX:       # %bb.0:
158 ; AVX-NEXT:    vmovaps 48(%rdi), %xmm0
159 ; AVX-NEXT:    retq
161 ; X32-AVX-LABEL: merge_4i64_2i64_3z:
162 ; X32-AVX:       # %bb.0:
163 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
164 ; X32-AVX-NEXT:    vmovaps 48(%eax), %xmm0
165 ; X32-AVX-NEXT:    retl
166   %ptr0 = getelementptr inbounds <2 x i64>, <2 x i64>* %ptr, i64 3
167   %val0 = load <2 x i64>, <2 x i64>* %ptr0
168   %res = shufflevector <2 x i64> %val0, <2 x i64> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
169   ret <4 x i64> %res
172 define <4 x i64> @merge_4i64_i64_1234(i64* %ptr) nounwind uwtable noinline ssp {
173 ; AVX-LABEL: merge_4i64_i64_1234:
174 ; AVX:       # %bb.0:
175 ; AVX-NEXT:    vmovups 8(%rdi), %ymm0
176 ; AVX-NEXT:    retq
178 ; X32-AVX-LABEL: merge_4i64_i64_1234:
179 ; X32-AVX:       # %bb.0:
180 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
181 ; X32-AVX-NEXT:    vmovups 8(%eax), %ymm0
182 ; X32-AVX-NEXT:    retl
183   %ptr0 = getelementptr inbounds i64, i64* %ptr, i64 1
184   %ptr1 = getelementptr inbounds i64, i64* %ptr, i64 2
185   %ptr2 = getelementptr inbounds i64, i64* %ptr, i64 3
186   %ptr3 = getelementptr inbounds i64, i64* %ptr, i64 4
187   %val0 = load i64, i64* %ptr0
188   %val1 = load i64, i64* %ptr1
189   %val2 = load i64, i64* %ptr2
190   %val3 = load i64, i64* %ptr3
191   %res0 = insertelement <4 x i64> undef, i64 %val0, i32 0
192   %res1 = insertelement <4 x i64> %res0, i64 %val1, i32 1
193   %res2 = insertelement <4 x i64> %res1, i64 %val2, i32 2
194   %res3 = insertelement <4 x i64> %res2, i64 %val3, i32 3
195   ret <4 x i64> %res3
198 define <4 x i64> @merge_4i64_i64_1zzu(i64* %ptr) nounwind uwtable noinline ssp {
199 ; AVX-LABEL: merge_4i64_i64_1zzu:
200 ; AVX:       # %bb.0:
201 ; AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
202 ; AVX-NEXT:    retq
204 ; X32-AVX-LABEL: merge_4i64_i64_1zzu:
205 ; X32-AVX:       # %bb.0:
206 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
207 ; X32-AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
208 ; X32-AVX-NEXT:    retl
209   %ptr0 = getelementptr inbounds i64, i64* %ptr, i64 1
210   %val0 = load i64, i64* %ptr0
211   %res0 = insertelement <4 x i64> undef, i64 %val0, i32 0
212   %res1 = insertelement <4 x i64> %res0, i64 0, i32 1
213   %res2 = insertelement <4 x i64> %res1, i64 0, i32 2
214   ret <4 x i64> %res2
217 define <4 x i64> @merge_4i64_i64_23zz(i64* %ptr) nounwind uwtable noinline ssp {
218 ; AVX-LABEL: merge_4i64_i64_23zz:
219 ; AVX:       # %bb.0:
220 ; AVX-NEXT:    vmovups 16(%rdi), %xmm0
221 ; AVX-NEXT:    retq
223 ; X32-AVX-LABEL: merge_4i64_i64_23zz:
224 ; X32-AVX:       # %bb.0:
225 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
226 ; X32-AVX-NEXT:    vmovups 16(%eax), %xmm0
227 ; X32-AVX-NEXT:    retl
228   %ptr0 = getelementptr inbounds i64, i64* %ptr, i64 2
229   %ptr1 = getelementptr inbounds i64, i64* %ptr, i64 3
230   %val0 = load i64, i64* %ptr0
231   %val1 = load i64, i64* %ptr1
232   %res0 = insertelement <4 x i64> zeroinitializer, i64 %val0, i32 0
233   %res1 = insertelement <4 x i64> %res0, i64 %val1, i32 1
234   ret <4 x i64> %res1
237 define <8 x float> @merge_8f32_2f32_23z5(<2 x float>* %ptr) nounwind uwtable noinline ssp {
238 ; AVX1-LABEL: merge_8f32_2f32_23z5:
239 ; AVX1:       # %bb.0:
240 ; AVX1-NEXT:    vmovups 16(%rdi), %xmm0
241 ; AVX1-NEXT:    vxorpd %xmm1, %xmm1, %xmm1
242 ; AVX1-NEXT:    vmovhpd {{.*#+}} xmm1 = xmm1[0],mem[0]
243 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
244 ; AVX1-NEXT:    retq
246 ; AVX2-LABEL: merge_8f32_2f32_23z5:
247 ; AVX2:       # %bb.0:
248 ; AVX2-NEXT:    vmovupd 16(%rdi), %xmm0
249 ; AVX2-NEXT:    vxorpd %xmm1, %xmm1, %xmm1
250 ; AVX2-NEXT:    vmovhpd {{.*#+}} xmm1 = xmm1[0],mem[0]
251 ; AVX2-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
252 ; AVX2-NEXT:    retq
254 ; AVX512F-LABEL: merge_8f32_2f32_23z5:
255 ; AVX512F:       # %bb.0:
256 ; AVX512F-NEXT:    vmovupd 16(%rdi), %xmm0
257 ; AVX512F-NEXT:    vxorpd %xmm1, %xmm1, %xmm1
258 ; AVX512F-NEXT:    vmovhpd {{.*#+}} xmm1 = xmm1[0],mem[0]
259 ; AVX512F-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
260 ; AVX512F-NEXT:    retq
262 ; X32-AVX-LABEL: merge_8f32_2f32_23z5:
263 ; X32-AVX:       # %bb.0:
264 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
265 ; X32-AVX-NEXT:    vmovups 16(%eax), %xmm0
266 ; X32-AVX-NEXT:    vxorpd %xmm1, %xmm1, %xmm1
267 ; X32-AVX-NEXT:    vmovhpd {{.*#+}} xmm1 = xmm1[0],mem[0]
268 ; X32-AVX-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
269 ; X32-AVX-NEXT:    retl
270   %ptr0 = getelementptr inbounds <2 x float>, <2 x float>* %ptr, i64 2
271   %ptr1 = getelementptr inbounds <2 x float>, <2 x float>* %ptr, i64 3
272   %ptr3 = getelementptr inbounds <2 x float>, <2 x float>* %ptr, i64 5
273   %val0 = load <2 x float>, <2 x float>* %ptr0
274   %val1 = load <2 x float>, <2 x float>* %ptr1
275   %val3 = load <2 x float>, <2 x float>* %ptr3
276   %res01 = shufflevector <2 x float> %val0, <2 x float> %val1, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
277   %res23 = shufflevector <2 x float> zeroinitializer, <2 x float> %val3, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
278   %res = shufflevector <4 x float> %res01, <4 x float> %res23, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
279   ret <8 x float> %res
282 define <8 x float> @merge_8f32_4f32_z2(<4 x float>* %ptr) nounwind uwtable noinline ssp {
283 ; AVX-LABEL: merge_8f32_4f32_z2:
284 ; AVX:       # %bb.0:
285 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
286 ; AVX-NEXT:    vinsertf128 $1, 32(%rdi), %ymm0, %ymm0
287 ; AVX-NEXT:    retq
289 ; X32-AVX-LABEL: merge_8f32_4f32_z2:
290 ; X32-AVX:       # %bb.0:
291 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
292 ; X32-AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
293 ; X32-AVX-NEXT:    vinsertf128 $1, 32(%eax), %ymm0, %ymm0
294 ; X32-AVX-NEXT:    retl
295   %ptr1 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i64 2
296   %val1 = load <4 x float>, <4 x float>* %ptr1
297   %res = shufflevector <4 x float> zeroinitializer, <4 x float> %val1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
298   ret <8 x float> %res
301 define <8 x float> @merge_8f32_f32_12zzuuzz(float* %ptr) nounwind uwtable noinline ssp {
302 ; AVX-LABEL: merge_8f32_f32_12zzuuzz:
303 ; AVX:       # %bb.0:
304 ; AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
305 ; AVX-NEXT:    retq
307 ; X32-AVX-LABEL: merge_8f32_f32_12zzuuzz:
308 ; X32-AVX:       # %bb.0:
309 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
310 ; X32-AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
311 ; X32-AVX-NEXT:    retl
312   %ptr0 = getelementptr inbounds float, float* %ptr, i64 1
313   %ptr1 = getelementptr inbounds float, float* %ptr, i64 2
314   %val0 = load float, float* %ptr0
315   %val1 = load float, float* %ptr1
316   %res0 = insertelement <8 x float> undef, float %val0, i32 0
317   %res1 = insertelement <8 x float> %res0, float %val1, i32 1
318   %res2 = insertelement <8 x float> %res1, float   0.0, i32 2
319   %res3 = insertelement <8 x float> %res2, float   0.0, i32 3
320   %res6 = insertelement <8 x float> %res3, float   0.0, i32 6
321   %res7 = insertelement <8 x float> %res6, float   0.0, i32 7
322   ret <8 x float> %res7
325 define <8 x float> @merge_8f32_f32_1u3u5zu8(float* %ptr) nounwind uwtable noinline ssp {
326 ; AVX-LABEL: merge_8f32_f32_1u3u5zu8:
327 ; AVX:       # %bb.0:
328 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
329 ; AVX-NEXT:    vblendps {{.*#+}} ymm0 = mem[0,1,2,3,4],ymm0[5],mem[6,7]
330 ; AVX-NEXT:    retq
332 ; X32-AVX-LABEL: merge_8f32_f32_1u3u5zu8:
333 ; X32-AVX:       # %bb.0:
334 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
335 ; X32-AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
336 ; X32-AVX-NEXT:    vblendps {{.*#+}} ymm0 = mem[0,1,2,3,4],ymm0[5],mem[6,7]
337 ; X32-AVX-NEXT:    retl
338   %ptr0 = getelementptr inbounds float, float* %ptr, i64 1
339   %ptr2 = getelementptr inbounds float, float* %ptr, i64 3
340   %ptr4 = getelementptr inbounds float, float* %ptr, i64 5
341   %ptr7 = getelementptr inbounds float, float* %ptr, i64 8
342   %val0 = load float, float* %ptr0
343   %val2 = load float, float* %ptr2
344   %val4 = load float, float* %ptr4
345   %val7 = load float, float* %ptr7
346   %res0 = insertelement <8 x float> undef, float %val0, i32 0
347   %res2 = insertelement <8 x float> %res0, float %val2, i32 2
348   %res4 = insertelement <8 x float> %res2, float %val4, i32 4
349   %res5 = insertelement <8 x float> %res4, float   0.0, i32 5
350   %res7 = insertelement <8 x float> %res5, float %val7, i32 7
351   ret <8 x float> %res7
354 define <8 x i32> @merge_8i32_4i32_z3(<4 x i32>* %ptr) nounwind uwtable noinline ssp {
355 ; AVX-LABEL: merge_8i32_4i32_z3:
356 ; AVX:       # %bb.0:
357 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
358 ; AVX-NEXT:    vinsertf128 $1, 48(%rdi), %ymm0, %ymm0
359 ; AVX-NEXT:    retq
361 ; X32-AVX-LABEL: merge_8i32_4i32_z3:
362 ; X32-AVX:       # %bb.0:
363 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
364 ; X32-AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
365 ; X32-AVX-NEXT:    vinsertf128 $1, 48(%eax), %ymm0, %ymm0
366 ; X32-AVX-NEXT:    retl
367   %ptr1 = getelementptr inbounds <4 x i32>, <4 x i32>* %ptr, i64 3
368   %val1 = load <4 x i32>, <4 x i32>* %ptr1
369   %res = shufflevector <4 x i32> zeroinitializer, <4 x i32> %val1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
370   ret <8 x i32> %res
373 define <8 x i32> @merge_8i32_i32_56zz9uzz(i32* %ptr) nounwind uwtable noinline ssp {
374 ; AVX-LABEL: merge_8i32_i32_56zz9uzz:
375 ; AVX:       # %bb.0:
376 ; AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
377 ; AVX-NEXT:    vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero
378 ; AVX-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
379 ; AVX-NEXT:    retq
381 ; X32-AVX-LABEL: merge_8i32_i32_56zz9uzz:
382 ; X32-AVX:       # %bb.0:
383 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
384 ; X32-AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
385 ; X32-AVX-NEXT:    vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero
386 ; X32-AVX-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
387 ; X32-AVX-NEXT:    retl
388   %ptr0 = getelementptr inbounds i32, i32* %ptr, i64 5
389   %ptr1 = getelementptr inbounds i32, i32* %ptr, i64 6
390   %ptr4 = getelementptr inbounds i32, i32* %ptr, i64 9
391   %val0 = load i32, i32* %ptr0
392   %val1 = load i32, i32* %ptr1
393   %val4 = load i32, i32* %ptr4
394   %res0 = insertelement <8 x i32> undef, i32 %val0, i32 0
395   %res1 = insertelement <8 x i32> %res0, i32 %val1, i32 1
396   %res2 = insertelement <8 x i32> %res1, i32     0, i32 2
397   %res3 = insertelement <8 x i32> %res2, i32     0, i32 3
398   %res4 = insertelement <8 x i32> %res3, i32 %val4, i32 4
399   %res6 = insertelement <8 x i32> %res4, i32     0, i32 6
400   %res7 = insertelement <8 x i32> %res6, i32     0, i32 7
401   ret <8 x i32> %res7
404 define <8 x i32> @merge_8i32_i32_1u3u5zu8(i32* %ptr) nounwind uwtable noinline ssp {
405 ; AVX-LABEL: merge_8i32_i32_1u3u5zu8:
406 ; AVX:       # %bb.0:
407 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
408 ; AVX-NEXT:    vblendps {{.*#+}} ymm0 = mem[0,1,2,3,4],ymm0[5],mem[6,7]
409 ; AVX-NEXT:    retq
411 ; X32-AVX-LABEL: merge_8i32_i32_1u3u5zu8:
412 ; X32-AVX:       # %bb.0:
413 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
414 ; X32-AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
415 ; X32-AVX-NEXT:    vblendps {{.*#+}} ymm0 = mem[0,1,2,3,4],ymm0[5],mem[6,7]
416 ; X32-AVX-NEXT:    retl
417   %ptr0 = getelementptr inbounds i32, i32* %ptr, i64 1
418   %ptr2 = getelementptr inbounds i32, i32* %ptr, i64 3
419   %ptr4 = getelementptr inbounds i32, i32* %ptr, i64 5
420   %ptr7 = getelementptr inbounds i32, i32* %ptr, i64 8
421   %val0 = load i32, i32* %ptr0
422   %val2 = load i32, i32* %ptr2
423   %val4 = load i32, i32* %ptr4
424   %val7 = load i32, i32* %ptr7
425   %res0 = insertelement <8 x i32> undef, i32 %val0, i32 0
426   %res2 = insertelement <8 x i32> %res0, i32 %val2, i32 2
427   %res4 = insertelement <8 x i32> %res2, i32 %val4, i32 4
428   %res5 = insertelement <8 x i32> %res4, i32     0, i32 5
429   %res7 = insertelement <8 x i32> %res5, i32 %val7, i32 7
430   ret <8 x i32> %res7
433 define <16 x i16> @merge_16i16_i16_89zzzuuuuuuuuuuuz(i16* %ptr) nounwind uwtable noinline ssp {
434 ; AVX-LABEL: merge_16i16_i16_89zzzuuuuuuuuuuuz:
435 ; AVX:       # %bb.0:
436 ; AVX-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
437 ; AVX-NEXT:    retq
439 ; X32-AVX-LABEL: merge_16i16_i16_89zzzuuuuuuuuuuuz:
440 ; X32-AVX:       # %bb.0:
441 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
442 ; X32-AVX-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
443 ; X32-AVX-NEXT:    retl
444   %ptr0 = getelementptr inbounds i16, i16* %ptr, i64 8
445   %ptr1 = getelementptr inbounds i16, i16* %ptr, i64 9
446   %val0 = load i16, i16* %ptr0
447   %val1 = load i16, i16* %ptr1
448   %res0 = insertelement <16 x i16> undef, i16 %val0, i16 0
449   %res1 = insertelement <16 x i16> %res0, i16 %val1, i16 1
450   %res2 = insertelement <16 x i16> %res1, i16     0, i16 2
451   %res3 = insertelement <16 x i16> %res2, i16     0, i16 3
452   %res4 = insertelement <16 x i16> %res3, i16     0, i16 4
453   %resF = insertelement <16 x i16> %res4, i16     0, i16 15
454   ret <16 x i16> %resF
457 define <16 x i16> @merge_16i16_i16_45u7uuuuuuuuuuuu(i16* %ptr) nounwind uwtable noinline ssp {
458 ; AVX-LABEL: merge_16i16_i16_45u7uuuuuuuuuuuu:
459 ; AVX:       # %bb.0:
460 ; AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
461 ; AVX-NEXT:    retq
463 ; X32-AVX-LABEL: merge_16i16_i16_45u7uuuuuuuuuuuu:
464 ; X32-AVX:       # %bb.0:
465 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
466 ; X32-AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
467 ; X32-AVX-NEXT:    retl
468   %ptr0 = getelementptr inbounds i16, i16* %ptr, i64 4
469   %ptr1 = getelementptr inbounds i16, i16* %ptr, i64 5
470   %ptr3 = getelementptr inbounds i16, i16* %ptr, i64 7
471   %val0 = load i16, i16* %ptr0
472   %val1 = load i16, i16* %ptr1
473   %val3 = load i16, i16* %ptr3
474   %res0 = insertelement <16 x i16> undef, i16 %val0, i16 0
475   %res1 = insertelement <16 x i16> %res0, i16 %val1, i16 1
476   %res3 = insertelement <16 x i16> %res1, i16 %val3, i16 3
477   ret <16 x i16> %res3
480 define <16 x i16> @merge_16i16_i16_0uu3uuuuuuuuCuEF(i16* %ptr) nounwind uwtable noinline ssp {
481 ; AVX-LABEL: merge_16i16_i16_0uu3uuuuuuuuCuEF:
482 ; AVX:       # %bb.0:
483 ; AVX-NEXT:    vmovups (%rdi), %ymm0
484 ; AVX-NEXT:    retq
486 ; X32-AVX-LABEL: merge_16i16_i16_0uu3uuuuuuuuCuEF:
487 ; X32-AVX:       # %bb.0:
488 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
489 ; X32-AVX-NEXT:    vmovups (%eax), %ymm0
490 ; X32-AVX-NEXT:    retl
491   %ptr0 = getelementptr inbounds i16, i16* %ptr, i64 0
492   %ptr3 = getelementptr inbounds i16, i16* %ptr, i64 3
493   %ptrC = getelementptr inbounds i16, i16* %ptr, i64 12
494   %ptrE = getelementptr inbounds i16, i16* %ptr, i64 14
495   %ptrF = getelementptr inbounds i16, i16* %ptr, i64 15
496   %val0 = load i16, i16* %ptr0
497   %val3 = load i16, i16* %ptr3
498   %valC = load i16, i16* %ptrC
499   %valE = load i16, i16* %ptrE
500   %valF = load i16, i16* %ptrF
501   %res0 = insertelement <16 x i16> undef, i16 %val0, i16 0
502   %res3 = insertelement <16 x i16> %res0, i16 %val3, i16 3
503   %resC = insertelement <16 x i16> %res3, i16 %valC, i16 12
504   %resE = insertelement <16 x i16> %resC, i16 %valE, i16 14
505   %resF = insertelement <16 x i16> %resE, i16 %valF, i16 15
506   ret <16 x i16> %resF
509 define <16 x i16> @merge_16i16_i16_0uu3zzuuuuuzCuEF(i16* %ptr) nounwind uwtable noinline ssp {
510 ; AVX-LABEL: merge_16i16_i16_0uu3zzuuuuuzCuEF:
511 ; AVX:       # %bb.0:
512 ; AVX-NEXT:    vmovups (%rdi), %ymm0
513 ; AVX-NEXT:    vandps {{.*}}(%rip), %ymm0, %ymm0
514 ; AVX-NEXT:    retq
516 ; X32-AVX-LABEL: merge_16i16_i16_0uu3zzuuuuuzCuEF:
517 ; X32-AVX:       # %bb.0:
518 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
519 ; X32-AVX-NEXT:    vmovups (%eax), %ymm0
520 ; X32-AVX-NEXT:    vandps {{\.LCPI.*}}, %ymm0, %ymm0
521 ; X32-AVX-NEXT:    retl
522   %ptr0 = getelementptr inbounds i16, i16* %ptr, i64 0
523   %ptr3 = getelementptr inbounds i16, i16* %ptr, i64 3
524   %ptrC = getelementptr inbounds i16, i16* %ptr, i64 12
525   %ptrE = getelementptr inbounds i16, i16* %ptr, i64 14
526   %ptrF = getelementptr inbounds i16, i16* %ptr, i64 15
527   %val0 = load i16, i16* %ptr0
528   %val3 = load i16, i16* %ptr3
529   %valC = load i16, i16* %ptrC
530   %valE = load i16, i16* %ptrE
531   %valF = load i16, i16* %ptrF
532   %res0 = insertelement <16 x i16> undef, i16 %val0, i16 0
533   %res3 = insertelement <16 x i16> %res0, i16 %val3, i16 3
534   %res4 = insertelement <16 x i16> %res3, i16     0, i16 4
535   %res5 = insertelement <16 x i16> %res4, i16     0, i16 5
536   %resC = insertelement <16 x i16> %res5, i16 %valC, i16 12
537   %resD = insertelement <16 x i16> %resC, i16     0, i16 13
538   %resE = insertelement <16 x i16> %resD, i16 %valE, i16 14
539   %resF = insertelement <16 x i16> %resE, i16 %valF, i16 15
540   ret <16 x i16> %resF
543 define <32 x i8> @merge_32i8_i8_45u7uuuuuuuuuuuuuuuuuuuuuuuuuuuu(i8* %ptr) nounwind uwtable noinline ssp {
544 ; AVX-LABEL: merge_32i8_i8_45u7uuuuuuuuuuuuuuuuuuuuuuuuuuuu:
545 ; AVX:       # %bb.0:
546 ; AVX-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
547 ; AVX-NEXT:    retq
549 ; X32-AVX-LABEL: merge_32i8_i8_45u7uuuuuuuuuuuuuuuuuuuuuuuuuuuu:
550 ; X32-AVX:       # %bb.0:
551 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
552 ; X32-AVX-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
553 ; X32-AVX-NEXT:    retl
554   %ptr0 = getelementptr inbounds i8, i8* %ptr, i64 4
555   %ptr1 = getelementptr inbounds i8, i8* %ptr, i64 5
556   %ptr3 = getelementptr inbounds i8, i8* %ptr, i64 7
557   %val0 = load i8, i8* %ptr0
558   %val1 = load i8, i8* %ptr1
559   %val3 = load i8, i8* %ptr3
560   %res0 = insertelement <32 x i8> undef, i8 %val0, i8 0
561   %res1 = insertelement <32 x i8> %res0, i8 %val1, i8 1
562   %res3 = insertelement <32 x i8> %res1, i8 %val3, i8 3
563   ret <32 x i8> %res3
566 define <32 x i8> @merge_32i8_i8_23u5uuuuuuuuuuzzzzuuuuuuuuuuuuuu(i8* %ptr) nounwind uwtable noinline ssp {
567 ; AVX-LABEL: merge_32i8_i8_23u5uuuuuuuuuuzzzzuuuuuuuuuuuuuu:
568 ; AVX:       # %bb.0:
569 ; AVX-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
570 ; AVX-NEXT:    retq
572 ; X32-AVX-LABEL: merge_32i8_i8_23u5uuuuuuuuuuzzzzuuuuuuuuuuuuuu:
573 ; X32-AVX:       # %bb.0:
574 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
575 ; X32-AVX-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
576 ; X32-AVX-NEXT:    retl
577   %ptr0 = getelementptr inbounds i8, i8* %ptr, i64 2
578   %ptr1 = getelementptr inbounds i8, i8* %ptr, i64 3
579   %ptr3 = getelementptr inbounds i8, i8* %ptr, i64 5
580   %val0 = load i8, i8* %ptr0
581   %val1 = load i8, i8* %ptr1
582   %val3 = load i8, i8* %ptr3
583   %res0 = insertelement <32 x i8> undef, i8 %val0, i8 0
584   %res1 = insertelement <32 x i8> %res0, i8 %val1, i8 1
585   %res3 = insertelement <32 x i8> %res1, i8 %val3, i8 3
586   %resE = insertelement <32 x i8> %res3, i8     0, i8 14
587   %resF = insertelement <32 x i8> %resE, i8     0, i8 15
588   %resG = insertelement <32 x i8> %resF, i8     0, i8 16
589   %resH = insertelement <32 x i8> %resG, i8     0, i8 17
590   ret <32 x i8> %resH
594 ; consecutive loads including any/all volatiles may not be combined
597 define <4 x double> @merge_4f64_f64_34uz_volatile(double* %ptr) nounwind uwtable noinline ssp {
598 ; AVX-LABEL: merge_4f64_f64_34uz_volatile:
599 ; AVX:       # %bb.0:
600 ; AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
601 ; AVX-NEXT:    vmovhpd {{.*#+}} xmm0 = xmm0[0],mem[0]
602 ; AVX-NEXT:    retq
604 ; X32-AVX-LABEL: merge_4f64_f64_34uz_volatile:
605 ; X32-AVX:       # %bb.0:
606 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
607 ; X32-AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
608 ; X32-AVX-NEXT:    vmovhpd {{.*#+}} xmm0 = xmm0[0],mem[0]
609 ; X32-AVX-NEXT:    retl
610   %ptr0 = getelementptr inbounds double, double* %ptr, i64 3
611   %ptr1 = getelementptr inbounds double, double* %ptr, i64 4
612   %val0 = load volatile double, double* %ptr0
613   %val1 = load volatile double, double* %ptr1
614   %res0 = insertelement <4 x double> undef, double %val0, i32 0
615   %res1 = insertelement <4 x double> %res0, double %val1, i32 1
616   %res3 = insertelement <4 x double> %res1, double   0.0, i32 3
617   ret <4 x double> %res3
620 define <16 x i16> @merge_16i16_i16_0uu3zzuuuuuzCuEF_volatile(i16* %ptr) nounwind uwtable noinline ssp {
621 ; AVX1-LABEL: merge_16i16_i16_0uu3zzuuuuuzCuEF_volatile:
622 ; AVX1:       # %bb.0:
623 ; AVX1-NEXT:    vpxor %xmm0, %xmm0, %xmm0
624 ; AVX1-NEXT:    vpinsrw $0, (%rdi), %xmm0, %xmm1
625 ; AVX1-NEXT:    vpinsrw $4, 24(%rdi), %xmm0, %xmm0
626 ; AVX1-NEXT:    vpinsrw $6, 28(%rdi), %xmm0, %xmm0
627 ; AVX1-NEXT:    vpinsrw $7, 30(%rdi), %xmm0, %xmm0
628 ; AVX1-NEXT:    vpinsrw $3, 6(%rdi), %xmm1, %xmm1
629 ; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
630 ; AVX1-NEXT:    retq
632 ; AVX2-LABEL: merge_16i16_i16_0uu3zzuuuuuzCuEF_volatile:
633 ; AVX2:       # %bb.0:
634 ; AVX2-NEXT:    vpxor %xmm0, %xmm0, %xmm0
635 ; AVX2-NEXT:    vpinsrw $0, (%rdi), %xmm0, %xmm1
636 ; AVX2-NEXT:    vpinsrw $4, 24(%rdi), %xmm0, %xmm0
637 ; AVX2-NEXT:    vpinsrw $6, 28(%rdi), %xmm0, %xmm0
638 ; AVX2-NEXT:    vpinsrw $7, 30(%rdi), %xmm0, %xmm0
639 ; AVX2-NEXT:    vpinsrw $3, 6(%rdi), %xmm1, %xmm1
640 ; AVX2-NEXT:    vinserti128 $1, %xmm0, %ymm1, %ymm0
641 ; AVX2-NEXT:    retq
643 ; AVX512F-LABEL: merge_16i16_i16_0uu3zzuuuuuzCuEF_volatile:
644 ; AVX512F:       # %bb.0:
645 ; AVX512F-NEXT:    vpxor %xmm0, %xmm0, %xmm0
646 ; AVX512F-NEXT:    vpinsrw $0, (%rdi), %xmm0, %xmm1
647 ; AVX512F-NEXT:    vpinsrw $4, 24(%rdi), %xmm0, %xmm0
648 ; AVX512F-NEXT:    vpinsrw $6, 28(%rdi), %xmm0, %xmm0
649 ; AVX512F-NEXT:    vpinsrw $7, 30(%rdi), %xmm0, %xmm0
650 ; AVX512F-NEXT:    vpinsrw $3, 6(%rdi), %xmm1, %xmm1
651 ; AVX512F-NEXT:    vinserti128 $1, %xmm0, %ymm1, %ymm0
652 ; AVX512F-NEXT:    retq
654 ; X32-AVX-LABEL: merge_16i16_i16_0uu3zzuuuuuzCuEF_volatile:
655 ; X32-AVX:       # %bb.0:
656 ; X32-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
657 ; X32-AVX-NEXT:    vpxor %xmm0, %xmm0, %xmm0
658 ; X32-AVX-NEXT:    vpinsrw $0, (%eax), %xmm0, %xmm1
659 ; X32-AVX-NEXT:    vpinsrw $4, 24(%eax), %xmm0, %xmm0
660 ; X32-AVX-NEXT:    vpinsrw $6, 28(%eax), %xmm0, %xmm0
661 ; X32-AVX-NEXT:    vpinsrw $7, 30(%eax), %xmm0, %xmm0
662 ; X32-AVX-NEXT:    vpinsrw $3, 6(%eax), %xmm1, %xmm1
663 ; X32-AVX-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
664 ; X32-AVX-NEXT:    retl
665   %ptr0 = getelementptr inbounds i16, i16* %ptr, i64 0
666   %ptr3 = getelementptr inbounds i16, i16* %ptr, i64 3
667   %ptrC = getelementptr inbounds i16, i16* %ptr, i64 12
668   %ptrE = getelementptr inbounds i16, i16* %ptr, i64 14
669   %ptrF = getelementptr inbounds i16, i16* %ptr, i64 15
670   %val0 = load volatile i16, i16* %ptr0
671   %val3 = load i16, i16* %ptr3
672   %valC = load i16, i16* %ptrC
673   %valE = load i16, i16* %ptrE
674   %valF = load volatile i16, i16* %ptrF
675   %res0 = insertelement <16 x i16> undef, i16 %val0, i16 0
676   %res3 = insertelement <16 x i16> %res0, i16 %val3, i16 3
677   %res4 = insertelement <16 x i16> %res3, i16     0, i16 4
678   %res5 = insertelement <16 x i16> %res4, i16     0, i16 5
679   %resC = insertelement <16 x i16> %res5, i16 %valC, i16 12
680   %resD = insertelement <16 x i16> %resC, i16     0, i16 13
681   %resE = insertelement <16 x i16> %resD, i16 %valE, i16 14
682   %resF = insertelement <16 x i16> %resE, i16 %valF, i16 15
683   ret <16 x i16> %resF