1 ; RUN: llc < %s -mtriple=ve | FileCheck %s
3 ;;; Test ‘select’ instruction
6 ;;; <result> = select [fast-math flags] selty <cond>, <ty> <val1>, <ty> <val2>
9 ;;; selty is either i1 or {<N x i1>}
12 ;;; The ‘select’ instruction is used to choose one value based on a condition,
13 ;;; without IR-level branching.
16 ;;; The ‘select’ instruction requires an ‘i1’ value or a vector of ‘i1’ values
17 ;;; indicating the condition, and two values of the same first class type.
19 ;;; The optional fast-math flags marker indicates that the select has one or
20 ;;; more fast-math flags. These are optimization hints to enable otherwise
21 ;;; unsafe floating-point optimizations. Fast-math flags are only valid for
22 ;;; selects that return a floating-point scalar or vector type, or an array
23 ;;; (nested to any depth) of floating-point scalar or vector types.
26 ;;; If the condition is an i1 and it evaluates to 1, the instruction returns
27 ;;; the first value argument; otherwise, it returns the second value argument.
29 ;;; If the condition is a vector of i1, then the value arguments must be
30 ;;; vectors of the same size, and the selection is done element by element.
32 ;;; If the condition is an i1 and the value arguments are vectors of the same
33 ;;; size, then an entire vector is selected.
36 ;;; %X = select i1 true, i8 17, i8 42 ; yields i8:17
39 ;;; We test only i1/i8/u8/i16/u16/i32/u32/i64/u64/i128/u128/float/double/fp128
41 ; Function Attrs: norecurse nounwind readnone
42 define zeroext i1 @select_i1_var(i1 zeroext %0, i1 zeroext %1, i1 zeroext %2) {
43 ; CHECK-LABEL: select_i1_var:
45 ; CHECK-NEXT: cmov.w.ne %s2, %s1, %s0
46 ; CHECK-NEXT: adds.w.zx %s0, %s2, (0)1
47 ; CHECK-NEXT: b.l.t (, %s10)
48 %4 = select i1 %0, i1 %1, i1 %2
52 ; Function Attrs: norecurse nounwind readnone
53 define signext i8 @select_i8_var(i1 zeroext %0, i8 signext %1, i8 signext %2) {
54 ; CHECK-LABEL: select_i8_var:
56 ; CHECK-NEXT: cmov.w.ne %s2, %s1, %s0
57 ; CHECK-NEXT: adds.w.sx %s0, %s2, (0)1
58 ; CHECK-NEXT: b.l.t (, %s10)
59 %4 = select i1 %0, i8 %1, i8 %2
63 ; Function Attrs: norecurse nounwind readnone
64 define zeroext i8 @select_u8_var(i1 zeroext %0, i8 zeroext %1, i8 zeroext %2) {
65 ; CHECK-LABEL: select_u8_var:
67 ; CHECK-NEXT: cmov.w.ne %s2, %s1, %s0
68 ; CHECK-NEXT: adds.w.zx %s0, %s2, (0)1
69 ; CHECK-NEXT: b.l.t (, %s10)
70 %4 = select i1 %0, i8 %1, i8 %2
74 ; Function Attrs: norecurse nounwind readnone
75 define signext i16 @select_i16_var(i1 zeroext %0, i16 signext %1, i16 signext %2) {
76 ; CHECK-LABEL: select_i16_var:
78 ; CHECK-NEXT: cmov.w.ne %s2, %s1, %s0
79 ; CHECK-NEXT: adds.w.sx %s0, %s2, (0)1
80 ; CHECK-NEXT: b.l.t (, %s10)
81 %4 = select i1 %0, i16 %1, i16 %2
85 ; Function Attrs: norecurse nounwind readnone
86 define zeroext i16 @select_u16_var(i1 zeroext %0, i16 zeroext %1, i16 zeroext %2) {
87 ; CHECK-LABEL: select_u16_var:
89 ; CHECK-NEXT: cmov.w.ne %s2, %s1, %s0
90 ; CHECK-NEXT: adds.w.zx %s0, %s2, (0)1
91 ; CHECK-NEXT: b.l.t (, %s10)
92 %4 = select i1 %0, i16 %1, i16 %2
96 ; Function Attrs: norecurse nounwind readnone
97 define signext i32 @select_i32_var(i1 zeroext %0, i32 signext %1, i32 signext %2) {
98 ; CHECK-LABEL: select_i32_var:
100 ; CHECK-NEXT: cmov.w.ne %s2, %s1, %s0
101 ; CHECK-NEXT: adds.w.sx %s0, %s2, (0)1
102 ; CHECK-NEXT: b.l.t (, %s10)
103 %4 = select i1 %0, i32 %1, i32 %2
107 ; Function Attrs: norecurse nounwind readnone
108 define zeroext i32 @select_u32_var(i1 zeroext %0, i32 zeroext %1, i32 zeroext %2) {
109 ; CHECK-LABEL: select_u32_var:
111 ; CHECK-NEXT: cmov.w.ne %s2, %s1, %s0
112 ; CHECK-NEXT: adds.w.zx %s0, %s2, (0)1
113 ; CHECK-NEXT: b.l.t (, %s10)
114 %4 = select i1 %0, i32 %1, i32 %2
118 ; Function Attrs: norecurse nounwind readnone
119 define i64 @select_i64_var(i1 zeroext %0, i64 %1, i64 %2) {
120 ; CHECK-LABEL: select_i64_var:
122 ; CHECK-NEXT: cmov.w.ne %s2, %s1, %s0
123 ; CHECK-NEXT: or %s0, 0, %s2
124 ; CHECK-NEXT: b.l.t (, %s10)
125 %4 = select i1 %0, i64 %1, i64 %2
129 ; Function Attrs: norecurse nounwind readnone
130 define i64 @select_u64_var(i1 zeroext %0, i64 %1, i64 %2) {
131 ; CHECK-LABEL: select_u64_var:
133 ; CHECK-NEXT: cmov.w.ne %s2, %s1, %s0
134 ; CHECK-NEXT: or %s0, 0, %s2
135 ; CHECK-NEXT: b.l.t (, %s10)
136 %4 = select i1 %0, i64 %1, i64 %2
140 ; Function Attrs: norecurse nounwind readnone
141 define i128 @select_i128_var(i1 zeroext %0, i128 %1, i128 %2) {
142 ; CHECK-LABEL: select_i128_var:
144 ; CHECK-NEXT: cmov.w.ne %s3, %s1, %s0
145 ; CHECK-NEXT: cmov.w.ne %s4, %s2, %s0
146 ; CHECK-NEXT: or %s0, 0, %s3
147 ; CHECK-NEXT: or %s1, 0, %s4
148 ; CHECK-NEXT: b.l.t (, %s10)
149 %4 = select i1 %0, i128 %1, i128 %2
153 ; Function Attrs: norecurse nounwind readnone
154 define i128 @select_u128_var(i1 zeroext %0, i128 %1, i128 %2) {
155 ; CHECK-LABEL: select_u128_var:
157 ; CHECK-NEXT: cmov.w.ne %s3, %s1, %s0
158 ; CHECK-NEXT: cmov.w.ne %s4, %s2, %s0
159 ; CHECK-NEXT: or %s0, 0, %s3
160 ; CHECK-NEXT: or %s1, 0, %s4
161 ; CHECK-NEXT: b.l.t (, %s10)
162 %4 = select i1 %0, i128 %1, i128 %2
166 ; Function Attrs: norecurse nounwind readnone
167 define float @select_float_var(i1 zeroext %0, float %1, float %2) {
168 ; CHECK-LABEL: select_float_var:
170 ; CHECK-NEXT: cmov.w.ne %s2, %s1, %s0
171 ; CHECK-NEXT: or %s0, 0, %s2
172 ; CHECK-NEXT: b.l.t (, %s10)
173 %4 = select fast i1 %0, float %1, float %2
177 ; Function Attrs: norecurse nounwind readnone
178 define double @select_double_var(i1 zeroext %0, double %1, double %2) {
179 ; CHECK-LABEL: select_double_var:
181 ; CHECK-NEXT: cmov.w.ne %s2, %s1, %s0
182 ; CHECK-NEXT: or %s0, 0, %s2
183 ; CHECK-NEXT: b.l.t (, %s10)
184 %4 = select fast i1 %0, double %1, double %2
188 ; Function Attrs: norecurse nounwind readnone
189 define fp128 @select_quad_var(i1 zeroext %0, fp128 %1, fp128 %2) {
190 ; CHECK-LABEL: select_quad_var:
192 ; CHECK-NEXT: cmov.w.ne %s4, %s2, %s0
193 ; CHECK-NEXT: cmov.w.ne %s5, %s3, %s0
194 ; CHECK-NEXT: or %s0, 0, %s4
195 ; CHECK-NEXT: or %s1, 0, %s5
196 ; CHECK-NEXT: b.l.t (, %s10)
197 %4 = select fast i1 %0, fp128 %1, fp128 %2
201 ; Function Attrs: norecurse nounwind readnone
202 define zeroext i1 @select_i1_mimm(i1 zeroext %0, i1 zeroext %1) {
203 ; CHECK-LABEL: select_i1_mimm:
205 ; CHECK-NEXT: or %s0, %s0, %s1
206 ; CHECK-NEXT: b.l.t (, %s10)
211 ; Function Attrs: norecurse nounwind readnone
212 define signext i8 @select_i8_mimm(i1 zeroext %0, i8 signext %1) {
213 ; CHECK-LABEL: select_i8_mimm:
215 ; CHECK-NEXT: cmov.w.ne %s1, (57)1, %s0
216 ; CHECK-NEXT: adds.w.sx %s0, %s1, (0)1
217 ; CHECK-NEXT: b.l.t (, %s10)
218 %3 = select i1 %0, i8 -128, i8 %1
222 ; Function Attrs: norecurse nounwind readnone
223 define zeroext i8 @select_u8_mimm(i1 zeroext %0, i8 zeroext %1) {
224 ; CHECK-LABEL: select_u8_mimm:
226 ; CHECK-NEXT: cmov.w.ne %s1, (57)0, %s0
227 ; CHECK-NEXT: adds.w.zx %s0, %s1, (0)1
228 ; CHECK-NEXT: b.l.t (, %s10)
229 %3 = select i1 %0, i8 127, i8 %1
233 ; Function Attrs: norecurse nounwind readnone
234 define signext i16 @select_i16_mimm(i1 zeroext %0, i16 signext %1) {
235 ; CHECK-LABEL: select_i16_mimm:
237 ; CHECK-NEXT: cmov.w.ne %s1, (49)1, %s0
238 ; CHECK-NEXT: adds.w.sx %s0, %s1, (0)1
239 ; CHECK-NEXT: b.l.t (, %s10)
240 %3 = select i1 %0, i16 -32768, i16 %1
244 ; Function Attrs: norecurse nounwind readnone
245 define zeroext i16 @select_u16_mimm(i1 zeroext %0, i16 zeroext %1) {
246 ; CHECK-LABEL: select_u16_mimm:
248 ; CHECK-NEXT: cmov.w.ne %s1, (49)0, %s0
249 ; CHECK-NEXT: adds.w.zx %s0, %s1, (0)1
250 ; CHECK-NEXT: b.l.t (, %s10)
251 %3 = select i1 %0, i16 32767, i16 %1
255 ; Function Attrs: norecurse nounwind readnone
256 define signext i32 @select_i32_mimm(i1 zeroext %0, i32 signext %1) {
257 ; CHECK-LABEL: select_i32_mimm:
259 ; CHECK-NEXT: cmov.w.ne %s1, (48)0, %s0
260 ; CHECK-NEXT: adds.w.sx %s0, %s1, (0)1
261 ; CHECK-NEXT: b.l.t (, %s10)
262 %3 = select i1 %0, i32 65535, i32 %1
266 ; Function Attrs: norecurse nounwind readnone
267 define zeroext i32 @select_u32_mimm(i1 zeroext %0, i32 zeroext %1) {
268 ; CHECK-LABEL: select_u32_mimm:
270 ; CHECK-NEXT: cmov.w.ne %s1, (48)0, %s0
271 ; CHECK-NEXT: adds.w.zx %s0, %s1, (0)1
272 ; CHECK-NEXT: b.l.t (, %s10)
273 %3 = select i1 %0, i32 65535, i32 %1
277 ; Function Attrs: norecurse nounwind readnone
278 define i64 @select_i64_mimm(i1 zeroext %0, i64 %1) {
279 ; CHECK-LABEL: select_i64_mimm:
281 ; CHECK-NEXT: cmov.w.ne %s1, (48)0, %s0
282 ; CHECK-NEXT: or %s0, 0, %s1
283 ; CHECK-NEXT: b.l.t (, %s10)
284 %3 = select i1 %0, i64 65535, i64 %1
288 ; Function Attrs: norecurse nounwind readnone
289 define i64 @select_u64_mimm(i1 zeroext %0, i64 %1) {
290 ; CHECK-LABEL: select_u64_mimm:
292 ; CHECK-NEXT: cmov.w.ne %s1, (48)0, %s0
293 ; CHECK-NEXT: or %s0, 0, %s1
294 ; CHECK-NEXT: b.l.t (, %s10)
295 %3 = select i1 %0, i64 65535, i64 %1
299 ; Function Attrs: norecurse nounwind readnone
300 define i128 @select_i128_mimm(i1 zeroext %0, i128 %1) {
301 ; CHECK-LABEL: select_i128_mimm:
303 ; CHECK-NEXT: cmov.w.ne %s1, (48)0, %s0
304 ; CHECK-NEXT: cmov.w.ne %s2, (0)1, %s0
305 ; CHECK-NEXT: or %s0, 0, %s1
306 ; CHECK-NEXT: or %s1, 0, %s2
307 ; CHECK-NEXT: b.l.t (, %s10)
308 %3 = select i1 %0, i128 65535, i128 %1
312 ; Function Attrs: norecurse nounwind readnone
313 define i128 @select_u128_mimm(i1 zeroext %0, i128 %1) {
314 ; CHECK-LABEL: select_u128_mimm:
316 ; CHECK-NEXT: cmov.w.ne %s1, (48)0, %s0
317 ; CHECK-NEXT: cmov.w.ne %s2, (0)1, %s0
318 ; CHECK-NEXT: or %s0, 0, %s1
319 ; CHECK-NEXT: or %s1, 0, %s2
320 ; CHECK-NEXT: b.l.t (, %s10)
321 %3 = select i1 %0, i128 65535, i128 %1
325 ; Function Attrs: norecurse nounwind readnone
326 define float @select_float_mimm(i1 zeroext %0, float %1) {
327 ; CHECK-LABEL: select_float_mimm:
329 ; CHECK-NEXT: cmov.w.ne %s1, (2)1, %s0
330 ; CHECK-NEXT: or %s0, 0, %s1
331 ; CHECK-NEXT: b.l.t (, %s10)
332 %3 = select i1 %0, float -2.000000e+00, float %1
336 ; Function Attrs: norecurse nounwind readnone
337 define double @select_double_mimm(i1 zeroext %0, double %1) {
338 ; CHECK-LABEL: select_double_mimm:
340 ; CHECK-NEXT: cmov.w.ne %s1, (2)1, %s0
341 ; CHECK-NEXT: or %s0, 0, %s1
342 ; CHECK-NEXT: b.l.t (, %s10)
343 %3 = select fast i1 %0, double -2.000000e+00, double %1
347 ; Function Attrs: norecurse nounwind readnone
348 define fp128 @select_quad_mimm(i1 zeroext %0, fp128 %1) {
349 ; CHECK-LABEL: select_quad_mimm:
351 ; CHECK-NEXT: lea %s1, .LCPI{{[0-9]+}}_0@lo
352 ; CHECK-NEXT: and %s1, %s1, (32)0
353 ; CHECK-NEXT: lea.sl %s1, .LCPI{{[0-9]+}}_0@hi(, %s1)
354 ; CHECK-NEXT: ld %s4, 8(, %s1)
355 ; CHECK-NEXT: ld %s5, (, %s1)
356 ; CHECK-NEXT: cmov.w.ne %s2, %s4, %s0
357 ; CHECK-NEXT: cmov.w.ne %s3, %s5, %s0
358 ; CHECK-NEXT: or %s0, 0, %s2
359 ; CHECK-NEXT: or %s1, 0, %s3
360 ; CHECK-NEXT: b.l.t (, %s10)
361 %3 = select fast i1 %0, fp128 0xL0000000000000000C000000000000000, fp128 %1
365 ; Function Attrs: norecurse nounwind readnone
366 define zeroext i1 @select_mimm_i1(i1 zeroext %0, i1 zeroext %1) {
367 ; CHECK-LABEL: select_mimm_i1:
369 ; CHECK-NEXT: xor %s0, 1, %s0
370 ; CHECK-NEXT: or %s0, %s0, %s1
371 ; CHECK-NEXT: b.l.t (, %s10)
377 ; Function Attrs: norecurse nounwind readnone
378 define signext i8 @select_mimm_i8(i1 zeroext %0, i8 signext %1) {
379 ; CHECK-LABEL: select_mimm_i8:
381 ; CHECK-NEXT: cmov.w.eq %s1, (57)1, %s0
382 ; CHECK-NEXT: adds.w.sx %s0, %s1, (0)1
383 ; CHECK-NEXT: b.l.t (, %s10)
384 %3 = select i1 %0, i8 %1, i8 -128
388 ; Function Attrs: norecurse nounwind readnone
389 define zeroext i8 @select_mimm_u8(i1 zeroext %0, i8 zeroext %1) {
390 ; CHECK-LABEL: select_mimm_u8:
392 ; CHECK-NEXT: cmov.w.eq %s1, (57)0, %s0
393 ; CHECK-NEXT: adds.w.zx %s0, %s1, (0)1
394 ; CHECK-NEXT: b.l.t (, %s10)
395 %3 = select i1 %0, i8 %1, i8 127
399 ; Function Attrs: norecurse nounwind readnone
400 define signext i16 @select_mimm_i16(i1 zeroext %0, i16 signext %1) {
401 ; CHECK-LABEL: select_mimm_i16:
403 ; CHECK-NEXT: cmov.w.eq %s1, (49)1, %s0
404 ; CHECK-NEXT: adds.w.sx %s0, %s1, (0)1
405 ; CHECK-NEXT: b.l.t (, %s10)
406 %3 = select i1 %0, i16 %1, i16 -32768
410 ; Function Attrs: norecurse nounwind readnone
411 define zeroext i16 @select_mimm_u16(i1 zeroext %0, i16 zeroext %1) {
412 ; CHECK-LABEL: select_mimm_u16:
414 ; CHECK-NEXT: cmov.w.eq %s1, (49)0, %s0
415 ; CHECK-NEXT: adds.w.zx %s0, %s1, (0)1
416 ; CHECK-NEXT: b.l.t (, %s10)
417 %3 = select i1 %0, i16 %1, i16 32767
421 ; Function Attrs: norecurse nounwind readnone
422 define signext i32 @select_mimm_i32(i1 zeroext %0, i32 signext %1) {
423 ; CHECK-LABEL: select_mimm_i32:
425 ; CHECK-NEXT: cmov.w.eq %s1, (48)0, %s0
426 ; CHECK-NEXT: adds.w.sx %s0, %s1, (0)1
427 ; CHECK-NEXT: b.l.t (, %s10)
428 %3 = select i1 %0, i32 %1, i32 65535
432 ; Function Attrs: norecurse nounwind readnone
433 define zeroext i32 @select_mimm_u32(i1 zeroext %0, i32 zeroext %1) {
434 ; CHECK-LABEL: select_mimm_u32:
436 ; CHECK-NEXT: cmov.w.eq %s1, (48)0, %s0
437 ; CHECK-NEXT: adds.w.zx %s0, %s1, (0)1
438 ; CHECK-NEXT: b.l.t (, %s10)
439 %3 = select i1 %0, i32 %1, i32 65535
443 ; Function Attrs: norecurse nounwind readnone
444 define i64 @select_mimm_i64(i1 zeroext %0, i64 %1) {
445 ; CHECK-LABEL: select_mimm_i64:
447 ; CHECK-NEXT: cmov.w.eq %s1, (48)0, %s0
448 ; CHECK-NEXT: or %s0, 0, %s1
449 ; CHECK-NEXT: b.l.t (, %s10)
450 %3 = select i1 %0, i64 %1, i64 65535
454 ; Function Attrs: norecurse nounwind readnone
455 define i64 @select_mimm_u64(i1 zeroext %0, i64 %1) {
456 ; CHECK-LABEL: select_mimm_u64:
458 ; CHECK-NEXT: cmov.w.eq %s1, (48)0, %s0
459 ; CHECK-NEXT: or %s0, 0, %s1
460 ; CHECK-NEXT: b.l.t (, %s10)
461 %3 = select i1 %0, i64 %1, i64 65535
465 ; Function Attrs: norecurse nounwind readnone
466 define i128 @select_mimm_i128(i1 zeroext %0, i128 %1) {
467 ; CHECK-LABEL: select_mimm_i128:
469 ; CHECK-NEXT: cmov.w.eq %s1, (48)0, %s0
470 ; CHECK-NEXT: cmov.w.eq %s2, (0)1, %s0
471 ; CHECK-NEXT: or %s0, 0, %s1
472 ; CHECK-NEXT: or %s1, 0, %s2
473 ; CHECK-NEXT: b.l.t (, %s10)
474 %3 = select i1 %0, i128 %1, i128 65535
478 ; Function Attrs: norecurse nounwind readnone
479 define i128 @select_mimm_u128(i1 zeroext %0, i128 %1) {
480 ; CHECK-LABEL: select_mimm_u128:
482 ; CHECK-NEXT: cmov.w.eq %s1, (48)0, %s0
483 ; CHECK-NEXT: cmov.w.eq %s2, (0)1, %s0
484 ; CHECK-NEXT: or %s0, 0, %s1
485 ; CHECK-NEXT: or %s1, 0, %s2
486 ; CHECK-NEXT: b.l.t (, %s10)
487 %3 = select i1 %0, i128 %1, i128 65535
491 ; Function Attrs: norecurse nounwind readnone
492 define float @select_mimm_float(i1 zeroext %0, float %1) {
493 ; CHECK-LABEL: select_mimm_float:
495 ; CHECK-NEXT: cmov.w.eq %s1, (2)1, %s0
496 ; CHECK-NEXT: or %s0, 0, %s1
497 ; CHECK-NEXT: b.l.t (, %s10)
498 %3 = select i1 %0, float %1, float -2.000000e+00
502 ; Function Attrs: norecurse nounwind readnone
503 define double @select_mimm_double(i1 zeroext %0, double %1) {
504 ; CHECK-LABEL: select_mimm_double:
506 ; CHECK-NEXT: cmov.w.eq %s1, (2)1, %s0
507 ; CHECK-NEXT: or %s0, 0, %s1
508 ; CHECK-NEXT: b.l.t (, %s10)
509 %3 = select fast i1 %0, double %1, double -2.000000e+00
513 ; Function Attrs: norecurse nounwind readnone
514 define fp128 @select_mimm_quad(i1 zeroext %0, fp128 %1) {
515 ; CHECK-LABEL: select_mimm_quad:
517 ; CHECK-NEXT: lea %s1, .LCPI{{[0-9]+}}_0@lo
518 ; CHECK-NEXT: and %s1, %s1, (32)0
519 ; CHECK-NEXT: lea.sl %s1, .LCPI{{[0-9]+}}_0@hi(, %s1)
520 ; CHECK-NEXT: ld %s4, 8(, %s1)
521 ; CHECK-NEXT: ld %s5, (, %s1)
522 ; CHECK-NEXT: cmov.w.ne %s4, %s2, %s0
523 ; CHECK-NEXT: cmov.w.ne %s5, %s3, %s0
524 ; CHECK-NEXT: or %s0, 0, %s4
525 ; CHECK-NEXT: or %s1, 0, %s5
526 ; CHECK-NEXT: b.l.t (, %s10)
527 %3 = select fast i1 %0, fp128 %1, fp128 0xL0000000000000000C000000000000000