Merging r261039:
[oota-llvm.git] / test / CodeGen / X86 / avx-vbroadcast.ll
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=i686-apple-darwin -mattr=+avx | FileCheck %s --check-prefix=X32
3 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mattr=+avx | FileCheck %s --check-prefix=X64
4
5 define <4 x i64> @A(i64* %ptr) nounwind uwtable readnone ssp {
6 ; X32-LABEL: A:
7 ; X32:       ## BB#0: ## %entry
8 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
9 ; X32-NEXT:    movl (%eax), %ecx
10 ; X32-NEXT:    movl 4(%eax), %eax
11 ; X32-NEXT:    vmovd %ecx, %xmm0
12 ; X32-NEXT:    vpinsrd $1, %eax, %xmm0, %xmm0
13 ; X32-NEXT:    vpinsrd $2, %ecx, %xmm0, %xmm0
14 ; X32-NEXT:    vpinsrd $3, %eax, %xmm0, %xmm0
15 ; X32-NEXT:    vinsertf128 $1, %xmm0, %ymm0, %ymm0
16 ; X32-NEXT:    retl
17 ;
18 ; X64-LABEL: A:
19 ; X64:       ## BB#0: ## %entry
20 ; X64-NEXT:    vbroadcastsd (%rdi), %ymm0
21 ; X64-NEXT:    retq
22 entry:
23   %q = load i64, i64* %ptr, align 8
24   %vecinit.i = insertelement <4 x i64> undef, i64 %q, i32 0
25   %vecinit2.i = insertelement <4 x i64> %vecinit.i, i64 %q, i32 1
26   %vecinit4.i = insertelement <4 x i64> %vecinit2.i, i64 %q, i32 2
27   %vecinit6.i = insertelement <4 x i64> %vecinit4.i, i64 %q, i32 3
28   ret <4 x i64> %vecinit6.i
29 }
30
31 define <8 x i32> @B(i32* %ptr) nounwind uwtable readnone ssp {
32 ; X32-LABEL: B:
33 ; X32:       ## BB#0: ## %entry
34 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
35 ; X32-NEXT:    vbroadcastss (%eax), %ymm0
36 ; X32-NEXT:    retl
37 ;
38 ; X64-LABEL: B:
39 ; X64:       ## BB#0: ## %entry
40 ; X64-NEXT:    vbroadcastss (%rdi), %ymm0
41 ; X64-NEXT:    retq
42 entry:
43   %q = load i32, i32* %ptr, align 4
44   %vecinit.i = insertelement <8 x i32> undef, i32 %q, i32 0
45   %vecinit2.i = insertelement <8 x i32> %vecinit.i, i32 %q, i32 1
46   %vecinit4.i = insertelement <8 x i32> %vecinit2.i, i32 %q, i32 2
47   %vecinit6.i = insertelement <8 x i32> %vecinit4.i, i32 %q, i32 3
48   ret <8 x i32> %vecinit6.i
49 }
50
51 define <4 x double> @C(double* %ptr) nounwind uwtable readnone ssp {
52 ; X32-LABEL: C:
53 ; X32:       ## BB#0: ## %entry
54 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
55 ; X32-NEXT:    vbroadcastsd (%eax), %ymm0
56 ; X32-NEXT:    retl
57 ;
58 ; X64-LABEL: C:
59 ; X64:       ## BB#0: ## %entry
60 ; X64-NEXT:    vbroadcastsd (%rdi), %ymm0
61 ; X64-NEXT:    retq
62 entry:
63   %q = load double, double* %ptr, align 8
64   %vecinit.i = insertelement <4 x double> undef, double %q, i32 0
65   %vecinit2.i = insertelement <4 x double> %vecinit.i, double %q, i32 1
66   %vecinit4.i = insertelement <4 x double> %vecinit2.i, double %q, i32 2
67   %vecinit6.i = insertelement <4 x double> %vecinit4.i, double %q, i32 3
68   ret <4 x double> %vecinit6.i
69 }
70
71 define <8 x float> @D(float* %ptr) nounwind uwtable readnone ssp {
72 ; X32-LABEL: D:
73 ; X32:       ## BB#0: ## %entry
74 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
75 ; X32-NEXT:    vbroadcastss (%eax), %ymm0
76 ; X32-NEXT:    retl
77 ;
78 ; X64-LABEL: D:
79 ; X64:       ## BB#0: ## %entry
80 ; X64-NEXT:    vbroadcastss (%rdi), %ymm0
81 ; X64-NEXT:    retq
82 entry:
83   %q = load float, float* %ptr, align 4
84   %vecinit.i = insertelement <8 x float> undef, float %q, i32 0
85   %vecinit2.i = insertelement <8 x float> %vecinit.i, float %q, i32 1
86   %vecinit4.i = insertelement <8 x float> %vecinit2.i, float %q, i32 2
87   %vecinit6.i = insertelement <8 x float> %vecinit4.i, float %q, i32 3
88   ret <8 x float> %vecinit6.i
89 }
90
91 ;;;; 128-bit versions
92
93 define <4 x float> @e(float* %ptr) nounwind uwtable readnone ssp {
94 ; X32-LABEL: e:
95 ; X32:       ## BB#0: ## %entry
96 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
97 ; X32-NEXT:    vbroadcastss (%eax), %xmm0
98 ; X32-NEXT:    retl
99 ;
100 ; X64-LABEL: e:
101 ; X64:       ## BB#0: ## %entry
102 ; X64-NEXT:    vbroadcastss (%rdi), %xmm0
103 ; X64-NEXT:    retq
104 entry:
105   %q = load float, float* %ptr, align 4
106   %vecinit.i = insertelement <4 x float> undef, float %q, i32 0
107   %vecinit2.i = insertelement <4 x float> %vecinit.i, float %q, i32 1
108   %vecinit4.i = insertelement <4 x float> %vecinit2.i, float %q, i32 2
109   %vecinit6.i = insertelement <4 x float> %vecinit4.i, float %q, i32 3
110   ret <4 x float> %vecinit6.i
111 }
112
113 ; Don't broadcast constants on pre-AVX2 hardware.
114 define <4 x float> @_e2(float* %ptr) nounwind uwtable readnone ssp {
115 ; X32-LABEL: _e2:
116 ; X32:       ## BB#0: ## %entry
117 ; X32-NEXT:    vmovaps {{.*#+}} xmm0 = [-7.812500e-03,-7.812500e-03,-7.812500e-03,-7.812500e-03]
118 ; X32-NEXT:    retl
119 ;
120 ; X64-LABEL: _e2:
121 ; X64:       ## BB#0: ## %entry
122 ; X64-NEXT:    vmovaps {{.*#+}} xmm0 = [-7.812500e-03,-7.812500e-03,-7.812500e-03,-7.812500e-03]
123 ; X64-NEXT:    retq
124 entry:
125    %vecinit.i = insertelement <4 x float> undef, float       0xbf80000000000000, i32 0
126   %vecinit2.i = insertelement <4 x float> %vecinit.i, float  0xbf80000000000000, i32 1
127   %vecinit4.i = insertelement <4 x float> %vecinit2.i, float 0xbf80000000000000, i32 2
128   %vecinit6.i = insertelement <4 x float> %vecinit4.i, float 0xbf80000000000000, i32 3
129   ret <4 x float> %vecinit6.i
130 }
131
132
133 define <4 x i32> @F(i32* %ptr) nounwind uwtable readnone ssp {
134 ; X32-LABEL: F:
135 ; X32:       ## BB#0: ## %entry
136 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
137 ; X32-NEXT:    vbroadcastss (%eax), %xmm0
138 ; X32-NEXT:    retl
139 ;
140 ; X64-LABEL: F:
141 ; X64:       ## BB#0: ## %entry
142 ; X64-NEXT:    vbroadcastss (%rdi), %xmm0
143 ; X64-NEXT:    retq
144 entry:
145   %q = load i32, i32* %ptr, align 4
146   %vecinit.i = insertelement <4 x i32> undef, i32 %q, i32 0
147   %vecinit2.i = insertelement <4 x i32> %vecinit.i, i32 %q, i32 1
148   %vecinit4.i = insertelement <4 x i32> %vecinit2.i, i32 %q, i32 2
149   %vecinit6.i = insertelement <4 x i32> %vecinit4.i, i32 %q, i32 3
150   ret <4 x i32> %vecinit6.i
151 }
152
153 ; FIXME: Pointer adjusted broadcasts
154
155 define <4 x i32> @load_splat_4i32_4i32_1111(<4 x i32>* %ptr) nounwind uwtable readnone ssp {
156 ; X32-LABEL: load_splat_4i32_4i32_1111:
157 ; X32:       ## BB#0: ## %entry
158 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
159 ; X32-NEXT:    vpshufd {{.*#+}} xmm0 = mem[1,1,1,1]
160 ; X32-NEXT:    retl
161 ;
162 ; X64-LABEL: load_splat_4i32_4i32_1111:
163 ; X64:       ## BB#0: ## %entry
164 ; X64-NEXT:    vpshufd {{.*#+}} xmm0 = mem[1,1,1,1]
165 ; X64-NEXT:    retq
166 entry:
167   %ld = load <4 x i32>, <4 x i32>* %ptr
168   %ret = shufflevector <4 x i32> %ld, <4 x i32> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
169   ret <4 x i32> %ret
170 }
171
172 define <8 x i32> @load_splat_8i32_4i32_33333333(<4 x i32>* %ptr) nounwind uwtable readnone ssp {
173 ; X32-LABEL: load_splat_8i32_4i32_33333333:
174 ; X32:       ## BB#0: ## %entry
175 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
176 ; X32-NEXT:    vpermilps {{.*#+}} xmm0 = mem[3,3,3,3]
177 ; X32-NEXT:    vinsertf128 $1, %xmm0, %ymm0, %ymm0
178 ; X32-NEXT:    retl
179 ;
180 ; X64-LABEL: load_splat_8i32_4i32_33333333:
181 ; X64:       ## BB#0: ## %entry
182 ; X64-NEXT:    vpermilps {{.*#+}} xmm0 = mem[3,3,3,3]
183 ; X64-NEXT:    vinsertf128 $1, %xmm0, %ymm0, %ymm0
184 ; X64-NEXT:    retq
185 entry:
186   %ld = load <4 x i32>, <4 x i32>* %ptr
187   %ret = shufflevector <4 x i32> %ld, <4 x i32> undef, <8 x i32> <i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3>
188   ret <8 x i32> %ret
189 }
190
191 define <8 x i32> @load_splat_8i32_8i32_55555555(<8 x i32>* %ptr) nounwind uwtable readnone ssp {
192 ; X32-LABEL: load_splat_8i32_8i32_55555555:
193 ; X32:       ## BB#0: ## %entry
194 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
195 ; X32-NEXT:    vbroadcastss 20(%eax), %ymm0
196 ; X32-NEXT:    retl
197 ;
198 ; X64-LABEL: load_splat_8i32_8i32_55555555:
199 ; X64:       ## BB#0: ## %entry
200 ; X64-NEXT:    vbroadcastss 20(%rdi), %ymm0
201 ; X64-NEXT:    retq
202 entry:
203   %ld = load <8 x i32>, <8 x i32>* %ptr
204   %ret = shufflevector <8 x i32> %ld, <8 x i32> undef, <8 x i32> <i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5>
205   ret <8 x i32> %ret
206 }
207
208 define <4 x float> @load_splat_4f32_4f32_1111(<4 x float>* %ptr) nounwind uwtable readnone ssp {
209 ; X32-LABEL: load_splat_4f32_4f32_1111:
210 ; X32:       ## BB#0: ## %entry
211 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
212 ; X32-NEXT:    vbroadcastss 4(%eax), %xmm0
213 ; X32-NEXT:    retl
214 ;
215 ; X64-LABEL: load_splat_4f32_4f32_1111:
216 ; X64:       ## BB#0: ## %entry
217 ; X64-NEXT:    vbroadcastss 4(%rdi), %xmm0
218 ; X64-NEXT:    retq
219 entry:
220   %ld = load <4 x float>, <4 x float>* %ptr
221   %ret = shufflevector <4 x float> %ld, <4 x float> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
222   ret <4 x float> %ret
223 }
224
225 define <8 x float> @load_splat_8f32_4f32_33333333(<4 x float>* %ptr) nounwind uwtable readnone ssp {
226 ; X32-LABEL: load_splat_8f32_4f32_33333333:
227 ; X32:       ## BB#0: ## %entry
228 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
229 ; X32-NEXT:    vbroadcastss 12(%eax), %ymm0
230 ; X32-NEXT:    retl
231 ;
232 ; X64-LABEL: load_splat_8f32_4f32_33333333:
233 ; X64:       ## BB#0: ## %entry
234 ; X64-NEXT:    vbroadcastss 12(%rdi), %ymm0
235 ; X64-NEXT:    retq
236 entry:
237   %ld = load <4 x float>, <4 x float>* %ptr
238   %ret = shufflevector <4 x float> %ld, <4 x float> undef, <8 x i32> <i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3>
239   ret <8 x float> %ret
240 }
241
242 define <8 x float> @load_splat_8f32_8f32_55555555(<8 x float>* %ptr) nounwind uwtable readnone ssp {
243 ; X32-LABEL: load_splat_8f32_8f32_55555555:
244 ; X32:       ## BB#0: ## %entry
245 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
246 ; X32-NEXT:    vbroadcastss 20(%eax), %ymm0
247 ; X32-NEXT:    retl
248 ;
249 ; X64-LABEL: load_splat_8f32_8f32_55555555:
250 ; X64:       ## BB#0: ## %entry
251 ; X64-NEXT:    vbroadcastss 20(%rdi), %ymm0
252 ; X64-NEXT:    retq
253 entry:
254   %ld = load <8 x float>, <8 x float>* %ptr
255   %ret = shufflevector <8 x float> %ld, <8 x float> undef, <8 x i32> <i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5>
256   ret <8 x float> %ret
257 }
258
259 define <2 x i64> @load_splat_2i64_2i64_1111(<2 x i64>* %ptr) nounwind uwtable readnone ssp {
260 ; X32-LABEL: load_splat_2i64_2i64_1111:
261 ; X32:       ## BB#0: ## %entry
262 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
263 ; X32-NEXT:    vpshufd {{.*#+}} xmm0 = mem[2,3,2,3]
264 ; X32-NEXT:    retl
265 ;
266 ; X64-LABEL: load_splat_2i64_2i64_1111:
267 ; X64:       ## BB#0: ## %entry
268 ; X64-NEXT:    vpshufd {{.*#+}} xmm0 = mem[2,3,2,3]
269 ; X64-NEXT:    retq
270 entry:
271   %ld = load <2 x i64>, <2 x i64>* %ptr
272   %ret = shufflevector <2 x i64> %ld, <2 x i64> undef, <2 x i32> <i32 1, i32 1>
273   ret <2 x i64> %ret
274 }
275
276 define <4 x i64> @load_splat_4i64_2i64_1111(<2 x i64>* %ptr) nounwind uwtable readnone ssp {
277 ; X32-LABEL: load_splat_4i64_2i64_1111:
278 ; X32:       ## BB#0: ## %entry
279 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
280 ; X32-NEXT:    vmovaps (%eax), %xmm0
281 ; X32-NEXT:    vmovhlps {{.*#+}} xmm0 = xmm0[1,1]
282 ; X32-NEXT:    vinsertf128 $1, %xmm0, %ymm0, %ymm0
283 ; X32-NEXT:    retl
284 ;
285 ; X64-LABEL: load_splat_4i64_2i64_1111:
286 ; X64:       ## BB#0: ## %entry
287 ; X64-NEXT:    vmovaps (%rdi), %xmm0
288 ; X64-NEXT:    vmovhlps {{.*#+}} xmm0 = xmm0[1,1]
289 ; X64-NEXT:    vinsertf128 $1, %xmm0, %ymm0, %ymm0
290 ; X64-NEXT:    retq
291 entry:
292   %ld = load <2 x i64>, <2 x i64>* %ptr
293   %ret = shufflevector <2 x i64> %ld, <2 x i64> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
294   ret <4 x i64> %ret
295 }
296
297 define <4 x i64> @load_splat_4i64_4i64_2222(<4 x i64>* %ptr) nounwind uwtable readnone ssp {
298 ; X32-LABEL: load_splat_4i64_4i64_2222:
299 ; X32:       ## BB#0: ## %entry
300 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
301 ; X32-NEXT:    vbroadcastsd 16(%eax), %ymm0
302 ; X32-NEXT:    retl
303 ;
304 ; X64-LABEL: load_splat_4i64_4i64_2222:
305 ; X64:       ## BB#0: ## %entry
306 ; X64-NEXT:    vbroadcastsd 16(%rdi), %ymm0
307 ; X64-NEXT:    retq
308 entry:
309   %ld = load <4 x i64>, <4 x i64>* %ptr
310   %ret = shufflevector <4 x i64> %ld, <4 x i64> undef, <4 x i32> <i32 2, i32 2, i32 2, i32 2>
311   ret <4 x i64> %ret
312 }
313
314 define <2 x double> @load_splat_2f64_2f64_1111(<2 x double>* %ptr) nounwind uwtable readnone ssp {
315 ; X32-LABEL: load_splat_2f64_2f64_1111:
316 ; X32:       ## BB#0: ## %entry
317 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
318 ; X32-NEXT:    vmovaps (%eax), %xmm0
319 ; X32-NEXT:    vmovhlps {{.*#+}} xmm0 = xmm0[1,1]
320 ; X32-NEXT:    retl
321 ;
322 ; X64-LABEL: load_splat_2f64_2f64_1111:
323 ; X64:       ## BB#0: ## %entry
324 ; X64-NEXT:    vmovaps (%rdi), %xmm0
325 ; X64-NEXT:    vmovhlps {{.*#+}} xmm0 = xmm0[1,1]
326 ; X64-NEXT:    retq
327 entry:
328   %ld = load <2 x double>, <2 x double>* %ptr
329   %ret = shufflevector <2 x double> %ld, <2 x double> undef, <2 x i32> <i32 1, i32 1>
330   ret <2 x double> %ret
331 }
332
333 define <4 x double> @load_splat_4f64_2f64_1111(<2 x double>* %ptr) nounwind uwtable readnone ssp {
334 ; X32-LABEL: load_splat_4f64_2f64_1111:
335 ; X32:       ## BB#0: ## %entry
336 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
337 ; X32-NEXT:    vbroadcastsd 8(%eax), %ymm0
338 ; X32-NEXT:    retl
339 ;
340 ; X64-LABEL: load_splat_4f64_2f64_1111:
341 ; X64:       ## BB#0: ## %entry
342 ; X64-NEXT:    vbroadcastsd 8(%rdi), %ymm0
343 ; X64-NEXT:    retq
344 entry:
345   %ld = load <2 x double>, <2 x double>* %ptr
346   %ret = shufflevector <2 x double> %ld, <2 x double> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
347   ret <4 x double> %ret
348 }
349
350 define <4 x double> @load_splat_4f64_4f64_2222(<4 x double>* %ptr) nounwind uwtable readnone ssp {
351 ; X32-LABEL: load_splat_4f64_4f64_2222:
352 ; X32:       ## BB#0: ## %entry
353 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
354 ; X32-NEXT:    vbroadcastsd 16(%eax), %ymm0
355 ; X32-NEXT:    retl
356 ;
357 ; X64-LABEL: load_splat_4f64_4f64_2222:
358 ; X64:       ## BB#0: ## %entry
359 ; X64-NEXT:    vbroadcastsd 16(%rdi), %ymm0
360 ; X64-NEXT:    retq
361 entry:
362   %ld = load <4 x double>, <4 x double>* %ptr
363   %ret = shufflevector <4 x double> %ld, <4 x double> undef, <4 x i32> <i32 2, i32 2, i32 2, i32 2>
364   ret <4 x double> %ret
365 }
366
367 ; Unsupported vbroadcasts
368
369 define <2 x i64> @G(i64* %ptr) nounwind uwtable readnone ssp {
370 ; X32-LABEL: G:
371 ; X32:       ## BB#0: ## %entry
372 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
373 ; X32-NEXT:    movl (%eax), %ecx
374 ; X32-NEXT:    movl 4(%eax), %eax
375 ; X32-NEXT:    vmovd %ecx, %xmm0
376 ; X32-NEXT:    vpinsrd $1, %eax, %xmm0, %xmm0
377 ; X32-NEXT:    vpinsrd $2, %ecx, %xmm0, %xmm0
378 ; X32-NEXT:    vpinsrd $3, %eax, %xmm0, %xmm0
379 ; X32-NEXT:    retl
380 ;
381 ; X64-LABEL: G:
382 ; X64:       ## BB#0: ## %entry
383 ; X64-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
384 ; X64-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,1,0,1]
385 ; X64-NEXT:    retq
386 entry:
387   %q = load i64, i64* %ptr, align 8
388   %vecinit.i = insertelement <2 x i64> undef, i64 %q, i32 0
389   %vecinit2.i = insertelement <2 x i64> %vecinit.i, i64 %q, i32 1
390   ret <2 x i64> %vecinit2.i
391 }
392
393 define <4 x i32> @H(<4 x i32> %a) {
394 ; X32-LABEL: H:
395 ; X32:       ## BB#0: ## %entry
396 ; X32-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
397 ; X32-NEXT:    retl
398 ;
399 ; X64-LABEL: H:
400 ; X64:       ## BB#0: ## %entry
401 ; X64-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
402 ; X64-NEXT:    retq
403 entry:
404   %x = shufflevector <4 x i32> %a, <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
405   ret <4 x i32> %x
406 }
407
408 define <2 x double> @I(double* %ptr) nounwind uwtable readnone ssp {
409 ; X32-LABEL: I:
410 ; X32:       ## BB#0: ## %entry
411 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
412 ; X32-NEXT:    vmovddup {{.*#+}} xmm0 = mem[0,0]
413 ; X32-NEXT:    retl
414 ;
415 ; X64-LABEL: I:
416 ; X64:       ## BB#0: ## %entry
417 ; X64-NEXT:    vmovddup {{.*#+}} xmm0 = mem[0,0]
418 ; X64-NEXT:    retq
419 entry:
420   %q = load double, double* %ptr, align 4
421   %vecinit.i = insertelement <2 x double> undef, double %q, i32 0
422   %vecinit2.i = insertelement <2 x double> %vecinit.i, double %q, i32 1
423   ret <2 x double> %vecinit2.i
424 }
425
426 define <4 x float> @_RR(float* %ptr, i32* %k) nounwind uwtable readnone ssp {
427 ; X32-LABEL: _RR:
428 ; X32:       ## BB#0: ## %entry
429 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
430 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
431 ; X32-NEXT:    vbroadcastss (%ecx), %xmm0
432 ; X32-NEXT:    movl (%eax), %eax
433 ; X32-NEXT:    movl %eax, (%eax)
434 ; X32-NEXT:    retl
435 ;
436 ; X64-LABEL: _RR:
437 ; X64:       ## BB#0: ## %entry
438 ; X64-NEXT:    vbroadcastss (%rdi), %xmm0
439 ; X64-NEXT:    movl (%rsi), %eax
440 ; X64-NEXT:    movl %eax, (%rax)
441 ; X64-NEXT:    retq
442 entry:
443   %q = load float, float* %ptr, align 4
444   %vecinit.i = insertelement <4 x float> undef, float %q, i32 0
445   %vecinit2.i = insertelement <4 x float> %vecinit.i, float %q, i32 1
446   %vecinit4.i = insertelement <4 x float> %vecinit2.i, float %q, i32 2
447   %vecinit6.i = insertelement <4 x float> %vecinit4.i, float %q, i32 3
448   ; force a chain
449   %j = load i32, i32* %k, align 4
450   store i32 %j, i32* undef
451   ret <4 x float> %vecinit6.i
452 }
453
454 define <4 x float> @_RR2(float* %ptr, i32* %k) nounwind uwtable readnone ssp {
455 ; X32-LABEL: _RR2:
456 ; X32:       ## BB#0: ## %entry
457 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
458 ; X32-NEXT:    vbroadcastss (%eax), %xmm0
459 ; X32-NEXT:    retl
460 ;
461 ; X64-LABEL: _RR2:
462 ; X64:       ## BB#0: ## %entry
463 ; X64-NEXT:    vbroadcastss (%rdi), %xmm0
464 ; X64-NEXT:    retq
465 entry:
466   %q = load float, float* %ptr, align 4
467   %v = insertelement <4 x float> undef, float %q, i32 0
468   %t = shufflevector <4 x float> %v, <4 x float> undef, <4 x i32> zeroinitializer
469   ret <4 x float> %t
470 }
471
472 ; These tests check that a vbroadcast instruction is used when we have a splat
473 ; formed from a concat_vectors (via the shufflevector) of two BUILD_VECTORs
474 ; (via the insertelements).
475
476 define <8 x float> @splat_concat1(float* %p) {
477 ; X32-LABEL: splat_concat1:
478 ; X32:       ## BB#0:
479 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
480 ; X32-NEXT:    vbroadcastss (%eax), %ymm0
481 ; X32-NEXT:    retl
482 ;
483 ; X64-LABEL: splat_concat1:
484 ; X64:       ## BB#0:
485 ; X64-NEXT:    vbroadcastss (%rdi), %ymm0
486 ; X64-NEXT:    retq
487   %1 = load float, float* %p, align 4
488   %2 = insertelement <4 x float> undef, float %1, i32 0
489   %3 = insertelement <4 x float> %2, float %1, i32 1
490   %4 = insertelement <4 x float> %3, float %1, i32 2
491   %5 = insertelement <4 x float> %4, float %1, i32 3
492   %6 = shufflevector <4 x float> %5, <4 x float> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
493   ret <8 x float> %6
494 }
495
496 define <8 x float> @splat_concat2(float* %p) {
497 ; X32-LABEL: splat_concat2:
498 ; X32:       ## BB#0:
499 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
500 ; X32-NEXT:    vbroadcastss (%eax), %ymm0
501 ; X32-NEXT:    retl
502 ;
503 ; X64-LABEL: splat_concat2:
504 ; X64:       ## BB#0:
505 ; X64-NEXT:    vbroadcastss (%rdi), %ymm0
506 ; X64-NEXT:    retq
507   %1 = load float, float* %p, align 4
508   %2 = insertelement <4 x float> undef, float %1, i32 0
509   %3 = insertelement <4 x float> %2, float %1, i32 1
510   %4 = insertelement <4 x float> %3, float %1, i32 2
511   %5 = insertelement <4 x float> %4, float %1, i32 3
512   %6 = insertelement <4 x float> undef, float %1, i32 0
513   %7 = insertelement <4 x float> %6, float %1, i32 1
514   %8 = insertelement <4 x float> %7, float %1, i32 2
515   %9 = insertelement <4 x float> %8, float %1, i32 3
516   %10 = shufflevector <4 x float> %5, <4 x float> %9, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
517   ret <8 x float> %10
518 }
519
520 define <4 x double> @splat_concat3(double* %p) {
521 ; X32-LABEL: splat_concat3:
522 ; X32:       ## BB#0:
523 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
524 ; X32-NEXT:    vbroadcastsd (%eax), %ymm0
525 ; X32-NEXT:    retl
526 ;
527 ; X64-LABEL: splat_concat3:
528 ; X64:       ## BB#0:
529 ; X64-NEXT:    vbroadcastsd (%rdi), %ymm0
530 ; X64-NEXT:    retq
531   %1 = load double, double* %p, align 8
532   %2 = insertelement <2 x double> undef, double %1, i32 0
533   %3 = insertelement <2 x double> %2, double %1, i32 1
534   %4 = shufflevector <2 x double> %3, <2 x double> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
535   ret <4 x double> %4
536 }
537
538 define <4 x double> @splat_concat4(double* %p) {
539 ; X32-LABEL: splat_concat4:
540 ; X32:       ## BB#0:
541 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
542 ; X32-NEXT:    vbroadcastsd (%eax), %ymm0
543 ; X32-NEXT:    retl
544 ;
545 ; X64-LABEL: splat_concat4:
546 ; X64:       ## BB#0:
547 ; X64-NEXT:    vbroadcastsd (%rdi), %ymm0
548 ; X64-NEXT:    retq
549   %1 = load double, double* %p, align 8
550   %2 = insertelement <2 x double> undef, double %1, i32 0
551   %3 = insertelement <2 x double> %2, double %1, i32 1
552   %4 = insertelement <2 x double> undef, double %1, i32 0
553   %5 = insertelement <2 x double> %2, double %1, i32 1
554   %6 = shufflevector <2 x double> %3, <2 x double> %5, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
555   ret <4 x double> %6
556 }