[RISCV] Add shrinkwrap test cases showing gaps in current impl
[llvm-project.git] / llvm / test / CodeGen / X86 / merge-consecutive-loads-256.ll
blob33e8d62c00a4c1a19b766e3a9592c759c1e250be
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -disable-peephole -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX1
3 ; RUN: llc < %s -disable-peephole -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=AVX --check-prefix=AVX2
4 ; RUN: llc < %s -disable-peephole -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=X86-AVX
9 define <4 x double> @merge_4f64_2f64_23(ptr %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 ; X86-AVX-LABEL: merge_4f64_2f64_23:
16 ; X86-AVX:       # %bb.0:
17 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
18 ; X86-AVX-NEXT:    vmovups 32(%eax), %ymm0
19 ; X86-AVX-NEXT:    retl
20   %ptr0 = getelementptr inbounds <2 x double>, ptr %ptr, i64 2
21   %ptr1 = getelementptr inbounds <2 x double>, ptr %ptr, i64 3
22   %val0 = load <2 x double>, ptr %ptr0
23   %val1 = load <2 x double>, ptr %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(ptr %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 ; X86-AVX-LABEL: merge_4f64_2f64_2z:
35 ; X86-AVX:       # %bb.0:
36 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
37 ; X86-AVX-NEXT:    vmovaps 32(%eax), %xmm0
38 ; X86-AVX-NEXT:    retl
39   %ptr0 = getelementptr inbounds <2 x double>, ptr %ptr, i64 2
40   %val0 = load <2 x double>, ptr %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(ptr %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 ; X86-AVX-LABEL: merge_4f64_f64_2345:
52 ; X86-AVX:       # %bb.0:
53 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
54 ; X86-AVX-NEXT:    vmovups 16(%eax), %ymm0
55 ; X86-AVX-NEXT:    retl
56   %ptr0 = getelementptr inbounds double, ptr %ptr, i64 2
57   %ptr1 = getelementptr inbounds double, ptr %ptr, i64 3
58   %ptr2 = getelementptr inbounds double, ptr %ptr, i64 4
59   %ptr3 = getelementptr inbounds double, ptr %ptr, i64 5
60   %val0 = load double, ptr %ptr0
61   %val1 = load double, ptr %ptr1
62   %val2 = load double, ptr %ptr2
63   %val3 = load double, ptr %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(ptr %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 ; X86-AVX-LABEL: merge_4f64_f64_3zuu:
78 ; X86-AVX:       # %bb.0:
79 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
80 ; X86-AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
81 ; X86-AVX-NEXT:    retl
82   %ptr0 = getelementptr inbounds double, ptr %ptr, i64 3
83   %val0 = load double, ptr %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(ptr %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 ; X86-AVX-LABEL: merge_4f64_f64_34uu:
96 ; X86-AVX:       # %bb.0:
97 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
98 ; X86-AVX-NEXT:    vmovups 24(%eax), %xmm0
99 ; X86-AVX-NEXT:    retl
100   %ptr0 = getelementptr inbounds double, ptr %ptr, i64 3
101   %ptr1 = getelementptr inbounds double, ptr %ptr, i64 4
102   %val0 = load double, ptr %ptr0
103   %val1 = load double, ptr %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(ptr %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 ; X86-AVX-LABEL: merge_4f64_f64_45zz:
116 ; X86-AVX:       # %bb.0:
117 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
118 ; X86-AVX-NEXT:    vmovups 32(%eax), %xmm0
119 ; X86-AVX-NEXT:    retl
120   %ptr0 = getelementptr inbounds double, ptr %ptr, i64 4
121   %ptr1 = getelementptr inbounds double, ptr %ptr, i64 5
122   %val0 = load double, ptr %ptr0
123   %val1 = load double, ptr %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(ptr %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 ; X86-AVX-LABEL: merge_4f64_f64_34z6:
137 ; X86-AVX:       # %bb.0:
138 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
139 ; X86-AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
140 ; X86-AVX-NEXT:    vblendps {{.*#+}} ymm0 = mem[0,1,2,3],ymm0[4,5],mem[6,7]
141 ; X86-AVX-NEXT:    retl
142   %ptr0 = getelementptr inbounds double, ptr %ptr, i64 3
143   %ptr1 = getelementptr inbounds double, ptr %ptr, i64 4
144   %ptr3 = getelementptr inbounds double, ptr %ptr, i64 6
145   %val0 = load double, ptr %ptr0
146   %val1 = load double, ptr %ptr1
147   %val3 = load double, ptr %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(ptr %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 ; X86-AVX-LABEL: merge_4i64_2i64_3z:
162 ; X86-AVX:       # %bb.0:
163 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
164 ; X86-AVX-NEXT:    vmovaps 48(%eax), %xmm0
165 ; X86-AVX-NEXT:    retl
166   %ptr0 = getelementptr inbounds <2 x i64>, ptr %ptr, i64 3
167   %val0 = load <2 x i64>, ptr %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(ptr %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 ; X86-AVX-LABEL: merge_4i64_i64_1234:
179 ; X86-AVX:       # %bb.0:
180 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
181 ; X86-AVX-NEXT:    vmovups 8(%eax), %ymm0
182 ; X86-AVX-NEXT:    retl
183   %ptr0 = getelementptr inbounds i64, ptr %ptr, i64 1
184   %ptr1 = getelementptr inbounds i64, ptr %ptr, i64 2
185   %ptr2 = getelementptr inbounds i64, ptr %ptr, i64 3
186   %ptr3 = getelementptr inbounds i64, ptr %ptr, i64 4
187   %val0 = load i64, ptr %ptr0
188   %val1 = load i64, ptr %ptr1
189   %val2 = load i64, ptr %ptr2
190   %val3 = load i64, ptr %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(ptr %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 ; X86-AVX-LABEL: merge_4i64_i64_1zzu:
205 ; X86-AVX:       # %bb.0:
206 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
207 ; X86-AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
208 ; X86-AVX-NEXT:    retl
209   %ptr0 = getelementptr inbounds i64, ptr %ptr, i64 1
210   %val0 = load i64, ptr %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(ptr %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 ; X86-AVX-LABEL: merge_4i64_i64_23zz:
224 ; X86-AVX:       # %bb.0:
225 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
226 ; X86-AVX-NEXT:    vmovups 16(%eax), %xmm0
227 ; X86-AVX-NEXT:    retl
228   %ptr0 = getelementptr inbounds i64, ptr %ptr, i64 2
229   %ptr1 = getelementptr inbounds i64, ptr %ptr, i64 3
230   %val0 = load i64, ptr %ptr0
231   %val1 = load i64, ptr %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(ptr %ptr) nounwind uwtable noinline ssp {
238 ; AVX-LABEL: merge_8f32_2f32_23z5:
239 ; AVX:       # %bb.0:
240 ; AVX-NEXT:    vmovups 16(%rdi), %xmm0
241 ; AVX-NEXT:    vxorps %xmm1, %xmm1, %xmm1
242 ; AVX-NEXT:    vmovhps {{.*#+}} xmm1 = xmm1[0,1],mem[0,1]
243 ; AVX-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
244 ; AVX-NEXT:    retq
246 ; X86-AVX-LABEL: merge_8f32_2f32_23z5:
247 ; X86-AVX:       # %bb.0:
248 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
249 ; X86-AVX-NEXT:    vmovups 16(%eax), %xmm0
250 ; X86-AVX-NEXT:    vxorps %xmm1, %xmm1, %xmm1
251 ; X86-AVX-NEXT:    vmovhps {{.*#+}} xmm1 = xmm1[0,1],mem[0,1]
252 ; X86-AVX-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
253 ; X86-AVX-NEXT:    retl
254   %ptr0 = getelementptr inbounds <2 x float>, ptr %ptr, i64 2
255   %ptr1 = getelementptr inbounds <2 x float>, ptr %ptr, i64 3
256   %ptr3 = getelementptr inbounds <2 x float>, ptr %ptr, i64 5
257   %val0 = load <2 x float>, ptr %ptr0
258   %val1 = load <2 x float>, ptr %ptr1
259   %val3 = load <2 x float>, ptr %ptr3
260   %res01 = shufflevector <2 x float> %val0, <2 x float> %val1, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
261   %res23 = shufflevector <2 x float> zeroinitializer, <2 x float> %val3, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
262   %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>
263   ret <8 x float> %res
266 define <8 x float> @merge_8f32_4f32_z2(ptr %ptr) nounwind uwtable noinline ssp {
267 ; AVX-LABEL: merge_8f32_4f32_z2:
268 ; AVX:       # %bb.0:
269 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
270 ; AVX-NEXT:    vinsertf128 $1, 32(%rdi), %ymm0, %ymm0
271 ; AVX-NEXT:    retq
273 ; X86-AVX-LABEL: merge_8f32_4f32_z2:
274 ; X86-AVX:       # %bb.0:
275 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
276 ; X86-AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
277 ; X86-AVX-NEXT:    vinsertf128 $1, 32(%eax), %ymm0, %ymm0
278 ; X86-AVX-NEXT:    retl
279   %ptr1 = getelementptr inbounds <4 x float>, ptr %ptr, i64 2
280   %val1 = load <4 x float>, ptr %ptr1
281   %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>
282   ret <8 x float> %res
285 define <8 x float> @merge_8f32_f32_12zzuuzz(ptr %ptr) nounwind uwtable noinline ssp {
286 ; AVX-LABEL: merge_8f32_f32_12zzuuzz:
287 ; AVX:       # %bb.0:
288 ; AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
289 ; AVX-NEXT:    retq
291 ; X86-AVX-LABEL: merge_8f32_f32_12zzuuzz:
292 ; X86-AVX:       # %bb.0:
293 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
294 ; X86-AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
295 ; X86-AVX-NEXT:    retl
296   %ptr0 = getelementptr inbounds float, ptr %ptr, i64 1
297   %ptr1 = getelementptr inbounds float, ptr %ptr, i64 2
298   %val0 = load float, ptr %ptr0
299   %val1 = load float, ptr %ptr1
300   %res0 = insertelement <8 x float> undef, float %val0, i32 0
301   %res1 = insertelement <8 x float> %res0, float %val1, i32 1
302   %res2 = insertelement <8 x float> %res1, float   0.0, i32 2
303   %res3 = insertelement <8 x float> %res2, float   0.0, i32 3
304   %res6 = insertelement <8 x float> %res3, float   0.0, i32 6
305   %res7 = insertelement <8 x float> %res6, float   0.0, i32 7
306   ret <8 x float> %res7
309 define <8 x float> @merge_8f32_f32_1u3u5zu8(ptr %ptr) nounwind uwtable noinline ssp {
310 ; AVX-LABEL: merge_8f32_f32_1u3u5zu8:
311 ; AVX:       # %bb.0:
312 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
313 ; AVX-NEXT:    vblendps {{.*#+}} ymm0 = mem[0,1,2,3,4],ymm0[5],mem[6,7]
314 ; AVX-NEXT:    retq
316 ; X86-AVX-LABEL: merge_8f32_f32_1u3u5zu8:
317 ; X86-AVX:       # %bb.0:
318 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
319 ; X86-AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
320 ; X86-AVX-NEXT:    vblendps {{.*#+}} ymm0 = mem[0,1,2,3,4],ymm0[5],mem[6,7]
321 ; X86-AVX-NEXT:    retl
322   %ptr0 = getelementptr inbounds float, ptr %ptr, i64 1
323   %ptr2 = getelementptr inbounds float, ptr %ptr, i64 3
324   %ptr4 = getelementptr inbounds float, ptr %ptr, i64 5
325   %ptr7 = getelementptr inbounds float, ptr %ptr, i64 8
326   %val0 = load float, ptr %ptr0
327   %val2 = load float, ptr %ptr2
328   %val4 = load float, ptr %ptr4
329   %val7 = load float, ptr %ptr7
330   %res0 = insertelement <8 x float> undef, float %val0, i32 0
331   %res2 = insertelement <8 x float> %res0, float %val2, i32 2
332   %res4 = insertelement <8 x float> %res2, float %val4, i32 4
333   %res5 = insertelement <8 x float> %res4, float   0.0, i32 5
334   %res7 = insertelement <8 x float> %res5, float %val7, i32 7
335   ret <8 x float> %res7
338 define <8 x i32> @merge_8i32_4i32_z3(ptr %ptr) nounwind uwtable noinline ssp {
339 ; AVX-LABEL: merge_8i32_4i32_z3:
340 ; AVX:       # %bb.0:
341 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
342 ; AVX-NEXT:    vinsertf128 $1, 48(%rdi), %ymm0, %ymm0
343 ; AVX-NEXT:    retq
345 ; X86-AVX-LABEL: merge_8i32_4i32_z3:
346 ; X86-AVX:       # %bb.0:
347 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
348 ; X86-AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
349 ; X86-AVX-NEXT:    vinsertf128 $1, 48(%eax), %ymm0, %ymm0
350 ; X86-AVX-NEXT:    retl
351   %ptr1 = getelementptr inbounds <4 x i32>, ptr %ptr, i64 3
352   %val1 = load <4 x i32>, ptr %ptr1
353   %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>
354   ret <8 x i32> %res
357 define <8 x i32> @merge_8i32_i32_56zz9uzz(ptr %ptr) nounwind uwtable noinline ssp {
358 ; AVX-LABEL: merge_8i32_i32_56zz9uzz:
359 ; AVX:       # %bb.0:
360 ; AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
361 ; AVX-NEXT:    vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero
362 ; AVX-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
363 ; AVX-NEXT:    retq
365 ; X86-AVX-LABEL: merge_8i32_i32_56zz9uzz:
366 ; X86-AVX:       # %bb.0:
367 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
368 ; X86-AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
369 ; X86-AVX-NEXT:    vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero
370 ; X86-AVX-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
371 ; X86-AVX-NEXT:    retl
372   %ptr0 = getelementptr inbounds i32, ptr %ptr, i64 5
373   %ptr1 = getelementptr inbounds i32, ptr %ptr, i64 6
374   %ptr4 = getelementptr inbounds i32, ptr %ptr, i64 9
375   %val0 = load i32, ptr %ptr0
376   %val1 = load i32, ptr %ptr1
377   %val4 = load i32, ptr %ptr4
378   %res0 = insertelement <8 x i32> undef, i32 %val0, i32 0
379   %res1 = insertelement <8 x i32> %res0, i32 %val1, i32 1
380   %res2 = insertelement <8 x i32> %res1, i32     0, i32 2
381   %res3 = insertelement <8 x i32> %res2, i32     0, i32 3
382   %res4 = insertelement <8 x i32> %res3, i32 %val4, i32 4
383   %res6 = insertelement <8 x i32> %res4, i32     0, i32 6
384   %res7 = insertelement <8 x i32> %res6, i32     0, i32 7
385   ret <8 x i32> %res7
388 define <8 x i32> @merge_8i32_i32_1u3u5zu8(ptr %ptr) nounwind uwtable noinline ssp {
389 ; AVX-LABEL: merge_8i32_i32_1u3u5zu8:
390 ; AVX:       # %bb.0:
391 ; AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
392 ; AVX-NEXT:    vblendps {{.*#+}} ymm0 = mem[0,1,2,3,4],ymm0[5],mem[6,7]
393 ; AVX-NEXT:    retq
395 ; X86-AVX-LABEL: merge_8i32_i32_1u3u5zu8:
396 ; X86-AVX:       # %bb.0:
397 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
398 ; X86-AVX-NEXT:    vxorps %xmm0, %xmm0, %xmm0
399 ; X86-AVX-NEXT:    vblendps {{.*#+}} ymm0 = mem[0,1,2,3,4],ymm0[5],mem[6,7]
400 ; X86-AVX-NEXT:    retl
401   %ptr0 = getelementptr inbounds i32, ptr %ptr, i64 1
402   %ptr2 = getelementptr inbounds i32, ptr %ptr, i64 3
403   %ptr4 = getelementptr inbounds i32, ptr %ptr, i64 5
404   %ptr7 = getelementptr inbounds i32, ptr %ptr, i64 8
405   %val0 = load i32, ptr %ptr0
406   %val2 = load i32, ptr %ptr2
407   %val4 = load i32, ptr %ptr4
408   %val7 = load i32, ptr %ptr7
409   %res0 = insertelement <8 x i32> undef, i32 %val0, i32 0
410   %res2 = insertelement <8 x i32> %res0, i32 %val2, i32 2
411   %res4 = insertelement <8 x i32> %res2, i32 %val4, i32 4
412   %res5 = insertelement <8 x i32> %res4, i32     0, i32 5
413   %res7 = insertelement <8 x i32> %res5, i32 %val7, i32 7
414   ret <8 x i32> %res7
417 define <16 x i16> @merge_16i16_i16_89zzzuuuuuuuuuuuz(ptr %ptr) nounwind uwtable noinline ssp {
418 ; AVX-LABEL: merge_16i16_i16_89zzzuuuuuuuuuuuz:
419 ; AVX:       # %bb.0:
420 ; AVX-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
421 ; AVX-NEXT:    retq
423 ; X86-AVX-LABEL: merge_16i16_i16_89zzzuuuuuuuuuuuz:
424 ; X86-AVX:       # %bb.0:
425 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
426 ; X86-AVX-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
427 ; X86-AVX-NEXT:    retl
428   %ptr0 = getelementptr inbounds i16, ptr %ptr, i64 8
429   %ptr1 = getelementptr inbounds i16, ptr %ptr, i64 9
430   %val0 = load i16, ptr %ptr0
431   %val1 = load i16, ptr %ptr1
432   %res0 = insertelement <16 x i16> undef, i16 %val0, i16 0
433   %res1 = insertelement <16 x i16> %res0, i16 %val1, i16 1
434   %res2 = insertelement <16 x i16> %res1, i16     0, i16 2
435   %res3 = insertelement <16 x i16> %res2, i16     0, i16 3
436   %res4 = insertelement <16 x i16> %res3, i16     0, i16 4
437   %resF = insertelement <16 x i16> %res4, i16     0, i16 15
438   ret <16 x i16> %resF
441 define <16 x i16> @merge_16i16_i16_45u7uuuuuuuuuuuu(ptr %ptr) nounwind uwtable noinline ssp {
442 ; AVX-LABEL: merge_16i16_i16_45u7uuuuuuuuuuuu:
443 ; AVX:       # %bb.0:
444 ; AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
445 ; AVX-NEXT:    retq
447 ; X86-AVX-LABEL: merge_16i16_i16_45u7uuuuuuuuuuuu:
448 ; X86-AVX:       # %bb.0:
449 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
450 ; X86-AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
451 ; X86-AVX-NEXT:    retl
452   %ptr0 = getelementptr inbounds i16, ptr %ptr, i64 4
453   %ptr1 = getelementptr inbounds i16, ptr %ptr, i64 5
454   %ptr3 = getelementptr inbounds i16, ptr %ptr, i64 7
455   %val0 = load i16, ptr %ptr0
456   %val1 = load i16, ptr %ptr1
457   %val3 = load i16, ptr %ptr3
458   %res0 = insertelement <16 x i16> undef, i16 %val0, i16 0
459   %res1 = insertelement <16 x i16> %res0, i16 %val1, i16 1
460   %res3 = insertelement <16 x i16> %res1, i16 %val3, i16 3
461   ret <16 x i16> %res3
464 define <16 x i16> @merge_16i16_i16_0uu3uuuuuuuuCuEF(ptr %ptr) nounwind uwtable noinline ssp {
465 ; AVX-LABEL: merge_16i16_i16_0uu3uuuuuuuuCuEF:
466 ; AVX:       # %bb.0:
467 ; AVX-NEXT:    vmovups (%rdi), %ymm0
468 ; AVX-NEXT:    retq
470 ; X86-AVX-LABEL: merge_16i16_i16_0uu3uuuuuuuuCuEF:
471 ; X86-AVX:       # %bb.0:
472 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
473 ; X86-AVX-NEXT:    vmovups (%eax), %ymm0
474 ; X86-AVX-NEXT:    retl
475   %ptr3 = getelementptr inbounds i16, ptr %ptr, i64 3
476   %ptrC = getelementptr inbounds i16, ptr %ptr, i64 12
477   %ptrE = getelementptr inbounds i16, ptr %ptr, i64 14
478   %ptrF = getelementptr inbounds i16, ptr %ptr, i64 15
479   %val0 = load i16, ptr %ptr
480   %val3 = load i16, ptr %ptr3
481   %valC = load i16, ptr %ptrC
482   %valE = load i16, ptr %ptrE
483   %valF = load i16, ptr %ptrF
484   %res0 = insertelement <16 x i16> undef, i16 %val0, i16 0
485   %res3 = insertelement <16 x i16> %res0, i16 %val3, i16 3
486   %resC = insertelement <16 x i16> %res3, i16 %valC, i16 12
487   %resE = insertelement <16 x i16> %resC, i16 %valE, i16 14
488   %resF = insertelement <16 x i16> %resE, i16 %valF, i16 15
489   ret <16 x i16> %resF
492 define <16 x i16> @merge_16i16_i16_0uu3zzuuuuuzCuEF(ptr %ptr) nounwind uwtable noinline ssp {
493 ; AVX-LABEL: merge_16i16_i16_0uu3zzuuuuuzCuEF:
494 ; AVX:       # %bb.0:
495 ; AVX-NEXT:    vmovups (%rdi), %ymm0
496 ; AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
497 ; AVX-NEXT:    retq
499 ; X86-AVX-LABEL: merge_16i16_i16_0uu3zzuuuuuzCuEF:
500 ; X86-AVX:       # %bb.0:
501 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
502 ; X86-AVX-NEXT:    vmovups (%eax), %ymm0
503 ; X86-AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}, %ymm0, %ymm0
504 ; X86-AVX-NEXT:    retl
505   %ptr3 = getelementptr inbounds i16, ptr %ptr, i64 3
506   %ptrC = getelementptr inbounds i16, ptr %ptr, i64 12
507   %ptrE = getelementptr inbounds i16, ptr %ptr, i64 14
508   %ptrF = getelementptr inbounds i16, ptr %ptr, i64 15
509   %val0 = load i16, ptr %ptr
510   %val3 = load i16, ptr %ptr3
511   %valC = load i16, ptr %ptrC
512   %valE = load i16, ptr %ptrE
513   %valF = load i16, ptr %ptrF
514   %res0 = insertelement <16 x i16> undef, i16 %val0, i16 0
515   %res3 = insertelement <16 x i16> %res0, i16 %val3, i16 3
516   %res4 = insertelement <16 x i16> %res3, i16     0, i16 4
517   %res5 = insertelement <16 x i16> %res4, i16     0, i16 5
518   %resC = insertelement <16 x i16> %res5, i16 %valC, i16 12
519   %resD = insertelement <16 x i16> %resC, i16     0, i16 13
520   %resE = insertelement <16 x i16> %resD, i16 %valE, i16 14
521   %resF = insertelement <16 x i16> %resE, i16 %valF, i16 15
522   ret <16 x i16> %resF
525 define <32 x i8> @merge_32i8_i8_45u7uuuuuuuuuuuuuuuuuuuuuuuuuuuu(ptr %ptr) nounwind uwtable noinline ssp {
526 ; AVX-LABEL: merge_32i8_i8_45u7uuuuuuuuuuuuuuuuuuuuuuuuuuuu:
527 ; AVX:       # %bb.0:
528 ; AVX-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
529 ; AVX-NEXT:    retq
531 ; X86-AVX-LABEL: merge_32i8_i8_45u7uuuuuuuuuuuuuuuuuuuuuuuuuuuu:
532 ; X86-AVX:       # %bb.0:
533 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
534 ; X86-AVX-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
535 ; X86-AVX-NEXT:    retl
536   %ptr0 = getelementptr inbounds i8, ptr %ptr, i64 4
537   %ptr1 = getelementptr inbounds i8, ptr %ptr, i64 5
538   %ptr3 = getelementptr inbounds i8, ptr %ptr, i64 7
539   %val0 = load i8, ptr %ptr0
540   %val1 = load i8, ptr %ptr1
541   %val3 = load i8, ptr %ptr3
542   %res0 = insertelement <32 x i8> undef, i8 %val0, i8 0
543   %res1 = insertelement <32 x i8> %res0, i8 %val1, i8 1
544   %res3 = insertelement <32 x i8> %res1, i8 %val3, i8 3
545   ret <32 x i8> %res3
548 define <32 x i8> @merge_32i8_i8_23u5uuuuuuuuuuzzzzuuuuuuuuuuuuuu(ptr %ptr) nounwind uwtable noinline ssp {
549 ; AVX-LABEL: merge_32i8_i8_23u5uuuuuuuuuuzzzzuuuuuuuuuuuuuu:
550 ; AVX:       # %bb.0:
551 ; AVX-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
552 ; AVX-NEXT:    retq
554 ; X86-AVX-LABEL: merge_32i8_i8_23u5uuuuuuuuuuzzzzuuuuuuuuuuuuuu:
555 ; X86-AVX:       # %bb.0:
556 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
557 ; X86-AVX-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
558 ; X86-AVX-NEXT:    retl
559   %ptr0 = getelementptr inbounds i8, ptr %ptr, i64 2
560   %ptr1 = getelementptr inbounds i8, ptr %ptr, i64 3
561   %ptr3 = getelementptr inbounds i8, ptr %ptr, i64 5
562   %val0 = load i8, ptr %ptr0
563   %val1 = load i8, ptr %ptr1
564   %val3 = load i8, ptr %ptr3
565   %res0 = insertelement <32 x i8> undef, i8 %val0, i8 0
566   %res1 = insertelement <32 x i8> %res0, i8 %val1, i8 1
567   %res3 = insertelement <32 x i8> %res1, i8 %val3, i8 3
568   %resE = insertelement <32 x i8> %res3, i8     0, i8 14
569   %resF = insertelement <32 x i8> %resE, i8     0, i8 15
570   %resG = insertelement <32 x i8> %resF, i8     0, i8 16
571   %resH = insertelement <32 x i8> %resG, i8     0, i8 17
572   ret <32 x i8> %resH
576 ; consecutive loads including any/all volatiles may not be combined
579 define <4 x double> @merge_4f64_f64_34uz_volatile(ptr %ptr) nounwind uwtable noinline ssp {
580 ; AVX-LABEL: merge_4f64_f64_34uz_volatile:
581 ; AVX:       # %bb.0:
582 ; AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
583 ; AVX-NEXT:    vmovhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]
584 ; AVX-NEXT:    retq
586 ; X86-AVX-LABEL: merge_4f64_f64_34uz_volatile:
587 ; X86-AVX:       # %bb.0:
588 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
589 ; X86-AVX-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
590 ; X86-AVX-NEXT:    vmovhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]
591 ; X86-AVX-NEXT:    retl
592   %ptr0 = getelementptr inbounds double, ptr %ptr, i64 3
593   %ptr1 = getelementptr inbounds double, ptr %ptr, i64 4
594   %val0 = load volatile double, ptr %ptr0
595   %val1 = load volatile double, ptr %ptr1
596   %res0 = insertelement <4 x double> undef, double %val0, i32 0
597   %res1 = insertelement <4 x double> %res0, double %val1, i32 1
598   %res3 = insertelement <4 x double> %res1, double   0.0, i32 3
599   ret <4 x double> %res3
602 define <16 x i16> @merge_16i16_i16_0uu3zzuuuuuzCuEF_volatile(ptr %ptr) nounwind uwtable noinline ssp {
603 ; AVX1-LABEL: merge_16i16_i16_0uu3zzuuuuuzCuEF_volatile:
604 ; AVX1:       # %bb.0:
605 ; AVX1-NEXT:    movzwl (%rdi), %eax
606 ; AVX1-NEXT:    vpxor %xmm0, %xmm0, %xmm0
607 ; AVX1-NEXT:    vpinsrw $4, 24(%rdi), %xmm0, %xmm0
608 ; AVX1-NEXT:    vpinsrw $6, 28(%rdi), %xmm0, %xmm0
609 ; AVX1-NEXT:    vpinsrw $7, 30(%rdi), %xmm0, %xmm0
610 ; AVX1-NEXT:    vmovd %eax, %xmm1
611 ; AVX1-NEXT:    vpinsrw $3, 6(%rdi), %xmm1, %xmm1
612 ; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
613 ; AVX1-NEXT:    retq
615 ; AVX2-LABEL: merge_16i16_i16_0uu3zzuuuuuzCuEF_volatile:
616 ; AVX2:       # %bb.0:
617 ; AVX2-NEXT:    movzwl (%rdi), %eax
618 ; AVX2-NEXT:    vpxor %xmm0, %xmm0, %xmm0
619 ; AVX2-NEXT:    vpinsrw $4, 24(%rdi), %xmm0, %xmm0
620 ; AVX2-NEXT:    vpinsrw $6, 28(%rdi), %xmm0, %xmm0
621 ; AVX2-NEXT:    vpinsrw $7, 30(%rdi), %xmm0, %xmm0
622 ; AVX2-NEXT:    vmovd %eax, %xmm1
623 ; AVX2-NEXT:    vpinsrw $3, 6(%rdi), %xmm1, %xmm1
624 ; AVX2-NEXT:    vinserti128 $1, %xmm0, %ymm1, %ymm0
625 ; AVX2-NEXT:    retq
627 ; AVX512F-LABEL: merge_16i16_i16_0uu3zzuuuuuzCuEF_volatile:
628 ; AVX512F:       # %bb.0:
629 ; AVX512F-NEXT:    movzwl (%rdi), %eax
630 ; AVX512F-NEXT:    vpxor %xmm0, %xmm0, %xmm0
631 ; AVX512F-NEXT:    vpinsrw $4, 24(%rdi), %xmm0, %xmm0
632 ; AVX512F-NEXT:    vpinsrw $6, 28(%rdi), %xmm0, %xmm0
633 ; AVX512F-NEXT:    vpinsrw $7, 30(%rdi), %xmm0, %xmm0
634 ; AVX512F-NEXT:    vmovd %eax, %xmm1
635 ; AVX512F-NEXT:    vpinsrw $3, 6(%rdi), %xmm1, %xmm1
636 ; AVX512F-NEXT:    vinserti128 $1, %xmm0, %ymm1, %ymm0
637 ; AVX512F-NEXT:    retq
639 ; X86-AVX-LABEL: merge_16i16_i16_0uu3zzuuuuuzCuEF_volatile:
640 ; X86-AVX:       # %bb.0:
641 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
642 ; X86-AVX-NEXT:    movzwl (%eax), %ecx
643 ; X86-AVX-NEXT:    vpxor %xmm0, %xmm0, %xmm0
644 ; X86-AVX-NEXT:    vpinsrw $4, 24(%eax), %xmm0, %xmm0
645 ; X86-AVX-NEXT:    vpinsrw $6, 28(%eax), %xmm0, %xmm0
646 ; X86-AVX-NEXT:    vpinsrw $7, 30(%eax), %xmm0, %xmm0
647 ; X86-AVX-NEXT:    vmovd %ecx, %xmm1
648 ; X86-AVX-NEXT:    vpinsrw $3, 6(%eax), %xmm1, %xmm1
649 ; X86-AVX-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
650 ; X86-AVX-NEXT:    retl
651   %ptr3 = getelementptr inbounds i16, ptr %ptr, i64 3
652   %ptrC = getelementptr inbounds i16, ptr %ptr, i64 12
653   %ptrE = getelementptr inbounds i16, ptr %ptr, i64 14
654   %ptrF = getelementptr inbounds i16, ptr %ptr, i64 15
655   %val0 = load volatile i16, ptr %ptr
656   %val3 = load i16, ptr %ptr3
657   %valC = load i16, ptr %ptrC
658   %valE = load i16, ptr %ptrE
659   %valF = load volatile i16, ptr %ptrF
660   %res0 = insertelement <16 x i16> undef, i16 %val0, i16 0
661   %res3 = insertelement <16 x i16> %res0, i16 %val3, i16 3
662   %res4 = insertelement <16 x i16> %res3, i16     0, i16 4
663   %res5 = insertelement <16 x i16> %res4, i16     0, i16 5
664   %resC = insertelement <16 x i16> %res5, i16 %valC, i16 12
665   %resD = insertelement <16 x i16> %resC, i16     0, i16 13
666   %resE = insertelement <16 x i16> %resD, i16 %valE, i16 14
667   %resF = insertelement <16 x i16> %resE, i16 %valF, i16 15
668   ret <16 x i16> %resF
672 ; Volatile tests.
675 @l = external dso_local global <32 x i8>, align 32
677 define <2 x i8> @PR42846(ptr %j, <2 x i8> %k) {
678 ; AVX-LABEL: PR42846:
679 ; AVX:       # %bb.0:
680 ; AVX-NEXT:    vmovdqa l(%rip), %ymm0
681 ; AVX-NEXT:    vpextrw $0, %xmm0, (%rdi)
682 ; AVX-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
683 ; AVX-NEXT:    vzeroupper
684 ; AVX-NEXT:    retq
686 ; X86-AVX-LABEL: PR42846:
687 ; X86-AVX:       # %bb.0:
688 ; X86-AVX-NEXT:    movl {{[0-9]+}}(%esp), %eax
689 ; X86-AVX-NEXT:    vmovdqa l, %ymm0
690 ; X86-AVX-NEXT:    vpextrw $0, %xmm0, (%eax)
691 ; X86-AVX-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
692 ; X86-AVX-NEXT:    vzeroupper
693 ; X86-AVX-NEXT:    retl
694   %t0 = load volatile <32 x i8>, ptr @l, align 32
695   %shuffle = shufflevector <32 x i8> %t0, <32 x i8> undef, <2 x i32> <i32 0, i32 1>
696   store <2 x i8> %shuffle, ptr %j, align 2
697   ret <2 x i8> %shuffle