[AVX512] Bring back vector-shuffle lowering support through broadcasts
[oota-llvm.git] / test / CodeGen / X86 / fast-isel-select-sse.ll
1 ; RUN: llc < %s -mtriple=x86_64-apple-darwin10                                              | FileCheck %s
2 ; RUN: llc < %s -mtriple=x86_64-apple-darwin10 -fast-isel -fast-isel-abort                  | FileCheck %s
3 ; RUN: llc < %s -mtriple=x86_64-apple-darwin10                             -mcpu=corei7-avx | FileCheck %s --check-prefix=AVX
4 ; RUN: llc < %s -mtriple=x86_64-apple-darwin10 -fast-isel -fast-isel-abort -mcpu=corei7-avx | FileCheck %s --check-prefix=AVX
5
6 ; Test all cmp predicates that can be used with SSE.
7
8 define float @select_fcmp_oeq_f32(float %a, float %b, float %c, float %d) {
9 ; CHECK-LABEL: select_fcmp_oeq_f32
10 ; CHECK:       cmpeqss %xmm1, %xmm0
11 ; CHECK-NEXT:  andps   %xmm0, %xmm2
12 ; CHECK-NEXT:  andnps  %xmm3, %xmm0
13 ; CHECK-NEXT:  orps    %xmm2, %xmm0
14 ; AVX-LABEL: select_fcmp_oeq_f32
15 ; AVX:       vcmpeqss %xmm1, %xmm0, %xmm0
16 ; AVX-NEXT:  vandps   %xmm2, %xmm0, %xmm1
17 ; AVX-NEXT:  vandnps  %xmm3, %xmm0, %xmm0
18 ; AVX-NEXT:  vorps    %xmm1, %xmm0, %xmm0
19   %1 = fcmp oeq float %a, %b
20   %2 = select i1 %1, float %c, float %d
21   ret float %2
22 }
23
24 define double @select_fcmp_oeq_f64(double %a, double %b, double %c, double %d) {
25 ; CHECK-LABEL: select_fcmp_oeq_f64
26 ; CHECK:       cmpeqsd %xmm1, %xmm0
27 ; CHECK-NEXT:  andpd   %xmm0, %xmm2
28 ; CHECK-NEXT:  andnpd  %xmm3, %xmm0
29 ; CHECK-NEXT:  orpd    %xmm2, %xmm0
30 ; AVX-LABEL: select_fcmp_oeq_f64
31 ; AVX:       vcmpeqsd %xmm1, %xmm0, %xmm0
32 ; AVX-NEXT:  vandpd   %xmm2, %xmm0, %xmm1
33 ; AVX-NEXT:  vandnpd  %xmm3, %xmm0, %xmm0
34 ; AVX-NEXT:  vorpd    %xmm1, %xmm0, %xmm0
35   %1 = fcmp oeq double %a, %b
36   %2 = select i1 %1, double %c, double %d
37   ret double %2
38 }
39
40 define float @select_fcmp_ogt_f32(float %a, float %b, float %c, float %d) {
41 ; CHECK-LABEL: select_fcmp_ogt_f32
42 ; CHECK:       cmpltss %xmm0, %xmm1
43 ; CHECK-NEXT:  andps   %xmm1, %xmm2
44 ; CHECK-NEXT:  andnps  %xmm3, %xmm1
45 ; CHECK-NEXT:  orps    %xmm2, %xmm1
46 ; AVX-LABEL: select_fcmp_ogt_f32
47 ; AVX:       vcmpltss %xmm0, %xmm1, %xmm0
48 ; AVX-NEXT:  vandps   %xmm2, %xmm0, %xmm1
49 ; AVX-NEXT:  vandnps  %xmm3, %xmm0, %xmm0
50 ; AVX-NEXT:  vorps    %xmm1, %xmm0, %xmm0
51   %1 = fcmp ogt float %a, %b
52   %2 = select i1 %1, float %c, float %d
53   ret float %2
54 }
55
56 define double @select_fcmp_ogt_f64(double %a, double %b, double %c, double %d) {
57 ; CHECK-LABEL: select_fcmp_ogt_f64
58 ; CHECK:       cmpltsd %xmm0, %xmm1
59 ; CHECK-NEXT:  andpd   %xmm1, %xmm2
60 ; CHECK-NEXT:  andnpd  %xmm3, %xmm1
61 ; CHECK-NEXT:  orpd    %xmm2, %xmm1
62 ; AVX-LABEL: select_fcmp_ogt_f64
63 ; AVX:       vcmpltsd %xmm0, %xmm1, %xmm0
64 ; AVX-NEXT:  vandpd   %xmm2, %xmm0, %xmm1
65 ; AVX-NEXT:  vandnpd  %xmm3, %xmm0, %xmm0
66 ; AVX-NEXT:  vorpd    %xmm1, %xmm0, %xmm0
67   %1 = fcmp ogt double %a, %b
68   %2 = select i1 %1, double %c, double %d
69   ret double %2
70 }
71
72 define float @select_fcmp_oge_f32(float %a, float %b, float %c, float %d) {
73 ; CHECK-LABEL: select_fcmp_oge_f32
74 ; CHECK:       cmpless %xmm0, %xmm1
75 ; CHECK-NEXT:  andps   %xmm1, %xmm2
76 ; CHECK-NEXT:  andnps  %xmm3, %xmm1
77 ; CHECK-NEXT:  orps    %xmm2, %xmm1
78 ; AVX-LABEL: select_fcmp_oge_f32
79 ; AVX:       vcmpless %xmm0, %xmm1, %xmm0
80 ; AVX-NEXT:  vandps   %xmm2, %xmm0, %xmm1
81 ; AVX-NEXT:  vandnps  %xmm3, %xmm0, %xmm0
82 ; AVX-NEXT:  vorps    %xmm1, %xmm0, %xmm0
83   %1 = fcmp oge float %a, %b
84   %2 = select i1 %1, float %c, float %d
85   ret float %2
86 }
87
88 define double @select_fcmp_oge_f64(double %a, double %b, double %c, double %d) {
89 ; CHECK-LABEL: select_fcmp_oge_f64
90 ; CHECK:       cmplesd %xmm0, %xmm1
91 ; CHECK-NEXT:  andpd   %xmm1, %xmm2
92 ; CHECK-NEXT:  andnpd  %xmm3, %xmm1
93 ; CHECK-NEXT:  orpd    %xmm2, %xmm1
94 ; AVX-LABEL: select_fcmp_oge_f64
95 ; AVX:       vcmplesd %xmm0, %xmm1, %xmm0
96 ; AVX-NEXT:  vandpd   %xmm2, %xmm0, %xmm1
97 ; AVX-NEXT:  vandnpd  %xmm3, %xmm0, %xmm0
98 ; AVX-NEXT:  vorpd    %xmm1, %xmm0, %xmm0
99   %1 = fcmp oge double %a, %b
100   %2 = select i1 %1, double %c, double %d
101   ret double %2
102 }
103
104 define float @select_fcmp_olt_f32(float %a, float %b, float %c, float %d) {
105 ; CHECK-LABEL: select_fcmp_olt_f32
106 ; CHECK:       cmpltss %xmm1, %xmm0
107 ; CHECK-NEXT:  andps   %xmm0, %xmm2
108 ; CHECK-NEXT:  andnps  %xmm3, %xmm0
109 ; CHECK-NEXT:  orps    %xmm2, %xmm0
110 ; AVX-LABEL: select_fcmp_olt_f32
111 ; AVX:       vcmpltss %xmm1, %xmm0, %xmm0
112 ; AVX-NEXT:  vandps   %xmm2, %xmm0, %xmm1
113 ; AVX-NEXT:  vandnps  %xmm3, %xmm0, %xmm0
114 ; AVX-NEXT:  vorps    %xmm1, %xmm0, %xmm0
115   %1 = fcmp olt float %a, %b
116   %2 = select i1 %1, float %c, float %d
117   ret float %2
118 }
119
120 define double @select_fcmp_olt_f64(double %a, double %b, double %c, double %d) {
121 ; CHECK-LABEL: select_fcmp_olt_f64
122 ; CHECK:       cmpltsd %xmm1, %xmm0
123 ; CHECK-NEXT:  andpd   %xmm0, %xmm2
124 ; CHECK-NEXT:  andnpd  %xmm3, %xmm0
125 ; CHECK-NEXT:  orpd    %xmm2, %xmm0
126 ; AVX-LABEL: select_fcmp_olt_f64
127 ; AVX:       vcmpltsd %xmm1, %xmm0, %xmm0
128 ; AVX-NEXT:  vandpd   %xmm2, %xmm0, %xmm1
129 ; AVX-NEXT:  vandnpd  %xmm3, %xmm0, %xmm0
130 ; AVX-NEXT:  vorpd    %xmm1, %xmm0, %xmm0
131   %1 = fcmp olt double %a, %b
132   %2 = select i1 %1, double %c, double %d
133   ret double %2
134 }
135
136 define float @select_fcmp_ole_f32(float %a, float %b, float %c, float %d) {
137 ; CHECK-LABEL: select_fcmp_ole_f32
138 ; CHECK:       cmpless %xmm1, %xmm0
139 ; CHECK-NEXT:  andps   %xmm0, %xmm2
140 ; CHECK-NEXT:  andnps  %xmm3, %xmm0
141 ; CHECK-NEXT:  orps    %xmm2, %xmm0
142 ; AVX-LABEL: select_fcmp_ole_f32
143 ; AVX:       vcmpless %xmm1, %xmm0, %xmm0
144 ; AVX-NEXT:  vandps   %xmm2, %xmm0, %xmm1
145 ; AVX-NEXT:  vandnps  %xmm3, %xmm0, %xmm0
146 ; AVX-NEXT:  vorps    %xmm1, %xmm0, %xmm0
147   %1 = fcmp ole float %a, %b
148   %2 = select i1 %1, float %c, float %d
149   ret float %2
150 }
151
152 define double @select_fcmp_ole_f64(double %a, double %b, double %c, double %d) {
153 ; CHECK-LABEL: select_fcmp_ole_f64
154 ; CHECK:       cmplesd %xmm1, %xmm0
155 ; CHECK-NEXT:  andpd   %xmm0, %xmm2
156 ; CHECK-NEXT:  andnpd  %xmm3, %xmm0
157 ; CHECK-NEXT:  orpd    %xmm2, %xmm0
158 ; AVX-LABEL: select_fcmp_ole_f64
159 ; AVX:       vcmplesd %xmm1, %xmm0, %xmm0
160 ; AVX-NEXT:  vandpd   %xmm2, %xmm0, %xmm1
161 ; AVX-NEXT:  vandnpd  %xmm3, %xmm0, %xmm0
162 ; AVX-NEXT:  vorpd    %xmm1, %xmm0, %xmm0
163   %1 = fcmp ole double %a, %b
164   %2 = select i1 %1, double %c, double %d
165   ret double %2
166 }
167
168 define float @select_fcmp_ord_f32(float %a, float %b, float %c, float %d) {
169 ; CHECK-LABEL: select_fcmp_ord_f32
170 ; CHECK:       cmpordss %xmm1, %xmm0
171 ; CHECK-NEXT:  andps    %xmm0, %xmm2
172 ; CHECK-NEXT:  andnps   %xmm3, %xmm0
173 ; CHECK-NEXT:  orps     %xmm2, %xmm0
174 ; AVX-LABEL: select_fcmp_ord_f32
175 ; AVX:       vcmpordss %xmm1, %xmm0, %xmm0
176 ; AVX-NEXT:  vandps    %xmm2, %xmm0, %xmm1
177 ; AVX-NEXT:  vandnps   %xmm3, %xmm0, %xmm0
178 ; AVX-NEXT:  vorps     %xmm1, %xmm0, %xmm0
179   %1 = fcmp ord float %a, %b
180   %2 = select i1 %1, float %c, float %d
181   ret float %2
182 }
183
184 define double @select_fcmp_ord_f64(double %a, double %b, double %c, double %d) {
185 ; CHECK-LABEL: select_fcmp_ord_f64
186 ; CHECK:       cmpordsd %xmm1, %xmm0
187 ; CHECK-NEXT:  andpd    %xmm0, %xmm2
188 ; CHECK-NEXT:  andnpd   %xmm3, %xmm0
189 ; CHECK-NEXT:  orpd     %xmm2, %xmm0
190 ; AVX-LABEL: select_fcmp_ord_f64
191 ; AVX:       vcmpordsd %xmm1, %xmm0, %xmm0
192 ; AVX-NEXT:  vandpd    %xmm2, %xmm0, %xmm1
193 ; AVX-NEXT:  vandnpd   %xmm3, %xmm0, %xmm0
194 ; AVX-NEXT:  vorpd     %xmm1, %xmm0, %xmm0
195   %1 = fcmp ord double %a, %b
196   %2 = select i1 %1, double %c, double %d
197   ret double %2
198 }
199
200 define float @select_fcmp_uno_f32(float %a, float %b, float %c, float %d) {
201 ; CHECK-LABEL: select_fcmp_uno_f32
202 ; CHECK:       cmpunordss %xmm1, %xmm0
203 ; CHECK-NEXT:  andps      %xmm0, %xmm2
204 ; CHECK-NEXT:  andnps     %xmm3, %xmm0
205 ; CHECK-NEXT:  orps       %xmm2, %xmm0
206 ; AVX-LABEL: select_fcmp_uno_f32
207 ; AVX:       vcmpunordss %xmm1, %xmm0, %xmm0
208 ; AVX-NEXT:  vandps      %xmm2, %xmm0, %xmm1
209 ; AVX-NEXT:  vandnps     %xmm3, %xmm0, %xmm0
210 ; AVX-NEXT:  vorps       %xmm1, %xmm0, %xmm0
211   %1 = fcmp uno float %a, %b
212   %2 = select i1 %1, float %c, float %d
213   ret float %2
214 }
215
216 define double @select_fcmp_uno_f64(double %a, double %b, double %c, double %d) {
217 ; CHECK-LABEL: select_fcmp_uno_f64
218 ; CHECK:       cmpunordsd %xmm1, %xmm0
219 ; CHECK-NEXT:  andpd      %xmm0, %xmm2
220 ; CHECK-NEXT:  andnpd     %xmm3, %xmm0
221 ; CHECK-NEXT:  orpd       %xmm2, %xmm0
222 ; AVX-LABEL: select_fcmp_uno_f64
223 ; AVX:       vcmpunordsd %xmm1, %xmm0, %xmm0
224 ; AVX-NEXT:  vandpd      %xmm2, %xmm0, %xmm1
225 ; AVX-NEXT:  vandnpd     %xmm3, %xmm0, %xmm0
226 ; AVX-NEXT:  vorpd       %xmm1, %xmm0, %xmm0
227   %1 = fcmp uno double %a, %b
228   %2 = select i1 %1, double %c, double %d
229   ret double %2
230 }
231
232 define float @select_fcmp_ugt_f32(float %a, float %b, float %c, float %d) {
233 ; CHECK-LABEL: select_fcmp_ugt_f32
234 ; CHECK:       cmpnless %xmm1, %xmm0
235 ; CHECK-NEXT:  andps    %xmm0, %xmm2
236 ; CHECK-NEXT:  andnps   %xmm3, %xmm0
237 ; CHECK-NEXT:  orps     %xmm2, %xmm0
238 ; AVX-LABEL: select_fcmp_ugt_f32
239 ; AVX:       vcmpnless %xmm1, %xmm0, %xmm0
240 ; AVX-NEXT:  vandps    %xmm2, %xmm0, %xmm1
241 ; AVX-NEXT:  vandnps   %xmm3, %xmm0, %xmm0
242 ; AVX-NEXT:  vorps     %xmm1, %xmm0, %xmm0
243   %1 = fcmp ugt float %a, %b
244   %2 = select i1 %1, float %c, float %d
245   ret float %2
246 }
247
248 define double @select_fcmp_ugt_f64(double %a, double %b, double %c, double %d) {
249 ; CHECK-LABEL: select_fcmp_ugt_f64
250 ; CHECK:       cmpnlesd %xmm1, %xmm0
251 ; CHECK-NEXT:  andpd    %xmm0, %xmm2
252 ; CHECK-NEXT:  andnpd   %xmm3, %xmm0
253 ; CHECK-NEXT:  orpd     %xmm2, %xmm0
254 ; AVX-LABEL: select_fcmp_ugt_f64
255 ; AVX:       vcmpnlesd %xmm1, %xmm0, %xmm0
256 ; AVX-NEXT:  vandpd    %xmm2, %xmm0, %xmm1
257 ; AVX-NEXT:  vandnpd   %xmm3, %xmm0, %xmm0
258 ; AVX-NEXT:  vorpd     %xmm1, %xmm0, %xmm0
259   %1 = fcmp ugt double %a, %b
260   %2 = select i1 %1, double %c, double %d
261   ret double %2
262 }
263
264 define float @select_fcmp_uge_f32(float %a, float %b, float %c, float %d) {
265 ; CHECK-LABEL: select_fcmp_uge_f32
266 ; CHECK:       cmpnltss %xmm1, %xmm0
267 ; CHECK-NEXT:  andps    %xmm0, %xmm2
268 ; CHECK-NEXT:  andnps   %xmm3, %xmm0
269 ; CHECK-NEXT:  orps     %xmm2, %xmm0
270 ; AVX-LABEL: select_fcmp_uge_f32
271 ; AVX:       vcmpnltss %xmm1, %xmm0, %xmm0
272 ; AVX-NEXT:  vandps    %xmm2, %xmm0, %xmm1
273 ; AVX-NEXT:  vandnps   %xmm3, %xmm0, %xmm0
274 ; AVX-NEXT:  vorps     %xmm1, %xmm0, %xmm0
275   %1 = fcmp uge float %a, %b
276   %2 = select i1 %1, float %c, float %d
277   ret float %2
278 }
279
280 define double @select_fcmp_uge_f64(double %a, double %b, double %c, double %d) {
281 ; CHECK-LABEL: select_fcmp_uge_f64
282 ; CHECK:       cmpnltsd %xmm1, %xmm0
283 ; CHECK-NEXT:  andpd    %xmm0, %xmm2
284 ; CHECK-NEXT:  andnpd   %xmm3, %xmm0
285 ; CHECK-NEXT:  orpd     %xmm2, %xmm0
286 ; AVX-LABEL: select_fcmp_uge_f64
287 ; AVX:       vcmpnltsd %xmm1, %xmm0, %xmm0
288 ; AVX-NEXT:  vandpd    %xmm2, %xmm0, %xmm1
289 ; AVX-NEXT:  vandnpd   %xmm3, %xmm0, %xmm0
290 ; AVX-NEXT:  vorpd     %xmm1, %xmm0, %xmm0
291   %1 = fcmp uge double %a, %b
292   %2 = select i1 %1, double %c, double %d
293   ret double %2
294 }
295
296 define float @select_fcmp_ult_f32(float %a, float %b, float %c, float %d) {
297 ; CHECK-LABEL: select_fcmp_ult_f32
298 ; CHECK:       cmpnless %xmm0, %xmm1
299 ; CHECK-NEXT:  andps    %xmm1, %xmm2
300 ; CHECK-NEXT:  andnps   %xmm3, %xmm1
301 ; CHECK-NEXT:  orps     %xmm2, %xmm1
302 ; AVX-LABEL: select_fcmp_ult_f32
303 ; AVX:       vcmpnless %xmm0, %xmm1, %xmm0
304 ; AVX-NEXT:  vandps    %xmm2, %xmm0, %xmm1
305 ; AVX-NEXT:  vandnps   %xmm3, %xmm0, %xmm0
306 ; AVX-NEXT:  vorps     %xmm1, %xmm0, %xmm0
307   %1 = fcmp ult float %a, %b
308   %2 = select i1 %1, float %c, float %d
309   ret float %2
310 }
311
312 define double @select_fcmp_ult_f64(double %a, double %b, double %c, double %d) {
313 ; CHECK-LABEL: select_fcmp_ult_f64
314 ; CHECK:       cmpnlesd %xmm0, %xmm1
315 ; CHECK-NEXT:  andpd    %xmm1, %xmm2
316 ; CHECK-NEXT:  andnpd   %xmm3, %xmm1
317 ; CHECK-NEXT:  orpd     %xmm2, %xmm1
318 ; AVX-LABEL: select_fcmp_ult_f64
319 ; AVX:       vcmpnlesd %xmm0, %xmm1, %xmm0
320 ; AVX-NEXT:  vandpd    %xmm2, %xmm0, %xmm1
321 ; AVX-NEXT:  vandnpd   %xmm3, %xmm0, %xmm0
322 ; AVX-NEXT:  vorpd     %xmm1, %xmm0, %xmm0
323   %1 = fcmp ult double %a, %b
324   %2 = select i1 %1, double %c, double %d
325   ret double %2
326 }
327
328 define float @select_fcmp_ule_f32(float %a, float %b, float %c, float %d) {
329 ; CHECK-LABEL: select_fcmp_ule_f32
330 ; CHECK:       cmpnltss %xmm0, %xmm1
331 ; CHECK-NEXT:  andps    %xmm1, %xmm2
332 ; CHECK-NEXT:  andnps   %xmm3, %xmm1
333 ; CHECK-NEXT:  orps     %xmm2, %xmm1
334 ; AVX-LABEL: select_fcmp_ule_f32
335 ; AVX:       vcmpnltss %xmm0, %xmm1, %xmm0
336 ; AVX-NEXT:  vandps    %xmm2, %xmm0, %xmm1
337 ; AVX-NEXT:  vandnps   %xmm3, %xmm0, %xmm0
338 ; AVX-NEXT:  vorps     %xmm1, %xmm0, %xmm0
339   %1 = fcmp ule float %a, %b
340   %2 = select i1 %1, float %c, float %d
341   ret float %2
342 }
343
344 define double @select_fcmp_ule_f64(double %a, double %b, double %c, double %d) {
345 ; CHECK-LABEL: select_fcmp_ule_f64
346 ; CHECK:       cmpnltsd %xmm0, %xmm1
347 ; CHECK-NEXT:  andpd    %xmm1, %xmm2
348 ; CHECK-NEXT:  andnpd   %xmm3, %xmm1
349 ; CHECK-NEXT:  orpd     %xmm2, %xmm1
350 ; AVX-LABEL: select_fcmp_ule_f64
351 ; AVX:       vcmpnltsd %xmm0, %xmm1, %xmm0
352 ; AVX-NEXT:  vandpd    %xmm2, %xmm0, %xmm1
353 ; AVX-NEXT:  vandnpd   %xmm3, %xmm0, %xmm0
354 ; AVX-NEXT:  vorpd     %xmm1, %xmm0, %xmm0
355   %1 = fcmp ule double %a, %b
356   %2 = select i1 %1, double %c, double %d
357   ret double %2
358 }
359
360 define float @select_fcmp_une_f32(float %a, float %b, float %c, float %d) {
361 ; CHECK-LABEL: select_fcmp_une_f32
362 ; CHECK:       cmpneqss %xmm1, %xmm0
363 ; CHECK-NEXT:  andps    %xmm0, %xmm2
364 ; CHECK-NEXT:  andnps   %xmm3, %xmm0
365 ; CHECK-NEXT:  orps     %xmm2, %xmm0
366 ; AVX-LABEL: select_fcmp_une_f32
367 ; AVX:       vcmpneqss %xmm1, %xmm0, %xmm0
368 ; AVX-NEXT:  vandps    %xmm2, %xmm0, %xmm1
369 ; AVX-NEXT:  vandnps   %xmm3, %xmm0, %xmm0
370 ; AVX-NEXT:  vorps     %xmm1, %xmm0, %xmm0
371   %1 = fcmp une float %a, %b
372   %2 = select i1 %1, float %c, float %d
373   ret float %2
374 }
375
376 define double @select_fcmp_une_f64(double %a, double %b, double %c, double %d) {
377 ; CHECK-LABEL: select_fcmp_une_f64
378 ; CHECK:       cmpneqsd %xmm1, %xmm0
379 ; CHECK-NEXT:  andpd    %xmm0, %xmm2
380 ; CHECK-NEXT:  andnpd   %xmm3, %xmm0
381 ; CHECK-NEXT:  orpd     %xmm2, %xmm0
382 ; AVX-LABEL: select_fcmp_une_f64
383 ; AVX:       vcmpneqsd %xmm1, %xmm0, %xmm0
384 ; AVX-NEXT:  vandpd    %xmm2, %xmm0, %xmm1
385 ; AVX-NEXT:  vandnpd   %xmm3, %xmm0, %xmm0
386 ; AVX-NEXT:  vorpd     %xmm1, %xmm0, %xmm0
387   %1 = fcmp une double %a, %b
388   %2 = select i1 %1, double %c, double %d
389   ret double %2
390 }
391