CodeGen peephole: fold redundant phys reg copies
[oota-llvm.git] / test / CodeGen / X86 / avx2-vbroadcast.ll
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mattr=+avx2 | FileCheck %s
3
4 define <16 x i8> @BB16(i8* %ptr) nounwind uwtable readnone ssp {
5 ; CHECK-LABEL: BB16:
6 ; CHECK:       ## BB#0: ## %entry
7 ; CHECK-NEXT:    vpbroadcastb (%rdi), %xmm0
8 ; CHECK-NEXT:    retq
9 entry:
10   %q = load i8, i8* %ptr, align 4
11   %q0 = insertelement <16 x i8> undef, i8 %q, i32 0
12   %q1 = insertelement <16 x i8> %q0, i8 %q, i32 1
13   %q2 = insertelement <16 x i8> %q1, i8 %q, i32 2
14   %q3 = insertelement <16 x i8> %q2, i8 %q, i32 3
15   %q4 = insertelement <16 x i8> %q3, i8 %q, i32 4
16   %q5 = insertelement <16 x i8> %q4, i8 %q, i32 5
17   %q6 = insertelement <16 x i8> %q5, i8 %q, i32 6
18   %q7 = insertelement <16 x i8> %q6, i8 %q, i32 7
19   %q8 = insertelement <16 x i8> %q7, i8 %q, i32 8
20   %q9 = insertelement <16 x i8> %q8, i8 %q, i32 9
21   %qa = insertelement <16 x i8> %q9, i8 %q, i32 10
22   %qb = insertelement <16 x i8> %qa, i8 %q, i32 11
23   %qc = insertelement <16 x i8> %qb, i8 %q, i32 12
24   %qd = insertelement <16 x i8> %qc, i8 %q, i32 13
25   %qe = insertelement <16 x i8> %qd, i8 %q, i32 14
26   %qf = insertelement <16 x i8> %qe, i8 %q, i32 15
27   ret <16 x i8> %qf
28 }
29
30 define <32 x i8> @BB32(i8* %ptr) nounwind uwtable readnone ssp {
31 ; CHECK-LABEL: BB32:
32 ; CHECK:       ## BB#0: ## %entry
33 ; CHECK-NEXT:    vpbroadcastb (%rdi), %ymm0
34 ; CHECK-NEXT:    retq
35 entry:
36   %q = load i8, i8* %ptr, align 4
37   %q0 = insertelement <32 x i8> undef, i8 %q, i32 0
38   %q1 = insertelement <32 x i8> %q0, i8 %q, i32 1
39   %q2 = insertelement <32 x i8> %q1, i8 %q, i32 2
40   %q3 = insertelement <32 x i8> %q2, i8 %q, i32 3
41   %q4 = insertelement <32 x i8> %q3, i8 %q, i32 4
42   %q5 = insertelement <32 x i8> %q4, i8 %q, i32 5
43   %q6 = insertelement <32 x i8> %q5, i8 %q, i32 6
44   %q7 = insertelement <32 x i8> %q6, i8 %q, i32 7
45   %q8 = insertelement <32 x i8> %q7, i8 %q, i32 8
46   %q9 = insertelement <32 x i8> %q8, i8 %q, i32 9
47   %qa = insertelement <32 x i8> %q9, i8 %q, i32 10
48   %qb = insertelement <32 x i8> %qa, i8 %q, i32 11
49   %qc = insertelement <32 x i8> %qb, i8 %q, i32 12
50   %qd = insertelement <32 x i8> %qc, i8 %q, i32 13
51   %qe = insertelement <32 x i8> %qd, i8 %q, i32 14
52   %qf = insertelement <32 x i8> %qe, i8 %q, i32 15
53
54   %q20 = insertelement <32 x i8> %qf, i8 %q,  i32 16
55   %q21 = insertelement <32 x i8> %q20, i8 %q, i32 17
56   %q22 = insertelement <32 x i8> %q21, i8 %q, i32 18
57   %q23 = insertelement <32 x i8> %q22, i8 %q, i32 19
58   %q24 = insertelement <32 x i8> %q23, i8 %q, i32 20
59   %q25 = insertelement <32 x i8> %q24, i8 %q, i32 21
60   %q26 = insertelement <32 x i8> %q25, i8 %q, i32 22
61   %q27 = insertelement <32 x i8> %q26, i8 %q, i32 23
62   %q28 = insertelement <32 x i8> %q27, i8 %q, i32 24
63   %q29 = insertelement <32 x i8> %q28, i8 %q, i32 25
64   %q2a = insertelement <32 x i8> %q29, i8 %q, i32 26
65   %q2b = insertelement <32 x i8> %q2a, i8 %q, i32 27
66   %q2c = insertelement <32 x i8> %q2b, i8 %q, i32 28
67   %q2d = insertelement <32 x i8> %q2c, i8 %q, i32 29
68   %q2e = insertelement <32 x i8> %q2d, i8 %q, i32 30
69   %q2f = insertelement <32 x i8> %q2e, i8 %q, i32 31
70   ret <32 x i8> %q2f
71 }
72
73 define <8 x i16> @W16(i16* %ptr) nounwind uwtable readnone ssp {
74 ; CHECK-LABEL: W16:
75 ; CHECK:       ## BB#0: ## %entry
76 ; CHECK-NEXT:    vpbroadcastw (%rdi), %xmm0
77 ; CHECK-NEXT:    retq
78 entry:
79   %q = load i16, i16* %ptr, align 4
80   %q0 = insertelement <8 x i16> undef, i16 %q, i32 0
81   %q1 = insertelement <8 x i16> %q0, i16 %q, i32 1
82   %q2 = insertelement <8 x i16> %q1, i16 %q, i32 2
83   %q3 = insertelement <8 x i16> %q2, i16 %q, i32 3
84   %q4 = insertelement <8 x i16> %q3, i16 %q, i32 4
85   %q5 = insertelement <8 x i16> %q4, i16 %q, i32 5
86   %q6 = insertelement <8 x i16> %q5, i16 %q, i32 6
87   %q7 = insertelement <8 x i16> %q6, i16 %q, i32 7
88   ret <8 x i16> %q7
89 }
90
91 define <16 x i16> @WW16(i16* %ptr) nounwind uwtable readnone ssp {
92 ; CHECK-LABEL: WW16:
93 ; CHECK:       ## BB#0: ## %entry
94 ; CHECK-NEXT:    vpbroadcastw (%rdi), %ymm0
95 ; CHECK-NEXT:    retq
96 entry:
97   %q = load i16, i16* %ptr, align 4
98   %q0 = insertelement <16 x i16> undef, i16 %q, i32 0
99   %q1 = insertelement <16 x i16> %q0, i16 %q, i32 1
100   %q2 = insertelement <16 x i16> %q1, i16 %q, i32 2
101   %q3 = insertelement <16 x i16> %q2, i16 %q, i32 3
102   %q4 = insertelement <16 x i16> %q3, i16 %q, i32 4
103   %q5 = insertelement <16 x i16> %q4, i16 %q, i32 5
104   %q6 = insertelement <16 x i16> %q5, i16 %q, i32 6
105   %q7 = insertelement <16 x i16> %q6, i16 %q, i32 7
106   %q8 = insertelement <16 x i16> %q7, i16 %q, i32 8
107   %q9 = insertelement <16 x i16> %q8, i16 %q, i32 9
108   %qa = insertelement <16 x i16> %q9, i16 %q, i32 10
109   %qb = insertelement <16 x i16> %qa, i16 %q, i32 11
110   %qc = insertelement <16 x i16> %qb, i16 %q, i32 12
111   %qd = insertelement <16 x i16> %qc, i16 %q, i32 13
112   %qe = insertelement <16 x i16> %qd, i16 %q, i32 14
113   %qf = insertelement <16 x i16> %qe, i16 %q, i32 15
114   ret <16 x i16> %qf
115 }
116
117 define <4 x i32> @D32(i32* %ptr) nounwind uwtable readnone ssp {
118 ; CHECK-LABEL: D32:
119 ; CHECK:       ## BB#0: ## %entry
120 ; CHECK-NEXT:    vbroadcastss (%rdi), %xmm0
121 ; CHECK-NEXT:    retq
122 entry:
123   %q = load i32, i32* %ptr, align 4
124   %q0 = insertelement <4 x i32> undef, i32 %q, i32 0
125   %q1 = insertelement <4 x i32> %q0, i32 %q, i32 1
126   %q2 = insertelement <4 x i32> %q1, i32 %q, i32 2
127   %q3 = insertelement <4 x i32> %q2, i32 %q, i32 3
128   ret <4 x i32> %q3
129 }
130
131 define <8 x i32> @DD32(i32* %ptr) nounwind uwtable readnone ssp {
132 ; CHECK-LABEL: DD32:
133 ; CHECK:       ## BB#0: ## %entry
134 ; CHECK-NEXT:    vbroadcastss (%rdi), %ymm0
135 ; CHECK-NEXT:    retq
136 entry:
137   %q = load i32, i32* %ptr, align 4
138   %q0 = insertelement <8 x i32> undef, i32 %q, i32 0
139   %q1 = insertelement <8 x i32> %q0, i32 %q, i32 1
140   %q2 = insertelement <8 x i32> %q1, i32 %q, i32 2
141   %q3 = insertelement <8 x i32> %q2, i32 %q, i32 3
142   %q4 = insertelement <8 x i32> %q3, i32 %q, i32 4
143   %q5 = insertelement <8 x i32> %q4, i32 %q, i32 5
144   %q6 = insertelement <8 x i32> %q5, i32 %q, i32 6
145   %q7 = insertelement <8 x i32> %q6, i32 %q, i32 7
146   ret <8 x i32> %q7
147 }
148
149 define <2 x i64> @Q64(i64* %ptr) nounwind uwtable readnone ssp {
150 ; CHECK-LABEL: Q64:
151 ; CHECK:       ## BB#0: ## %entry
152 ; CHECK-NEXT:    vpbroadcastq (%rdi), %xmm0
153 ; CHECK-NEXT:    retq
154 entry:
155   %q = load i64, i64* %ptr, align 4
156   %q0 = insertelement <2 x i64> undef, i64 %q, i32 0
157   %q1 = insertelement <2 x i64> %q0, i64 %q, i32 1
158   ret <2 x i64> %q1
159 }
160
161 define <4 x i64> @QQ64(i64* %ptr) nounwind uwtable readnone ssp {
162 ; CHECK-LABEL: QQ64:
163 ; CHECK:       ## BB#0: ## %entry
164 ; CHECK-NEXT:    vbroadcastsd (%rdi), %ymm0
165 ; CHECK-NEXT:    retq
166 entry:
167   %q = load i64, i64* %ptr, align 4
168   %q0 = insertelement <4 x i64> undef, i64 %q, i32 0
169   %q1 = insertelement <4 x i64> %q0, i64 %q, i32 1
170   %q2 = insertelement <4 x i64> %q1, i64 %q, i32 2
171   %q3 = insertelement <4 x i64> %q2, i64 %q, i32 3
172   ret <4 x i64> %q3
173 }
174
175 ; make sure that we still don't support broadcast double into 128-bit vector
176 ; this used to crash
177 define <2 x double> @I(double* %ptr) nounwind uwtable readnone ssp {
178 ; CHECK-LABEL: I:
179 ; CHECK:       ## BB#0: ## %entry
180 ; CHECK-NEXT:    vmovddup {{.*#+}} xmm0 = mem[0,0]
181 ; CHECK-NEXT:    retq
182 entry:
183   %q = load double, double* %ptr, align 4
184   %vecinit.i = insertelement <2 x double> undef, double %q, i32 0
185   %vecinit2.i = insertelement <2 x double> %vecinit.i, double %q, i32 1
186   ret <2 x double> %vecinit2.i
187 }
188
189 define <8 x i32> @V111(<8 x i32> %in) nounwind uwtable readnone ssp {
190 ; CHECK-LABEL: V111:
191 ; CHECK:       ## BB#0: ## %entry
192 ; CHECK-NEXT:    vpbroadcastd {{.*}}(%rip), %ymm1
193 ; CHECK-NEXT:    vpaddd %ymm1, %ymm0, %ymm0
194 ; CHECK-NEXT:    retq
195 entry:
196   %g = add <8 x i32> %in, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
197   ret <8 x i32> %g
198 }
199
200 define <8 x float> @V113(<8 x float> %in) nounwind uwtable readnone ssp {
201 ; CHECK-LABEL: V113:
202 ; CHECK:       ## BB#0: ## %entry
203 ; CHECK-NEXT:    vbroadcastss {{.*}}(%rip), %ymm1
204 ; CHECK-NEXT:    vaddps %ymm1, %ymm0, %ymm0
205 ; CHECK-NEXT:    retq
206 entry:
207   %g = fadd <8 x float> %in, <float 0xbf80000000000000, float 0xbf80000000000000, float 0xbf80000000000000, float 0xbf80000000000000, float 0xbf80000000000000, float 0xbf80000000000000, float 0xbf80000000000000, float 0xbf80000000000000>
208   ret <8 x float> %g
209 }
210
211 define <4 x float> @_e2(float* %ptr) nounwind uwtable readnone ssp {
212 ; CHECK-LABEL: _e2:
213 ; CHECK:       ## BB#0:
214 ; CHECK-NEXT:    vbroadcastss {{.*}}(%rip), %xmm0
215 ; CHECK-NEXT:    retq
216   %vecinit.i = insertelement <4 x float> undef, float        0xbf80000000000000, i32 0
217   %vecinit2.i = insertelement <4 x float> %vecinit.i, float  0xbf80000000000000, i32 1
218   %vecinit4.i = insertelement <4 x float> %vecinit2.i, float 0xbf80000000000000, i32 2
219   %vecinit6.i = insertelement <4 x float> %vecinit4.i, float 0xbf80000000000000, i32 3
220   ret <4 x float> %vecinit6.i
221 }
222
223 define <8 x i8> @_e4(i8* %ptr) nounwind uwtable readnone ssp {
224 ; CHECK-LABEL: _e4:
225 ; CHECK:       ## BB#0:
226 ; CHECK-NEXT:    vmovaps {{.*#+}} xmm0 = [52,52,52,52,52,52,52,52]
227 ; CHECK-NEXT:    retq
228   %vecinit0.i = insertelement <8 x i8> undef, i8       52, i32 0
229   %vecinit1.i = insertelement <8 x i8> %vecinit0.i, i8 52, i32 1
230   %vecinit2.i = insertelement <8 x i8> %vecinit1.i, i8 52, i32 2
231   %vecinit3.i = insertelement <8 x i8> %vecinit2.i, i8 52, i32 3
232   %vecinit4.i = insertelement <8 x i8> %vecinit3.i, i8 52, i32 4
233   %vecinit5.i = insertelement <8 x i8> %vecinit4.i, i8 52, i32 5
234   %vecinit6.i = insertelement <8 x i8> %vecinit5.i, i8 52, i32 6
235   %vecinit7.i = insertelement <8 x i8> %vecinit6.i, i8 52, i32 7
236   ret <8 x i8> %vecinit7.i
237 }
238
239
240 define void @crash() nounwind alwaysinline {
241 ; CHECK-LABEL: crash:
242 ; CHECK:       ## BB#0: ## %WGLoopsEntry
243 ; CHECK-NEXT:    xorl %eax, %eax
244 ; CHECK-NEXT:    testb %al, %al
245 ; CHECK-NEXT:    je LBB13_1
246 ; CHECK-NEXT:  ## BB#2: ## %ret
247 ; CHECK-NEXT:    retq
248 ; CHECK-NEXT:    .align 4, 0x90
249 ; CHECK-NEXT:  LBB13_1: ## %footer349VF
250 ; CHECK-NEXT:    ## =>This Inner Loop Header: Depth=1
251 ; CHECK-NEXT:    jmp LBB13_1
252 WGLoopsEntry:
253   br i1 undef, label %ret, label %footer329VF
254
255 footer329VF:
256   %A.0.inVF = fmul float undef, 6.553600e+04
257   %B.0.in407VF = fmul <8 x float> undef, <float 6.553600e+04, float 6.553600e+04, float 6.553600e+04, float 6.553600e+04, float 6.553600e+04, float 6.553600e+04, float 6.553600e+04, float 6.553600e+04>
258   %A.0VF = fptosi float %A.0.inVF to i32
259   %B.0408VF = fptosi <8 x float> %B.0.in407VF to <8 x i32>
260   %0 = and <8 x i32> %B.0408VF, <i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535>
261   %1 = and i32 %A.0VF, 65535
262   %temp1098VF = insertelement <8 x i32> undef, i32 %1, i32 0
263   %vector1099VF = shufflevector <8 x i32> %temp1098VF, <8 x i32> undef, <8 x i32> zeroinitializer
264   br i1 undef, label %preload1201VF, label %footer349VF
265
266 preload1201VF:
267   br label %footer349VF
268
269 footer349VF:
270   %2 = mul nsw <8 x i32> undef, %0
271   %3 = mul nsw <8 x i32> undef, %vector1099VF
272   br label %footer329VF
273
274 ret:
275   ret void
276 }
277
278 define <8 x i32> @_inreg0(i32 %scalar) nounwind uwtable readnone ssp {
279 ; CHECK-LABEL: _inreg0:
280 ; CHECK:       ## BB#0:
281 ; CHECK-NEXT:    vmovd %edi, %xmm0
282 ; CHECK-NEXT:    vbroadcastss %xmm0, %ymm0
283 ; CHECK-NEXT:    retq
284   %in = insertelement <8 x i32> undef, i32 %scalar, i32 0
285   %wide = shufflevector <8 x i32> %in, <8 x i32> undef, <8 x i32> zeroinitializer
286   ret <8 x i32> %wide
287 }
288
289 define <8 x float> @_inreg1(float %scalar) nounwind uwtable readnone ssp {
290 ; CHECK-LABEL: _inreg1:
291 ; CHECK:       ## BB#0:
292 ; CHECK-NEXT:    vbroadcastss %xmm0, %ymm0
293 ; CHECK-NEXT:    retq
294   %in = insertelement <8 x float> undef, float %scalar, i32 0
295   %wide = shufflevector <8 x float> %in, <8 x float> undef, <8 x i32> zeroinitializer
296   ret <8 x float> %wide
297 }
298
299 define <4 x float> @_inreg2(float %scalar) nounwind uwtable readnone ssp {
300 ; CHECK-LABEL: _inreg2:
301 ; CHECK:       ## BB#0:
302 ; CHECK-NEXT:    vbroadcastss %xmm0, %xmm0
303 ; CHECK-NEXT:    retq
304   %in = insertelement <4 x float> undef, float %scalar, i32 0
305   %wide = shufflevector <4 x float> %in, <4 x float> undef, <4 x i32> zeroinitializer
306   ret <4 x float> %wide
307 }
308
309 define <4 x double> @_inreg3(double %scalar) nounwind uwtable readnone ssp {
310 ; CHECK-LABEL: _inreg3:
311 ; CHECK:       ## BB#0:
312 ; CHECK-NEXT:    vbroadcastsd %xmm0, %ymm0
313 ; CHECK-NEXT:    retq
314   %in = insertelement <4 x double> undef, double %scalar, i32 0
315   %wide = shufflevector <4 x double> %in, <4 x double> undef, <4 x i32> zeroinitializer
316   ret <4 x double> %wide
317 }
318
319 define   <8 x float> @_inreg8xfloat(<8 x float> %a) {
320 ; CHECK-LABEL: _inreg8xfloat:
321 ; CHECK:       ## BB#0:
322 ; CHECK-NEXT:    vbroadcastss %xmm0, %ymm0
323 ; CHECK-NEXT:    retq
324   %b = shufflevector <8 x float> %a, <8 x float> undef, <8 x i32> zeroinitializer
325   ret <8 x float> %b
326 }
327
328 define   <4 x float> @_inreg4xfloat(<4 x float> %a) {
329 ; CHECK-LABEL: _inreg4xfloat:
330 ; CHECK:       ## BB#0:
331 ; CHECK-NEXT:    vbroadcastss %xmm0, %xmm0
332 ; CHECK-NEXT:    retq
333   %b = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> zeroinitializer
334   ret <4 x float> %b
335 }
336
337 define   <16 x i16> @_inreg16xi16(<16 x i16> %a) {
338 ; CHECK-LABEL: _inreg16xi16:
339 ; CHECK:       ## BB#0:
340 ; CHECK-NEXT:    vpbroadcastw %xmm0, %ymm0
341 ; CHECK-NEXT:    retq
342   %b = shufflevector <16 x i16> %a, <16 x i16> undef, <16 x i32> zeroinitializer
343   ret <16 x i16> %b
344 }
345
346 define   <8 x i16> @_inreg8xi16(<8 x i16> %a) {
347 ; CHECK-LABEL: _inreg8xi16:
348 ; CHECK:       ## BB#0:
349 ; CHECK-NEXT:    vpbroadcastw %xmm0, %xmm0
350 ; CHECK-NEXT:    retq
351   %b = shufflevector <8 x i16> %a, <8 x i16> undef, <8 x i32> zeroinitializer
352   ret <8 x i16> %b
353 }
354
355 define   <4 x i64> @_inreg4xi64(<4 x i64> %a) {
356 ; CHECK-LABEL: _inreg4xi64:
357 ; CHECK:       ## BB#0:
358 ; CHECK-NEXT:    vbroadcastsd %xmm0, %ymm0
359 ; CHECK-NEXT:    retq
360   %b = shufflevector <4 x i64> %a, <4 x i64> undef, <4 x i32> zeroinitializer
361   ret <4 x i64> %b
362 }
363
364 define   <2 x i64> @_inreg2xi64(<2 x i64> %a) {
365 ; CHECK-LABEL: _inreg2xi64:
366 ; CHECK:       ## BB#0:
367 ; CHECK-NEXT:    vpbroadcastq %xmm0, %xmm0
368 ; CHECK-NEXT:    retq
369   %b = shufflevector <2 x i64> %a, <2 x i64> undef, <2 x i32> zeroinitializer
370   ret <2 x i64> %b
371 }
372
373 define   <4 x double> @_inreg4xdouble(<4 x double> %a) {
374 ; CHECK-LABEL: _inreg4xdouble:
375 ; CHECK:       ## BB#0:
376 ; CHECK-NEXT:    vbroadcastsd %xmm0, %ymm0
377 ; CHECK-NEXT:    retq
378   %b = shufflevector <4 x double> %a, <4 x double> undef, <4 x i32> zeroinitializer
379   ret <4 x double> %b
380 }
381
382 define   <2 x double> @_inreg2xdouble(<2 x double> %a) {
383 ; CHECK-LABEL: _inreg2xdouble:
384 ; CHECK:       ## BB#0:
385 ; CHECK-NEXT:    vmovddup {{.*#+}} xmm0 = xmm0[0,0]
386 ; CHECK-NEXT:    retq
387   %b = shufflevector <2 x double> %a, <2 x double> undef, <2 x i32> zeroinitializer
388   ret <2 x double> %b
389 }
390
391 define   <8 x i32> @_inreg8xi32(<8 x i32> %a) {
392 ; CHECK-LABEL: _inreg8xi32:
393 ; CHECK:       ## BB#0:
394 ; CHECK-NEXT:    vbroadcastss %xmm0, %ymm0
395 ; CHECK-NEXT:    retq
396   %b = shufflevector <8 x i32> %a, <8 x i32> undef, <8 x i32> zeroinitializer
397   ret <8 x i32> %b
398 }
399
400 define   <4 x i32> @_inreg4xi32(<4 x i32> %a) {
401 ; CHECK-LABEL: _inreg4xi32:
402 ; CHECK:       ## BB#0:
403 ; CHECK-NEXT:    vbroadcastss %xmm0, %xmm0
404 ; CHECK-NEXT:    retq
405   %b = shufflevector <4 x i32> %a, <4 x i32> undef, <4 x i32> zeroinitializer
406   ret <4 x i32> %b
407 }
408
409 define   <32 x i8> @_inreg32xi8(<32 x i8> %a) {
410 ; CHECK-LABEL: _inreg32xi8:
411 ; CHECK:       ## BB#0:
412 ; CHECK-NEXT:    vpbroadcastb %xmm0, %ymm0
413 ; CHECK-NEXT:    retq
414   %b = shufflevector <32 x i8> %a, <32 x i8> undef, <32 x i32> zeroinitializer
415   ret <32 x i8> %b
416 }
417
418 define   <16 x i8> @_inreg16xi8(<16 x i8> %a) {
419 ; CHECK-LABEL: _inreg16xi8:
420 ; CHECK:       ## BB#0:
421 ; CHECK-NEXT:    vpbroadcastb %xmm0, %xmm0
422 ; CHECK-NEXT:    retq
423   %b = shufflevector <16 x i8> %a, <16 x i8> undef, <16 x i32> zeroinitializer
424   ret <16 x i8> %b
425 }
426
427 ; These tests check that a vbroadcast instruction is used when we have a splat
428 ; formed from a concat_vectors (via the shufflevector) of two BUILD_VECTORs
429 ; (via the insertelements).
430
431 define <8 x float> @splat_concat1(float %f) {
432 ; CHECK-LABEL: splat_concat1:
433 ; CHECK:       ## BB#0:
434 ; CHECK-NEXT:    vbroadcastss %xmm0, %ymm0
435 ; CHECK-NEXT:    retq
436   %1 = insertelement <4 x float> undef, float %f, i32 0
437   %2 = insertelement <4 x float> %1, float %f, i32 1
438   %3 = insertelement <4 x float> %2, float %f, i32 2
439   %4 = insertelement <4 x float> %3, float %f, i32 3
440   %5 = shufflevector <4 x float> %4, <4 x float> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 3>
441   ret <8 x float> %5
442 }
443
444 define <8 x float> @splat_concat2(float %f) {
445 ; CHECK-LABEL: splat_concat2:
446 ; CHECK:       ## BB#0:
447 ; CHECK-NEXT:    vbroadcastss %xmm0, %ymm0
448 ; CHECK-NEXT:    retq
449   %1 = insertelement <4 x float> undef, float %f, i32 0
450   %2 = insertelement <4 x float> %1, float %f, i32 1
451   %3 = insertelement <4 x float> %2, float %f, i32 2
452   %4 = insertelement <4 x float> %3, float %f, i32 3
453   %5 = insertelement <4 x float> undef, float %f, i32 0
454   %6 = insertelement <4 x float> %5, float %f, i32 1
455   %7 = insertelement <4 x float> %6, float %f, i32 2
456   %8 = insertelement <4 x float> %7, float %f, i32 3
457   %9 = shufflevector <4 x float> %4, <4 x float> %8, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
458   ret <8 x float> %9
459 }
460
461 define <4 x double> @splat_concat3(double %d) {
462 ; CHECK-LABEL: splat_concat3:
463 ; CHECK:       ## BB#0:
464 ; CHECK-NEXT:    vbroadcastsd %xmm0, %ymm0
465 ; CHECK-NEXT:    retq
466   %1 = insertelement <2 x double> undef, double %d, i32 0
467   %2 = insertelement <2 x double> %1, double %d, i32 1
468   %3 = shufflevector <2 x double> %2, <2 x double> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
469   ret <4 x double> %3
470 }
471
472 define <4 x double> @splat_concat4(double %d) {
473 ; CHECK-LABEL: splat_concat4:
474 ; CHECK:       ## BB#0:
475 ; CHECK-NEXT:    vbroadcastsd %xmm0, %ymm0
476 ; CHECK-NEXT:    retq
477   %1 = insertelement <2 x double> undef, double %d, i32 0
478   %2 = insertelement <2 x double> %1, double %d, i32 1
479   %3 = insertelement <2 x double> undef, double %d, i32 0
480   %4 = insertelement <2 x double> %3, double %d, i32 1
481   %5 = shufflevector <2 x double> %2, <2 x double> %4, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
482   ret <4 x double> %5
483 }
484
485 ; Test cases for <rdar://problem/16074331>.
486 ; Instruction selection for broacast instruction fails if
487 ; the load cannot be folded into the broadcast.
488 ; This happens if the load has initial one use but other uses are
489 ; created later, or if selection DAG cannot prove that folding the
490 ; load will not create a cycle in the DAG.
491 ; Those test cases exerce the latter.
492
493 ; CHECK-LABEL: isel_crash_16b
494 ; CHECK: vpbroadcastb {{[^,]+}}, %xmm{{[0-9]+}}
495 ; CHECK: ret
496 define void @isel_crash_16b(i8* %cV_R.addr) {
497 eintry:
498   %__a.addr.i = alloca <2 x i64>, align 16
499   %__b.addr.i = alloca <2 x i64>, align 16
500   %vCr = alloca <2 x i64>, align 16
501   store <2 x i64> zeroinitializer, <2 x i64>* %vCr, align 16
502   %tmp = load <2 x i64>, <2 x i64>* %vCr, align 16
503   %tmp2 = load i8, i8* %cV_R.addr, align 4
504   %splat.splatinsert = insertelement <16 x i8> undef, i8 %tmp2, i32 0
505   %splat.splat = shufflevector <16 x i8> %splat.splatinsert, <16 x i8> undef, <16 x i32> zeroinitializer
506   %tmp3 = bitcast <16 x i8> %splat.splat to <2 x i64>
507   store <2 x i64> %tmp, <2 x i64>* %__a.addr.i, align 16
508   store <2 x i64> %tmp3, <2 x i64>* %__b.addr.i, align 16
509   ret void
510 }
511
512 ; CHECK-LABEL: isel_crash_32b
513 ; CHECK: vpbroadcastb {{[^,]+}}, %ymm{{[0-9]+}}
514 ; CHECK: ret
515 define void @isel_crash_32b(i8* %cV_R.addr) {
516 eintry:
517   %__a.addr.i = alloca <4 x i64>, align 16
518   %__b.addr.i = alloca <4 x i64>, align 16
519   %vCr = alloca <4 x i64>, align 16
520   store <4 x i64> zeroinitializer, <4 x i64>* %vCr, align 16
521   %tmp = load <4 x i64>, <4 x i64>* %vCr, align 16
522   %tmp2 = load i8, i8* %cV_R.addr, align 4
523   %splat.splatinsert = insertelement <32 x i8> undef, i8 %tmp2, i32 0
524   %splat.splat = shufflevector <32 x i8> %splat.splatinsert, <32 x i8> undef, <32 x i32> zeroinitializer
525   %tmp3 = bitcast <32 x i8> %splat.splat to <4 x i64>
526   store <4 x i64> %tmp, <4 x i64>* %__a.addr.i, align 16
527   store <4 x i64> %tmp3, <4 x i64>* %__b.addr.i, align 16
528   ret void
529 }
530
531 ; CHECK-LABEL: isel_crash_8w
532 ; CHECK: vpbroadcastw {{[^,]+}}, %xmm{{[0-9]+}}
533 ; CHECK: ret
534 define void @isel_crash_8w(i16* %cV_R.addr) {
535 entry:
536   %__a.addr.i = alloca <2 x i64>, align 16
537   %__b.addr.i = alloca <2 x i64>, align 16
538   %vCr = alloca <2 x i64>, align 16
539   store <2 x i64> zeroinitializer, <2 x i64>* %vCr, align 16
540   %tmp = load <2 x i64>, <2 x i64>* %vCr, align 16
541   %tmp2 = load i16, i16* %cV_R.addr, align 4
542   %splat.splatinsert = insertelement <8 x i16> undef, i16 %tmp2, i32 0
543   %splat.splat = shufflevector <8 x i16> %splat.splatinsert, <8 x i16> undef, <8 x i32> zeroinitializer
544   %tmp3 = bitcast <8 x i16> %splat.splat to <2 x i64>
545   store <2 x i64> %tmp, <2 x i64>* %__a.addr.i, align 16
546   store <2 x i64> %tmp3, <2 x i64>* %__b.addr.i, align 16
547   ret void
548 }
549
550 ; CHECK-LABEL: isel_crash_16w
551 ; CHECK: vpbroadcastw {{[^,]+}}, %ymm{{[0-9]+}}
552 ; CHECK: ret
553 define void @isel_crash_16w(i16* %cV_R.addr) {
554 eintry:
555   %__a.addr.i = alloca <4 x i64>, align 16
556   %__b.addr.i = alloca <4 x i64>, align 16
557   %vCr = alloca <4 x i64>, align 16
558   store <4 x i64> zeroinitializer, <4 x i64>* %vCr, align 16
559   %tmp = load <4 x i64>, <4 x i64>* %vCr, align 16
560   %tmp2 = load i16, i16* %cV_R.addr, align 4
561   %splat.splatinsert = insertelement <16 x i16> undef, i16 %tmp2, i32 0
562   %splat.splat = shufflevector <16 x i16> %splat.splatinsert, <16 x i16> undef, <16 x i32> zeroinitializer
563   %tmp3 = bitcast <16 x i16> %splat.splat to <4 x i64>
564   store <4 x i64> %tmp, <4 x i64>* %__a.addr.i, align 16
565   store <4 x i64> %tmp3, <4 x i64>* %__b.addr.i, align 16
566   ret void
567 }
568
569 ; CHECK-LABEL: isel_crash_4d
570 ; CHECK: vbroadcastss {{[^,]+}}, %xmm{{[0-9]+}}
571 ; CHECK: ret
572 define void @isel_crash_4d(i32* %cV_R.addr) {
573 entry:
574   %__a.addr.i = alloca <2 x i64>, align 16
575   %__b.addr.i = alloca <2 x i64>, align 16
576   %vCr = alloca <2 x i64>, align 16
577   store <2 x i64> zeroinitializer, <2 x i64>* %vCr, align 16
578   %tmp = load <2 x i64>, <2 x i64>* %vCr, align 16
579   %tmp2 = load i32, i32* %cV_R.addr, align 4
580   %splat.splatinsert = insertelement <4 x i32> undef, i32 %tmp2, i32 0
581   %splat.splat = shufflevector <4 x i32> %splat.splatinsert, <4 x i32> undef, <4 x i32> zeroinitializer
582   %tmp3 = bitcast <4 x i32> %splat.splat to <2 x i64>
583   store <2 x i64> %tmp, <2 x i64>* %__a.addr.i, align 16
584   store <2 x i64> %tmp3, <2 x i64>* %__b.addr.i, align 16
585   ret void
586 }
587
588 ; CHECK-LABEL: isel_crash_8d
589 ; CHECK: vbroadcastss {{[^,]+}}, %ymm{{[0-9]+}}
590 ; CHECK: ret
591 define void @isel_crash_8d(i32* %cV_R.addr) {
592 eintry:
593   %__a.addr.i = alloca <4 x i64>, align 16
594   %__b.addr.i = alloca <4 x i64>, align 16
595   %vCr = alloca <4 x i64>, align 16
596   store <4 x i64> zeroinitializer, <4 x i64>* %vCr, align 16
597   %tmp = load <4 x i64>, <4 x i64>* %vCr, align 16
598   %tmp2 = load i32, i32* %cV_R.addr, align 4
599   %splat.splatinsert = insertelement <8 x i32> undef, i32 %tmp2, i32 0
600   %splat.splat = shufflevector <8 x i32> %splat.splatinsert, <8 x i32> undef, <8 x i32> zeroinitializer
601   %tmp3 = bitcast <8 x i32> %splat.splat to <4 x i64>
602   store <4 x i64> %tmp, <4 x i64>* %__a.addr.i, align 16
603   store <4 x i64> %tmp3, <4 x i64>* %__b.addr.i, align 16
604   ret void
605 }
606
607 ; CHECK-LABEL: isel_crash_2q
608 ; CHECK: vpbroadcastq {{[^,]+}}, %xmm{{[0-9]+}}
609 ; CHECK: ret
610 define void @isel_crash_2q(i64* %cV_R.addr) {
611 entry:
612   %__a.addr.i = alloca <2 x i64>, align 16
613   %__b.addr.i = alloca <2 x i64>, align 16
614   %vCr = alloca <2 x i64>, align 16
615   store <2 x i64> zeroinitializer, <2 x i64>* %vCr, align 16
616   %tmp = load <2 x i64>, <2 x i64>* %vCr, align 16
617   %tmp2 = load i64, i64* %cV_R.addr, align 4
618   %splat.splatinsert = insertelement <2 x i64> undef, i64 %tmp2, i32 0
619   %splat.splat = shufflevector <2 x i64> %splat.splatinsert, <2 x i64> undef, <2 x i32> zeroinitializer
620   store <2 x i64> %tmp, <2 x i64>* %__a.addr.i, align 16
621   store <2 x i64> %splat.splat, <2 x i64>* %__b.addr.i, align 16
622   ret void
623 }
624
625 ; CHECK-LABEL: isel_crash_4q
626 ; CHECK: vbroadcastsd {{[^,]+}}, %ymm{{[0-9]+}}
627 ; CHECK: ret
628 define void @isel_crash_4q(i64* %cV_R.addr) {
629 eintry:
630   %__a.addr.i = alloca <4 x i64>, align 16
631   %__b.addr.i = alloca <4 x i64>, align 16
632   %vCr = alloca <4 x i64>, align 16
633   store <4 x i64> zeroinitializer, <4 x i64>* %vCr, align 16
634   %tmp = load <4 x i64>, <4 x i64>* %vCr, align 16
635   %tmp2 = load i64, i64* %cV_R.addr, align 4
636   %splat.splatinsert = insertelement <4 x i64> undef, i64 %tmp2, i32 0
637   %splat.splat = shufflevector <4 x i64> %splat.splatinsert, <4 x i64> undef, <4 x i32> zeroinitializer
638   store <4 x i64> %tmp, <4 x i64>* %__a.addr.i, align 16
639   store <4 x i64> %splat.splat, <4 x i64>* %__b.addr.i, align 16
640   ret void
641 }