1 /*
2 * Copyright (c) 2022, Arm Limited. All rights reserved.
3 * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25 package compiler.c2.irTests;
26
27 import compiler.lib.ir_framework.*;
28 import java.util.Random;
29 import jdk.test.lib.Asserts;
30 import jdk.test.lib.Utils;
31
32 /*
33 * @test
34 * @bug 8289422 8306088 8313720
35 * @key randomness
36 * @summary Auto-vectorization enhancement to support vector conditional move.
37 * @library /test/lib /
38 * @run driver compiler.c2.irTests.TestVectorConditionalMove
39 */
40
41 public class TestVectorConditionalMove {
42 final private static int SIZE = 1024;
43 private static final Random RANDOM = Utils.getRandomInstance();
44
45 public static void main(String[] args) {
46 // Cross-product: +-AlignVector and +-UseCompactObjectHeaders
47 TestFramework.runWithFlags("-XX:+UseCMoveUnconditionally", "-XX:+UseVectorCmov",
48 "-XX:-UseCompactObjectHeaders", "-XX:-AlignVector");
49 TestFramework.runWithFlags("-XX:+UseCMoveUnconditionally", "-XX:+UseVectorCmov",
50 "-XX:-UseCompactObjectHeaders", "-XX:+AlignVector");
51 TestFramework.runWithFlags("-XX:+UseCMoveUnconditionally", "-XX:+UseVectorCmov",
52 "-XX:+UseCompactObjectHeaders", "-XX:-AlignVector");
53 TestFramework.runWithFlags("-XX:+UseCMoveUnconditionally", "-XX:+UseVectorCmov",
54 "-XX:+UseCompactObjectHeaders", "-XX:+AlignVector");
55 }
56
57 // Compare 2 values, and pick one of them
58 private float cmoveFloatGT(float a, float b) {
59 return (a > b) ? a : b;
60 }
61
62 private float cmoveFloatGTSwap(float a, float b) {
63 return (b > a) ? a : b;
64 }
65
66 private float cmoveFloatLT(float a, float b) {
67 return (a < b) ? a : b;
68 }
69
70 private float cmoveFloatLTSwap(float a, float b) {
71 return (b < a) ? a : b;
72 }
73
74 private float cmoveFloatEQ(float a, float b) {
75 return (a == b) ? a : b;
76 }
77
78 private double cmoveDoubleLE(double a, double b) {
79 return (a <= b) ? a : b;
80 }
81
82 private double cmoveDoubleLESwap(double a, double b) {
83 return (b <= a) ? a : b;
84 }
85
86 private double cmoveDoubleGE(double a, double b) {
87 return (a >= b) ? a : b;
88 }
89
90 private double cmoveDoubleGESwap(double a, double b) {
91 return (b >= a) ? a : b;
92 }
93
94 private double cmoveDoubleNE(double a, double b) {
95 return (a != b) ? a : b;
96 }
97
98 // Extensions: compare 2 values, and pick from 2 consts
99 private float cmoveFGTforFConst(float a, float b) {
100 return (a > b) ? 0.1f : -0.1f;
101 }
102
103 private float cmoveFGEforFConst(float a, float b) {
104 return (a >= b) ? 0.1f : -0.1f;
105 }
106
107 private float cmoveFLTforFConst(float a, float b) {
108 return (a < b) ? 0.1f : -0.1f;
109 }
110
111 private float cmoveFLEforFConst(float a, float b) {
112 return (a <= b) ? 0.1f : -0.1f;
113 }
114
115 private float cmoveFEQforFConst(float a, float b) {
116 return (a == b) ? 0.1f : -0.1f;
117 }
118
119 private float cmoveFNEQforFConst(float a, float b) {
120 return (a != b) ? 0.1f : -0.1f;
121 }
122
123 private double cmoveDGTforDConst(double a, double b) {
124 return (a > b) ? 0.1 : -0.1;
125 }
126
127 private double cmoveDGEforDConst(double a, double b) {
128 return (a >= b) ? 0.1 : -0.1;
129 }
130
131 private double cmoveDLTforDConst(double a, double b) {
132 return (a < b) ? 0.1 : -0.1;
133 }
134
135 private double cmoveDLEforDConst(double a, double b) {
136 return (a <= b) ? 0.1 : -0.1;
137 }
138
139 private double cmoveDEQforDConst(double a, double b) {
140 return (a == b) ? 0.1 : -0.1;
141 }
142
143 private double cmoveDNEQforDConst(double a, double b) {
144 return (a != b) ? 0.1 : -0.1;
145 }
146
147 // Extension: Compare 2 ILFD values, and pick from 2 ILFD values
148 // Signed comparison: I/L
149 // I for I
150 private int cmoveIEQforI(int a, int b, int c, int d) {
151 return (a == b) ? c : d;
152 }
153
154 private int cmoveINEforI(int a, int b, int c, int d) {
155 return (a != b) ? c : d;
156 }
157
158 private int cmoveIGTforI(int a, int b, int c, int d) {
159 return (a > b) ? c : d;
160 }
161
162 private int cmoveIGEforI(int a, int b, int c, int d) {
163 return (a >= b) ? c : d;
164 }
165
166 private int cmoveILTforI(int a, int b, int c, int d) {
167 return (a < b) ? c : d;
168 }
169
170 private int cmoveILEforI(int a, int b, int c, int d) {
171 return (a <= b) ? c : d;
172 }
173
174 // I for L
175 private long cmoveIEQforL(int a, int b, long c, long d) {
176 return (a == b) ? c : d;
177 }
178
179 private long cmoveINEforL(int a, int b, long c, long d) {
180 return (a != b) ? c : d;
181 }
182
183 private long cmoveIGTforL(int a, int b, long c, long d) {
184 return (a > b) ? c : d;
185 }
186
187 private long cmoveIGEforL(int a, int b, long c, long d) {
188 return (a >= b) ? c : d;
189 }
190
191 private long cmoveILTforL(int a, int b, long c, long d) {
192 return (a < b) ? c : d;
193 }
194
195 private long cmoveILEforL(int a, int b, long c, long d) {
196 return (a <= b) ? c : d;
197 }
198
199 // I for F
200 private float cmoveIEQforF(int a, int b, float c, float d) {
201 return (a == b) ? c : d;
202 }
203
204 private float cmoveINEforF(int a, int b, float c, float d) {
205 return (a != b) ? c : d;
206 }
207
208 private float cmoveIGTforF(int a, int b, float c, float d) {
209 return (a > b) ? c : d;
210 }
211
212 private float cmoveIGEforF(int a, int b, float c, float d) {
213 return (a >= b) ? c : d;
214 }
215
216 private float cmoveILTforF(int a, int b, float c, float d) {
217 return (a < b) ? c : d;
218 }
219
220 private float cmoveILEforF(int a, int b, float c, float d) {
221 return (a <= b) ? c : d;
222 }
223
224 // I for D
225 private double cmoveIEQforD(int a, int b, double c, double d) {
226 return (a == b) ? c : d;
227 }
228
229 private double cmoveINEforD(int a, int b, double c, double d) {
230 return (a != b) ? c : d;
231 }
232
233 private double cmoveIGTforD(int a, int b, double c, double d) {
234 return (a > b) ? c : d;
235 }
236
237 private double cmoveIGEforD(int a, int b, double c, double d) {
238 return (a >= b) ? c : d;
239 }
240
241 private double cmoveILTforD(int a, int b, double c, double d) {
242 return (a < b) ? c : d;
243 }
244
245 private double cmoveILEforD(int a, int b, double c, double d) {
246 return (a <= b) ? c : d;
247 }
248
249 // L for I
250 private int cmoveLEQforI(long a, long b, int c, int d) {
251 return (a == b) ? c : d;
252 }
253
254 private int cmoveLNEforI(long a, long b, int c, int d) {
255 return (a != b) ? c : d;
256 }
257
258 private int cmoveLGTforI(long a, long b, int c, int d) {
259 return (a > b) ? c : d;
260 }
261
262 private int cmoveLGEforI(long a, long b, int c, int d) {
263 return (a >= b) ? c : d;
264 }
265
266 private int cmoveLLTforI(long a, long b, int c, int d) {
267 return (a < b) ? c : d;
268 }
269
270 private int cmoveLLEforI(long a, long b, int c, int d) {
271 return (a <= b) ? c : d;
272 }
273
274 // L for L
275 private long cmoveLEQforL(long a, long b, long c, long d) {
276 return (a == b) ? c : d;
277 }
278
279 private long cmoveLNEforL(long a, long b, long c, long d) {
280 return (a != b) ? c : d;
281 }
282
283 private long cmoveLGTforL(long a, long b, long c, long d) {
284 return (a > b) ? c : d;
285 }
286
287 private long cmoveLGEforL(long a, long b, long c, long d) {
288 return (a >= b) ? c : d;
289 }
290
291 private long cmoveLLTforL(long a, long b, long c, long d) {
292 return (a < b) ? c : d;
293 }
294
295 private long cmoveLLEforL(long a, long b, long c, long d) {
296 return (a <= b) ? c : d;
297 }
298
299 // L for F
300 private float cmoveLEQforF(long a, long b, float c, float d) {
301 return (a == b) ? c : d;
302 }
303
304 private float cmoveLNEforF(long a, long b, float c, float d) {
305 return (a != b) ? c : d;
306 }
307
308 private float cmoveLGTforF(long a, long b, float c, float d) {
309 return (a > b) ? c : d;
310 }
311
312 private float cmoveLGEforF(long a, long b, float c, float d) {
313 return (a >= b) ? c : d;
314 }
315
316 private float cmoveLLTforF(long a, long b, float c, float d) {
317 return (a < b) ? c : d;
318 }
319
320 private float cmoveLLEforF(long a, long b, float c, float d) {
321 return (a <= b) ? c : d;
322 }
323
324 // L for D
325 private double cmoveLEQforD(long a, long b, double c, double d) {
326 return (a == b) ? c : d;
327 }
328
329 private double cmoveLNEforD(long a, long b, double c, double d) {
330 return (a != b) ? c : d;
331 }
332
333 private double cmoveLGTforD(long a, long b, double c, double d) {
334 return (a > b) ? c : d;
335 }
336
337 private double cmoveLGEforD(long a, long b, double c, double d) {
338 return (a >= b) ? c : d;
339 }
340
341 private double cmoveLLTforD(long a, long b, double c, double d) {
342 return (a < b) ? c : d;
343 }
344
345 private double cmoveLLEforD(long a, long b, double c, double d) {
346 return (a <= b) ? c : d;
347 }
348
349 // Unsigned comparison: I/L
350 // I for I
351 private int cmoveUIEQforI(int a, int b, int c, int d) {
352 return Integer.compareUnsigned(a, b) == 0 ? c : d;
353 }
354
355 private int cmoveUINEforI(int a, int b, int c, int d) {
356 return Integer.compareUnsigned(a, b) != 0 ? c : d;
357 }
358
359 private int cmoveUIGTforI(int a, int b, int c, int d) {
360 return Integer.compareUnsigned(a, b) > 0 ? c : d;
361 }
362
363 private int cmoveUIGEforI(int a, int b, int c, int d) {
364 return Integer.compareUnsigned(a, b) >= 0 ? c : d;
365 }
366
367 private int cmoveUILTforI(int a, int b, int c, int d) {
368 return Integer.compareUnsigned(a, b) < 0 ? c : d;
369 }
370
371 private int cmoveUILEforI(int a, int b, int c, int d) {
372 return Integer.compareUnsigned(a, b) <= 0 ? c : d;
373 }
374
375 // I for L
376 private long cmoveUIEQforL(int a, int b, long c, long d) {
377 return Integer.compareUnsigned(a, b) == 0 ? c : d;
378 }
379
380 private long cmoveUINEforL(int a, int b, long c, long d) {
381 return Integer.compareUnsigned(a, b) != 0 ? c : d;
382 }
383
384 private long cmoveUIGTforL(int a, int b, long c, long d) {
385 return Integer.compareUnsigned(a, b) > 0 ? c : d;
386 }
387
388 private long cmoveUIGEforL(int a, int b, long c, long d) {
389 return Integer.compareUnsigned(a, b) >= 0 ? c : d;
390 }
391
392 private long cmoveUILTforL(int a, int b, long c, long d) {
393 return Integer.compareUnsigned(a, b) < 0 ? c : d;
394 }
395
396 private long cmoveUILEforL(int a, int b, long c, long d) {
397 return Integer.compareUnsigned(a, b) <= 0 ? c : d;
398 }
399
400 // I for F
401 private float cmoveUIEQforF(int a, int b, float c, float d) {
402 return Integer.compareUnsigned(a, b) == 0 ? c : d;
403 }
404
405 private float cmoveUINEforF(int a, int b, float c, float d) {
406 return Integer.compareUnsigned(a, b) != 0 ? c : d;
407 }
408
409 private float cmoveUIGTforF(int a, int b, float c, float d) {
410 return Integer.compareUnsigned(a, b) > 0 ? c : d;
411 }
412
413 private float cmoveUIGEforF(int a, int b, float c, float d) {
414 return Integer.compareUnsigned(a, b) >= 0 ? c : d;
415 }
416
417 private float cmoveUILTforF(int a, int b, float c, float d) {
418 return Integer.compareUnsigned(a, b) < 0 ? c : d;
419 }
420
421 private float cmoveUILEforF(int a, int b, float c, float d) {
422 return Integer.compareUnsigned(a, b) <= 0 ? c : d;
423 }
424
425 // I for D
426 private double cmoveUIEQforD(int a, int b, double c, double d) {
427 return Integer.compareUnsigned(a, b) == 0 ? c : d;
428 }
429
430 private double cmoveUINEforD(int a, int b, double c, double d) {
431 return Integer.compareUnsigned(a, b) != 0 ? c : d;
432 }
433
434 private double cmoveUIGTforD(int a, int b, double c, double d) {
435 return Integer.compareUnsigned(a, b) > 0 ? c : d;
436 }
437
438 private double cmoveUIGEforD(int a, int b, double c, double d) {
439 return Integer.compareUnsigned(a, b) >= 0 ? c : d;
440 }
441
442 private double cmoveUILTforD(int a, int b, double c, double d) {
443 return Integer.compareUnsigned(a, b) < 0 ? c : d;
444 }
445
446 private double cmoveUILEforD(int a, int b, double c, double d) {
447 return Integer.compareUnsigned(a, b) <= 0 ? c : d;
448 }
449
450 // L for I
451 private int cmoveULEQforI(long a, long b, int c, int d) {
452 return Long.compareUnsigned(a, b) == 0 ? c : d;
453 }
454
455 private int cmoveULNEforI(long a, long b, int c, int d) {
456 return Long.compareUnsigned(a, b) != 0 ? c : d;
457 }
458
459 private int cmoveULGTforI(long a, long b, int c, int d) {
460 return Long.compareUnsigned(a, b) > 0 ? c : d;
461 }
462
463 private int cmoveULGEforI(long a, long b, int c, int d) {
464 return Long.compareUnsigned(a, b) >= 0 ? c : d;
465 }
466
467 private int cmoveULLTforI(long a, long b, int c, int d) {
468 return Long.compareUnsigned(a, b) < 0 ? c : d;
469 }
470
471 private int cmoveULLEforI(long a, long b, int c, int d) {
472 return Long.compareUnsigned(a, b) <= 0 ? c : d;
473 }
474
475 // L for L
476 private long cmoveULEQforL(long a, long b, long c, long d) {
477 return Long.compareUnsigned(a, b) == 0 ? c : d;
478 }
479
480 private long cmoveULNEforL(long a, long b, long c, long d) {
481 return Long.compareUnsigned(a, b) != 0 ? c : d;
482 }
483
484 private long cmoveULGTforL(long a, long b, long c, long d) {
485 return Long.compareUnsigned(a, b) > 0 ? c : d;
486 }
487
488 private long cmoveULGEforL(long a, long b, long c, long d) {
489 return Long.compareUnsigned(a, b) >= 0 ? c : d;
490 }
491
492 private long cmoveULLTforL(long a, long b, long c, long d) {
493 return Long.compareUnsigned(a, b) < 0 ? c : d;
494 }
495
496 private long cmoveULLEforL(long a, long b, long c, long d) {
497 return Long.compareUnsigned(a, b) <= 0 ? c : d;
498 }
499
500 // L for F
501 private float cmoveULEQforF(long a, long b, float c, float d) {
502 return Long.compareUnsigned(a, b) == 0 ? c : d;
503 }
504
505 private float cmoveULNEforF(long a, long b, float c, float d) {
506 return Long.compareUnsigned(a, b) != 0 ? c : d;
507 }
508
509 private float cmoveULGTforF(long a, long b, float c, float d) {
510 return Long.compareUnsigned(a, b) > 0 ? c : d;
511 }
512
513 private float cmoveULGEforF(long a, long b, float c, float d) {
514 return Long.compareUnsigned(a, b) >= 0 ? c : d;
515 }
516
517 private float cmoveULLTforF(long a, long b, float c, float d) {
518 return Long.compareUnsigned(a, b) < 0 ? c : d;
519 }
520
521 private float cmoveULLEforF(long a, long b, float c, float d) {
522 return Long.compareUnsigned(a, b) <= 0 ? c : d;
523 }
524
525 // L for D
526 private double cmoveULEQforD(long a, long b, double c, double d) {
527 return Long.compareUnsigned(a, b) == 0 ? c : d;
528 }
529
530 private double cmoveULNEforD(long a, long b, double c, double d) {
531 return Long.compareUnsigned(a, b) != 0 ? c : d;
532 }
533
534 private double cmoveULGTforD(long a, long b, double c, double d) {
535 return Long.compareUnsigned(a, b) > 0 ? c : d;
536 }
537
538 private double cmoveULGEforD(long a, long b, double c, double d) {
539 return Long.compareUnsigned(a, b) >= 0 ? c : d;
540 }
541
542 private double cmoveULLTforD(long a, long b, double c, double d) {
543 return Long.compareUnsigned(a, b) < 0 ? c : d;
544 }
545
546 private double cmoveULLEforD(long a, long b, double c, double d) {
547 return Long.compareUnsigned(a, b) <= 0 ? c : d;
548 }
549
550 // Float comparison
551 private int cmoveFGTforI(float a, float b, int c, int d) {
552 return (a > b) ? c : d;
553 }
554
555 private long cmoveFGTforL(float a, float b, long c, long d) {
556 return (a > b) ? c : d;
557 }
558
559 private float cmoveFGTforF(float a, float b, float c, float d) {
560 return (a > b) ? c : d;
561 }
562
563 private double cmoveFGTforD(float a, float b, double c, double d) {
564 return (a > b) ? c : d;
565 }
566
567 private int cmoveDGTforI(double a, double b, int c, int d) {
568 return (a > b) ? c : d;
569 }
570
571 private long cmoveDGTforL(double a, double b, long c, long d) {
572 return (a > b) ? c : d;
573 }
574
575 private float cmoveDGTforF(double a, double b, float c, float d) {
576 return (a > b) ? c : d;
577 }
578
579 private double cmoveDGTforD(double a, double b, double c, double d) {
580 return (a > b) ? c : d;
581 }
582
583 // Compare 2 values, and pick one of them
584 @Test
585 @IR(counts = {IRNode.LOAD_VECTOR_F, ">0",
586 IRNode.VECTOR_MASK_CMP_F, ">0",
587 IRNode.VECTOR_BLEND_F, ">0",
588 IRNode.STORE_VECTOR, ">0"},
589 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
590 private static void testCMoveVFGT(float[] a, float[] b, float[] c) {
591 for (int i = 0; i < a.length; i++) {
592 c[i] = (a[i] > b[i]) ? a[i] : b[i];
593 }
594 }
595
596 @Test
597 @IR(counts = {IRNode.LOAD_VECTOR_F, ">0",
598 IRNode.VECTOR_MASK_CMP_F, ">0",
599 IRNode.VECTOR_BLEND_F, ">0",
600 IRNode.STORE_VECTOR, ">0"},
601 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
602 private static void testCMoveVFGTSwap(float[] a, float[] b, float[] c) {
603 for (int i = 0; i < a.length; i++) {
604 c[i] = (b[i] > a[i]) ? a[i] : b[i];
605 }
606 }
607
608 @Test
609 @IR(counts = {IRNode.LOAD_VECTOR_F, ">0",
610 IRNode.VECTOR_MASK_CMP_F, ">0",
611 IRNode.VECTOR_BLEND_F, ">0",
612 IRNode.STORE_VECTOR, ">0"},
613 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
614 private static void testCMoveVFLT(float[] a, float[] b, float[] c) {
615 for (int i = 0; i < a.length; i++) {
616 c[i] = (a[i] < b[i]) ? a[i] : b[i];
617 }
618 }
619
620 @Test
621 @IR(counts = {IRNode.LOAD_VECTOR_F, ">0",
622 IRNode.VECTOR_MASK_CMP_F, ">0",
623 IRNode.VECTOR_BLEND_F, ">0",
624 IRNode.STORE_VECTOR, ">0"},
625 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
626 private static void testCMoveVFLTSwap(float[] a, float[] b, float[] c) {
627 for (int i = 0; i < a.length; i++) {
628 c[i] = (b[i] < a[i]) ? a[i] : b[i];
629 }
630 }
631
632 @Test
633 @IR(counts = {IRNode.LOAD_VECTOR_F, ">0",
634 IRNode.VECTOR_MASK_CMP_F, ">0",
635 IRNode.VECTOR_BLEND_F, ">0",
636 IRNode.STORE_VECTOR, ">0"},
637 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
638 private static void testCMoveVFEQ(float[] a, float[] b, float[] c) {
639 for (int i = 0; i < a.length; i++) {
640 c[i] = (a[i] == b[i]) ? a[i] : b[i];
641 }
642 }
643
644 @Test
645 @IR(counts = {IRNode.LOAD_VECTOR_D, ">0",
646 IRNode.VECTOR_MASK_CMP_D, ">0",
647 IRNode.VECTOR_BLEND_D, ">0",
648 IRNode.STORE_VECTOR, ">0"},
649 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
650 private static void testCMoveVDLE(double[] a, double[] b, double[] c) {
651 for (int i = 0; i < a.length; i++) {
652 c[i] = (a[i] <= b[i]) ? a[i] : b[i];
653 }
654 }
655
656 @Test
657 @IR(counts = {IRNode.LOAD_VECTOR_D, ">0",
658 IRNode.VECTOR_MASK_CMP_D, ">0",
659 IRNode.VECTOR_BLEND_D, ">0",
660 IRNode.STORE_VECTOR, ">0"},
661 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
662 private static void testCMoveVDLESwap(double[] a, double[] b, double[] c) {
663 for (int i = 0; i < a.length; i++) {
664 c[i] = (b[i] <= a[i]) ? a[i] : b[i];
665 }
666 }
667
668 @Test
669 @IR(counts = {IRNode.LOAD_VECTOR_D, ">0",
670 IRNode.VECTOR_MASK_CMP_D, ">0",
671 IRNode.VECTOR_BLEND_D, ">0",
672 IRNode.STORE_VECTOR, ">0"},
673 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
674 private static void testCMoveVDGE(double[] a, double[] b, double[] c) {
675 for (int i = 0; i < a.length; i++) {
676 c[i] = (a[i] >= b[i]) ? a[i] : b[i];
677 }
678 }
679
680 @Test
681 @IR(counts = {IRNode.LOAD_VECTOR_D, ">0",
682 IRNode.VECTOR_MASK_CMP_D, ">0",
683 IRNode.VECTOR_BLEND_D, ">0",
684 IRNode.STORE_VECTOR, ">0"},
685 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
686 private static void testCMoveVDGESwap(double[] a, double[] b, double[] c) {
687 for (int i = 0; i < a.length; i++) {
688 c[i] = (b[i] >= a[i]) ? a[i] : b[i];
689 }
690 }
691
692 @Test
693 @IR(counts = {IRNode.LOAD_VECTOR_D, ">0",
694 IRNode.VECTOR_MASK_CMP_D, ">0",
695 IRNode.VECTOR_BLEND_D, ">0",
696 IRNode.STORE_VECTOR, ">0"},
697 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
698 private static void testCMoveVDNE(double[] a, double[] b, double[] c) {
699 for (int i = 0; i < a.length; i++) {
700 c[i] = (a[i] != b[i]) ? a[i] : b[i];
701 }
702 }
703
704 // Extensions: compare 2 values, and pick from 2 consts
705 @Test
706 @IR(counts = {IRNode.LOAD_VECTOR_F, ">0",
707 IRNode.VECTOR_MASK_CMP_F, ">0",
708 IRNode.VECTOR_BLEND_F, ">0",
709 IRNode.STORE_VECTOR, ">0"},
710 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
711 private static void testCMoveFGTforFConst(float[] a, float[] b, float[] c) {
712 for (int i = 0; i < a.length; i++) {
713 c[i] = (a[i] > b[i]) ? 0.1f : -0.1f;
714 }
715 }
716
717 @Test
718 @IR(counts = {IRNode.LOAD_VECTOR_F, ">0",
719 IRNode.VECTOR_MASK_CMP_F, ">0",
720 IRNode.VECTOR_BLEND_F, ">0",
721 IRNode.STORE_VECTOR, ">0"},
722 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
723 private static void testCMoveFGEforFConst(float[] a, float[] b, float[] c) {
724 for (int i = 0; i < a.length; i++) {
725 c[i] = (a[i] >= b[i]) ? 0.1f : -0.1f;
726 }
727 }
728
729 @Test
730 @IR(counts = {IRNode.LOAD_VECTOR_F, ">0",
731 IRNode.VECTOR_MASK_CMP_F, ">0",
732 IRNode.VECTOR_BLEND_F, ">0",
733 IRNode.STORE_VECTOR, ">0"},
734 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
735 private static void testCMoveFLTforFConst(float[] a, float[] b, float[] c) {
736 for (int i = 0; i < a.length; i++) {
737 c[i] = (a[i] < b[i]) ? 0.1f : -0.1f;
738 }
739 }
740
741 @Test
742 @IR(counts = {IRNode.LOAD_VECTOR_F, ">0",
743 IRNode.VECTOR_MASK_CMP_F, ">0",
744 IRNode.VECTOR_BLEND_F, ">0",
745 IRNode.STORE_VECTOR, ">0"},
746 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
747 private static void testCMoveFLEforFConst(float[] a, float[] b, float[] c) {
748 for (int i = 0; i < a.length; i++) {
749 c[i] = (a[i] <= b[i]) ? 0.1f : -0.1f;
750 }
751 }
752
753 @Test
754 @IR(counts = {IRNode.LOAD_VECTOR_F, ">0",
755 IRNode.VECTOR_MASK_CMP_F, ">0",
756 IRNode.VECTOR_BLEND_F, ">0",
757 IRNode.STORE_VECTOR, ">0"},
758 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
759 private static void testCMoveFEQforFConst(float[] a, float[] b, float[] c) {
760 for (int i = 0; i < a.length; i++) {
761 c[i] = (a[i] == b[i]) ? 0.1f : -0.1f;
762 }
763 }
764
765 @Test
766 @IR(counts = {IRNode.LOAD_VECTOR_F, ">0",
767 IRNode.VECTOR_MASK_CMP_F, ">0",
768 IRNode.VECTOR_BLEND_F, ">0",
769 IRNode.STORE_VECTOR, ">0"},
770 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
771 private static void testCMoveFNEQforFConst(float[] a, float[] b, float[] c) {
772 for (int i = 0; i < a.length; i++) {
773 c[i] = (a[i] != b[i]) ? 0.1f : -0.1f;
774 }
775 }
776
777 @Test
778 @IR(counts = {IRNode.LOAD_VECTOR_F, ">0",
779 IRNode.VECTOR_MASK_CMP_F, ">0",
780 IRNode.VECTOR_BLEND_F, ">0",
781 IRNode.STORE_VECTOR, ">0"},
782 applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"},
783 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
784 private static void testCMoveFLTforFConstH2(float[] a, float[] b, float[] c) {
785 for (int i = 0; i < a.length; i+=2) {
786 c[i+0] = (a[i+0] < b[i+0]) ? 0.1f : -0.1f;
787 c[i+1] = (a[i+1] < b[i+1]) ? 0.1f : -0.1f;
788 // With AlignVector, we need 8-byte alignment of vector loads/stores.
789 // UseCompactObjectHeaders=false UseCompactObjectHeaders=true
790 // adr = base + 16 + 8*i -> always adr = base + 12 + 8*i -> never
791 // -> vectorize -> no vectorization
792 }
793 }
794
795 @Test
796 @IR(counts = {IRNode.LOAD_VECTOR_F, ">0",
797 IRNode.VECTOR_MASK_CMP_F, ">0",
798 IRNode.VECTOR_BLEND_F, ">0",
799 IRNode.STORE_VECTOR, ">0"},
800 applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"},
801 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
802 private static void testCMoveFLEforFConstH2(float[] a, float[] b, float[] c) {
803 for (int i = 0; i < a.length; i+=2) {
804 c[i+0] = (a[i+0] <= b[i+0]) ? 0.1f : -0.1f;
805 c[i+1] = (a[i+1] <= b[i+1]) ? 0.1f : -0.1f;
806 // With AlignVector, we need 8-byte alignment of vector loads/stores.
807 // UseCompactObjectHeaders=false UseCompactObjectHeaders=true
808 // adr = base + 16 + 8*i -> always adr = base + 12 + 8*i -> never
809 // -> vectorize -> no vectorization
810 }
811 }
812
813 @Test
814 @IR(counts = {IRNode.LOAD_VECTOR_F, "=0",
815 IRNode.VECTOR_MASK_CMP_F, "=0",
816 IRNode.VECTOR_BLEND_F, "=0",
817 IRNode.STORE_VECTOR, "=0"},
818 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
819 private static void testCMoveFYYforFConstH2(float[] a, float[] b, float[] c) {
820 for (int i = 0; i < a.length; i+=2) {
821 c[i+0] = (a[i+0] <= b[i+0]) ? 0.1f : -0.1f;
822 c[i+1] = (a[i+1] < b[i+1]) ? 0.1f : -0.1f;
823 }
824 }
825
826 @Test
827 @IR(counts = {IRNode.LOAD_VECTOR_F, "=0",
828 IRNode.VECTOR_MASK_CMP_F, "=0",
829 IRNode.VECTOR_BLEND_F, "=0",
830 IRNode.STORE_VECTOR, "=0"},
831 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
832 private static void testCMoveFXXforFConstH2(float[] a, float[] b, float[] c) {
833 for (int i = 0; i < a.length; i+=2) {
834 c[i+0] = (a[i+0] < b[i+0]) ? 0.1f : -0.1f;
835 c[i+1] = (a[i+1] <= b[i+1]) ? 0.1f : -0.1f;
836 }
837 }
838
839 @Test
840 @IR(counts = {IRNode.LOAD_VECTOR_D, ">0",
841 IRNode.VECTOR_MASK_CMP_D, ">0",
842 IRNode.VECTOR_BLEND_D, ">0",
843 IRNode.STORE_VECTOR, ">0"},
844 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
845 private static void testCMoveDGTforDConst(double[] a, double[] b, double[] c) {
846 for (int i = 0; i < a.length; i++) {
847 c[i] = (a[i] > b[i]) ? 0.1 : -0.1;
848 }
849 }
850
851 @Test
852 @IR(counts = {IRNode.LOAD_VECTOR_D, ">0",
853 IRNode.VECTOR_MASK_CMP_D, ">0",
854 IRNode.VECTOR_BLEND_D, ">0",
855 IRNode.STORE_VECTOR, ">0"},
856 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
857 private static void testCMoveDGEforDConst(double[] a, double[] b, double[] c) {
858 for (int i = 0; i < a.length; i++) {
859 c[i] = (a[i] >= b[i]) ? 0.1 : -0.1;
860 }
861 }
862
863 @Test
864 @IR(counts = {IRNode.LOAD_VECTOR_D, ">0",
865 IRNode.VECTOR_MASK_CMP_D, ">0",
866 IRNode.VECTOR_BLEND_D, ">0",
867 IRNode.STORE_VECTOR, ">0"},
868 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
869 private static void testCMoveDLTforDConst(double[] a, double[] b, double[] c) {
870 for (int i = 0; i < a.length; i++) {
871 c[i] = (a[i] < b[i]) ? 0.1 : -0.1;
872 }
873 }
874
875 @Test
876 @IR(counts = {IRNode.LOAD_VECTOR_D, ">0",
877 IRNode.VECTOR_MASK_CMP_D, ">0",
878 IRNode.VECTOR_BLEND_D, ">0",
879 IRNode.STORE_VECTOR, ">0"},
880 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
881 private static void testCMoveDLEforDConst(double[] a, double[] b, double[] c) {
882 for (int i = 0; i < a.length; i++) {
883 c[i] = (a[i] <= b[i]) ? 0.1 : -0.1;
884 }
885 }
886
887 @Test
888 @IR(counts = {IRNode.LOAD_VECTOR_D, ">0",
889 IRNode.VECTOR_MASK_CMP_D, ">0",
890 IRNode.VECTOR_BLEND_D, ">0",
891 IRNode.STORE_VECTOR, ">0"},
892 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
893 private static void testCMoveDEQforDConst(double[] a, double[] b, double[] c) {
894 for (int i = 0; i < a.length; i++) {
895 c[i] = (a[i] == b[i]) ? 0.1 : -0.1;
896 }
897 }
898
899 @Test
900 @IR(counts = {IRNode.LOAD_VECTOR_D, ">0",
901 IRNode.VECTOR_MASK_CMP_D, ">0",
902 IRNode.VECTOR_BLEND_D, ">0",
903 IRNode.STORE_VECTOR, ">0"},
904 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
905 private static void testCMoveDNEQforDConst(double[] a, double[] b, double[] c) {
906 for (int i = 0; i < a.length; i++) {
907 c[i] = (a[i] != b[i]) ? 0.1 : -0.1;
908 }
909 }
910
911 @Test
912 @IR(counts = {IRNode.LOAD_VECTOR_D, ">0",
913 IRNode.VECTOR_MASK_CMP_D, ">0",
914 IRNode.VECTOR_BLEND_D, ">0",
915 IRNode.STORE_VECTOR, ">0"},
916 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
917 private static void testCMoveDLTforDConstH2(double[] a, double[] b, double[] c) {
918 for (int i = 0; i < a.length; i+=2) {
919 c[i+0] = (a[i+0] < b[i+0]) ? 0.1 : -0.1;
920 c[i+1] = (a[i+1] < b[i+1]) ? 0.1 : -0.1;
921 }
922 }
923
924 @Test
925 @IR(counts = {IRNode.LOAD_VECTOR_D, ">0",
926 IRNode.VECTOR_MASK_CMP_D, ">0",
927 IRNode.VECTOR_BLEND_D, ">0",
928 IRNode.STORE_VECTOR, ">0"},
929 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
930 private static void testCMoveDLEforDConstH2(double[] a, double[] b, double[] c) {
931 for (int i = 0; i < a.length; i+=2) {
932 c[i+0] = (a[i+0] <= b[i+0]) ? 0.1 : -0.1;
933 c[i+1] = (a[i+1] <= b[i+1]) ? 0.1 : -0.1;
934 }
935 }
936
937 @Test
938 @IR(counts = {IRNode.LOAD_VECTOR_D, "=0",
939 IRNode.VECTOR_MASK_CMP_D, "=0",
940 IRNode.VECTOR_BLEND_D, "=0",
941 IRNode.STORE_VECTOR, "=0"},
942 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
943 private static void testCMoveDYYforDConstH2(double[] a, double[] b, double[] c) {
944 for (int i = 0; i < a.length; i+=2) {
945 c[i+0] = (a[i+0] <= b[i+0]) ? 0.1 : -0.1;
946 c[i+1] = (a[i+1] < b[i+1]) ? 0.1 : -0.1;
947 }
948 }
949
950 @Test
951 @IR(counts = {IRNode.LOAD_VECTOR_D, "=0",
952 IRNode.VECTOR_MASK_CMP_D, "=0",
953 IRNode.VECTOR_BLEND_D, "=0",
954 IRNode.STORE_VECTOR, "=0"},
955 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
956 private static void testCMoveDXXforDConstH2(double[] a, double[] b, double[] c) {
957 for (int i = 0; i < a.length; i+=2) {
958 c[i+0] = (a[i+0] < b[i+0]) ? 0.1 : -0.1;
959 c[i+1] = (a[i+1] <= b[i+1]) ? 0.1 : -0.1;
960 }
961 }
962
963 // Extension: Compare 2 ILFD values, and pick from 2 ILFD values
964 // Note:
965 // To guarantee that CMove is introduced, I need to perform the loads before the branch. To ensure they
966 // do not float down into the branches, I compute a value, and store it to r2 (same as r, except that the
967 // compilation does not know that).
968 // So far, vectorization only works for CMoveF/D, with same data-width comparison (F/I for F, D/L for D).
969 // Signed comparison: I/L
970 // I fo I
971 @Test
972 @IR(failOn = {IRNode.STORE_VECTOR})
973 private static void testCMoveIEQforI(int[] a, int[] b, int[] c, int[] d, int[] r, int[] r2) {
974 for (int i = 0; i < a.length; i++) {
975 int cc = c[i];
976 int dd = d[i];
977 r2[i] = cc + dd;
978 r[i] = (a[i] == b[i]) ? cc : dd;
979 }
980 }
981
982 @Test
983 @IR(failOn = {IRNode.STORE_VECTOR})
984 private static void testCMoveINEforI(int[] a, int[] b, int[] c, int[] d, int[] r, int[] r2) {
985 for (int i = 0; i < a.length; i++) {
986 int cc = c[i];
987 int dd = d[i];
988 r2[i] = cc + dd;
989 r[i] = (a[i] != b[i]) ? cc : dd;
990 }
991 }
992
993 @Test
994 @IR(failOn = {IRNode.STORE_VECTOR})
995 private static void testCMoveIGTforI(int[] a, int[] b, int[] c, int[] d, int[] r, int[] r2) {
996 for (int i = 0; i < a.length; i++) {
997 int cc = c[i];
998 int dd = d[i];
999 r2[i] = cc + dd;
1000 r[i] = (a[i] > b[i]) ? cc : dd;
1001 }
1002 }
1003
1004 @Test
1005 @IR(failOn = {IRNode.STORE_VECTOR})
1006 private static void testCMoveIGEforI(int[] a, int[] b, int[] c, int[] d, int[] r, int[] r2) {
1007 for (int i = 0; i < a.length; i++) {
1008 int cc = c[i];
1009 int dd = d[i];
1010 r2[i] = cc + dd;
1011 r[i] = (a[i] >= b[i]) ? cc : dd;
1012 }
1013 }
1014
1015 @Test
1016 @IR(failOn = {IRNode.STORE_VECTOR})
1017 private static void testCMoveILTforI(int[] a, int[] b, int[] c, int[] d, int[] r, int[] r2) {
1018 for (int i = 0; i < a.length; i++) {
1019 int cc = c[i];
1020 int dd = d[i];
1021 r2[i] = cc + dd;
1022 r[i] = (a[i] < b[i]) ? cc : dd;
1023 }
1024 }
1025
1026 @Test
1027 @IR(failOn = {IRNode.STORE_VECTOR})
1028 private static void testCMoveILEforI(int[] a, int[] b, int[] c, int[] d, int[] r, int[] r2) {
1029 for (int i = 0; i < a.length; i++) {
1030 int cc = c[i];
1031 int dd = d[i];
1032 r2[i] = cc + dd;
1033 r[i] = (a[i] <= b[i]) ? cc : dd;
1034 }
1035 }
1036
1037 // I fo L
1038 @Test
1039 @IR(failOn = {IRNode.STORE_VECTOR})
1040 private static void testCMoveIEQforL(int[] a, int[] b, long[] c, long[] d, long[] r, long[] r2) {
1041 for (int i = 0; i < a.length; i++) {
1042 long cc = c[i];
1043 long dd = d[i];
1044 r2[i] = cc + dd;
1045 r[i] = (a[i] == b[i]) ? cc : dd;
1046 }
1047 }
1048
1049 @Test
1050 @IR(failOn = {IRNode.STORE_VECTOR})
1051 private static void testCMoveINEforL(int[] a, int[] b, long[] c, long[] d, long[] r, long[] r2) {
1052 for (int i = 0; i < a.length; i++) {
1053 long cc = c[i];
1054 long dd = d[i];
1055 r2[i] = cc + dd;
1056 r[i] = (a[i] != b[i]) ? cc : dd;
1057 }
1058 }
1059
1060 @Test
1061 @IR(failOn = {IRNode.STORE_VECTOR})
1062 private static void testCMoveIGTforL(int[] a, int[] b, long[] c, long[] d, long[] r, long[] r2) {
1063 for (int i = 0; i < a.length; i++) {
1064 long cc = c[i];
1065 long dd = d[i];
1066 r2[i] = cc + dd;
1067 r[i] = (a[i] > b[i]) ? cc : dd;
1068 }
1069 }
1070
1071 @Test
1072 @IR(failOn = {IRNode.STORE_VECTOR})
1073 private static void testCMoveIGEforL(int[] a, int[] b, long[] c, long[] d, long[] r, long[] r2) {
1074 for (int i = 0; i < a.length; i++) {
1075 long cc = c[i];
1076 long dd = d[i];
1077 r2[i] = cc + dd;
1078 r[i] = (a[i] >= b[i]) ? cc : dd;
1079 }
1080 }
1081
1082 @Test
1083 @IR(failOn = {IRNode.STORE_VECTOR})
1084 private static void testCMoveILTforL(int[] a, int[] b, long[] c, long[] d, long[] r, long[] r2) {
1085 for (int i = 0; i < a.length; i++) {
1086 long cc = c[i];
1087 long dd = d[i];
1088 r2[i] = cc + dd;
1089 r[i] = (a[i] < b[i]) ? cc : dd;
1090 }
1091 }
1092
1093 @Test
1094 @IR(failOn = {IRNode.STORE_VECTOR})
1095 private static void testCMoveILEforL(int[] a, int[] b, long[] c, long[] d, long[] r, long[] r2) {
1096 for (int i = 0; i < a.length; i++) {
1097 long cc = c[i];
1098 long dd = d[i];
1099 r2[i] = cc + dd;
1100 r[i] = (a[i] <= b[i]) ? cc : dd;
1101 }
1102 }
1103
1104 // I fo F
1105 @Test
1106 @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1107 IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1108 IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1109 IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1110 IRNode.STORE_VECTOR, ">0"},
1111 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
1112 private static void testCMoveIEQforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) {
1113 for (int i = 0; i < a.length; i++) {
1114 float cc = c[i];
1115 float dd = d[i];
1116 r2[i] = cc + dd;
1117 r[i] = (a[i] == b[i]) ? cc : dd;
1118 }
1119 }
1120
1121 @Test
1122 @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1123 IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1124 IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1125 IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1126 IRNode.STORE_VECTOR, ">0"},
1127 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
1128 private static void testCMoveINEforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) {
1129 for (int i = 0; i < a.length; i++) {
1130 float cc = c[i];
1131 float dd = d[i];
1132 r2[i] = cc + dd;
1133 r[i] = (a[i] != b[i]) ? cc : dd;
1134 }
1135 }
1136
1137 @Test
1138 @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1139 IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1140 IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1141 IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1142 IRNode.STORE_VECTOR, ">0"},
1143 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
1144 private static void testCMoveIGTforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) {
1145 for (int i = 0; i < a.length; i++) {
1146 float cc = c[i];
1147 float dd = d[i];
1148 r2[i] = cc + dd;
1149 r[i] = (a[i] > b[i]) ? cc : dd;
1150 }
1151 }
1152
1153 @Test
1154 @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1155 IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1156 IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1157 IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1158 IRNode.STORE_VECTOR, ">0"},
1159 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
1160 private static void testCMoveIGEforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) {
1161 for (int i = 0; i < a.length; i++) {
1162 float cc = c[i];
1163 float dd = d[i];
1164 r2[i] = cc + dd;
1165 r[i] = (a[i] >= b[i]) ? cc : dd;
1166 }
1167 }
1168
1169 @Test
1170 @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1171 IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1172 IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1173 IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1174 IRNode.STORE_VECTOR, ">0"},
1175 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
1176 private static void testCMoveILTforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) {
1177 for (int i = 0; i < a.length; i++) {
1178 float cc = c[i];
1179 float dd = d[i];
1180 r2[i] = cc + dd;
1181 r[i] = (a[i] < b[i]) ? cc : dd;
1182 }
1183 }
1184
1185 @Test
1186 @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1187 IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1188 IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1189 IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1190 IRNode.STORE_VECTOR, ">0"},
1191 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
1192 private static void testCMoveILEforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) {
1193 for (int i = 0; i < a.length; i++) {
1194 float cc = c[i];
1195 float dd = d[i];
1196 r2[i] = cc + dd;
1197 r[i] = (a[i] <= b[i]) ? cc : dd;
1198 }
1199 }
1200
1201 // I fo D
1202 @Test
1203 @IR(failOn = {IRNode.STORE_VECTOR})
1204 private static void testCMoveIEQforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) {
1205 for (int i = 0; i < a.length; i++) {
1206 double cc = c[i];
1207 double dd = d[i];
1208 r2[i] = cc + dd;
1209 r[i] = (a[i] == b[i]) ? cc : dd;
1210 }
1211 }
1212
1213 @Test
1214 @IR(failOn = {IRNode.STORE_VECTOR})
1215 private static void testCMoveINEforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) {
1216 for (int i = 0; i < a.length; i++) {
1217 double cc = c[i];
1218 double dd = d[i];
1219 r2[i] = cc + dd;
1220 r[i] = (a[i] != b[i]) ? cc : dd;
1221 }
1222 }
1223
1224 @Test
1225 @IR(failOn = {IRNode.STORE_VECTOR})
1226 private static void testCMoveIGTforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) {
1227 for (int i = 0; i < a.length; i++) {
1228 double cc = c[i];
1229 double dd = d[i];
1230 r2[i] = cc + dd;
1231 r[i] = (a[i] > b[i]) ? cc : dd;
1232 }
1233 }
1234
1235 @Test
1236 @IR(failOn = {IRNode.STORE_VECTOR})
1237 private static void testCMoveIGEforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) {
1238 for (int i = 0; i < a.length; i++) {
1239 double cc = c[i];
1240 double dd = d[i];
1241 r2[i] = cc + dd;
1242 r[i] = (a[i] >= b[i]) ? cc : dd;
1243 }
1244 }
1245
1246 @Test
1247 @IR(failOn = {IRNode.STORE_VECTOR})
1248 private static void testCMoveILTforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) {
1249 for (int i = 0; i < a.length; i++) {
1250 double cc = c[i];
1251 double dd = d[i];
1252 r2[i] = cc + dd;
1253 r[i] = (a[i] < b[i]) ? cc : dd;
1254 }
1255 }
1256
1257 @Test
1258 @IR(failOn = {IRNode.STORE_VECTOR})
1259 private static void testCMoveILEforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) {
1260 for (int i = 0; i < a.length; i++) {
1261 double cc = c[i];
1262 double dd = d[i];
1263 r2[i] = cc + dd;
1264 r[i] = (a[i] <= b[i]) ? cc : dd;
1265 }
1266 }
1267
1268 // L fo I
1269 @Test
1270 @IR(failOn = {IRNode.STORE_VECTOR})
1271 private static void testCMoveLEQforI(long[] a, long[] b, int[] c, int[] d, int[] r, int[] r2) {
1272 for (int i = 0; i < a.length; i++) {
1273 int cc = c[i];
1274 int dd = d[i];
1275 r2[i] = cc + dd;
1276 r[i] = (a[i] == b[i]) ? cc : dd;
1277 }
1278 }
1279
1280 @Test
1281 @IR(failOn = {IRNode.STORE_VECTOR})
1282 private static void testCMoveLNEforI(long[] a, long[] b, int[] c, int[] d, int[] r, int[] r2) {
1283 for (int i = 0; i < a.length; i++) {
1284 int cc = c[i];
1285 int dd = d[i];
1286 r2[i] = cc + dd;
1287 r[i] = (a[i] != b[i]) ? cc : dd;
1288 }
1289 }
1290
1291 @Test
1292 @IR(failOn = {IRNode.STORE_VECTOR})
1293 private static void testCMoveLGTforI(long[] a, long[] b, int[] c, int[] d, int[] r, int[] r2) {
1294 for (int i = 0; i < a.length; i++) {
1295 int cc = c[i];
1296 int dd = d[i];
1297 r2[i] = cc + dd;
1298 r[i] = (a[i] > b[i]) ? cc : dd;
1299 }
1300 }
1301
1302 @Test
1303 @IR(failOn = {IRNode.STORE_VECTOR})
1304 private static void testCMoveLGEforI(long[] a, long[] b, int[] c, int[] d, int[] r, int[] r2) {
1305 for (int i = 0; i < a.length; i++) {
1306 int cc = c[i];
1307 int dd = d[i];
1308 r2[i] = cc + dd;
1309 r[i] = (a[i] >= b[i]) ? cc : dd;
1310 }
1311 }
1312
1313 @Test
1314 @IR(failOn = {IRNode.STORE_VECTOR})
1315 private static void testCMoveLLTforI(long[] a, long[] b, int[] c, int[] d, int[] r, int[] r2) {
1316 for (int i = 0; i < a.length; i++) {
1317 int cc = c[i];
1318 int dd = d[i];
1319 r2[i] = cc + dd;
1320 r[i] = (a[i] < b[i]) ? cc : dd;
1321 }
1322 }
1323
1324 @Test
1325 @IR(failOn = {IRNode.STORE_VECTOR})
1326 private static void testCMoveLLEforI(long[] a, long[] b, int[] c, int[] d, int[] r, int[] r2) {
1327 for (int i = 0; i < a.length; i++) {
1328 int cc = c[i];
1329 int dd = d[i];
1330 r2[i] = cc + dd;
1331 r[i] = (a[i] <= b[i]) ? cc : dd;
1332 }
1333 }
1334
1335 // L fo L
1336 @Test
1337 @IR(failOn = {IRNode.STORE_VECTOR})
1338 private static void testCMoveLEQforL(long[] a, long[] b, long[] c, long[] d, long[] r, long[] r2) {
1339 for (int i = 0; i < a.length; i++) {
1340 long cc = c[i];
1341 long dd = d[i];
1342 r2[i] = cc + dd;
1343 r[i] = (a[i] == b[i]) ? cc : dd;
1344 }
1345 }
1346
1347 @Test
1348 @IR(failOn = {IRNode.STORE_VECTOR})
1349 private static void testCMoveLNEforL(long[] a, long[] b, long[] c, long[] d, long[] r, long[] r2) {
1350 for (int i = 0; i < a.length; i++) {
1351 long cc = c[i];
1352 long dd = d[i];
1353 r2[i] = cc + dd;
1354 r[i] = (a[i] != b[i]) ? cc : dd;
1355 }
1356 }
1357
1358 @Test
1359 @IR(failOn = {IRNode.STORE_VECTOR})
1360 private static void testCMoveLGTforL(long[] a, long[] b, long[] c, long[] d, long[] r, long[] r2) {
1361 for (int i = 0; i < a.length; i++) {
1362 long cc = c[i];
1363 long dd = d[i];
1364 r2[i] = cc + dd;
1365 r[i] = (a[i] > b[i]) ? cc : dd;
1366 }
1367 }
1368
1369 @Test
1370 @IR(failOn = {IRNode.STORE_VECTOR})
1371 private static void testCMoveLGEforL(long[] a, long[] b, long[] c, long[] d, long[] r, long[] r2) {
1372 for (int i = 0; i < a.length; i++) {
1373 long cc = c[i];
1374 long dd = d[i];
1375 r2[i] = cc + dd;
1376 r[i] = (a[i] >= b[i]) ? cc : dd;
1377 }
1378 }
1379
1380 @Test
1381 @IR(failOn = {IRNode.STORE_VECTOR})
1382 private static void testCMoveLLTforL(long[] a, long[] b, long[] c, long[] d, long[] r, long[] r2) {
1383 for (int i = 0; i < a.length; i++) {
1384 long cc = c[i];
1385 long dd = d[i];
1386 r2[i] = cc + dd;
1387 r[i] = (a[i] < b[i]) ? cc : dd;
1388 }
1389 }
1390
1391 @Test
1392 @IR(failOn = {IRNode.STORE_VECTOR})
1393 private static void testCMoveLLEforL(long[] a, long[] b, long[] c, long[] d, long[] r, long[] r2) {
1394 for (int i = 0; i < a.length; i++) {
1395 long cc = c[i];
1396 long dd = d[i];
1397 r2[i] = cc + dd;
1398 r[i] = (a[i] <= b[i]) ? cc : dd;
1399 }
1400 }
1401
1402 // L fo F
1403 @Test
1404 @IR(failOn = {IRNode.STORE_VECTOR})
1405 private static void testCMoveLEQforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) {
1406 for (int i = 0; i < a.length; i++) {
1407 float cc = c[i];
1408 float dd = d[i];
1409 r2[i] = cc + dd;
1410 r[i] = (a[i] == b[i]) ? cc : dd;
1411 }
1412 }
1413
1414 @Test
1415 @IR(failOn = {IRNode.STORE_VECTOR})
1416 private static void testCMoveLNEforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) {
1417 for (int i = 0; i < a.length; i++) {
1418 float cc = c[i];
1419 float dd = d[i];
1420 r2[i] = cc + dd;
1421 r[i] = (a[i] != b[i]) ? cc : dd;
1422 }
1423 }
1424
1425 @Test
1426 @IR(failOn = {IRNode.STORE_VECTOR})
1427 private static void testCMoveLGTforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) {
1428 for (int i = 0; i < a.length; i++) {
1429 float cc = c[i];
1430 float dd = d[i];
1431 r2[i] = cc + dd;
1432 r[i] = (a[i] > b[i]) ? cc : dd;
1433 }
1434 }
1435
1436 @Test
1437 @IR(failOn = {IRNode.STORE_VECTOR})
1438 private static void testCMoveLGEforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) {
1439 for (int i = 0; i < a.length; i++) {
1440 float cc = c[i];
1441 float dd = d[i];
1442 r2[i] = cc + dd;
1443 r[i] = (a[i] >= b[i]) ? cc : dd;
1444 }
1445 }
1446
1447 @Test
1448 @IR(failOn = {IRNode.STORE_VECTOR})
1449 private static void testCMoveLLTforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) {
1450 for (int i = 0; i < a.length; i++) {
1451 float cc = c[i];
1452 float dd = d[i];
1453 r2[i] = cc + dd;
1454 r[i] = (a[i] < b[i]) ? cc : dd;
1455 }
1456 }
1457
1458 @Test
1459 @IR(failOn = {IRNode.STORE_VECTOR})
1460 private static void testCMoveLLEforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) {
1461 for (int i = 0; i < a.length; i++) {
1462 float cc = c[i];
1463 float dd = d[i];
1464 r2[i] = cc + dd;
1465 r[i] = (a[i] <= b[i]) ? cc : dd;
1466 }
1467 }
1468
1469 // L fo D
1470 @Test
1471 @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1472 IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1473 IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1474 IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1475 IRNode.STORE_VECTOR, ">0"},
1476 applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
1477 // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4.
1478 private static void testCMoveLEQforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) {
1479 for (int i = 0; i < a.length; i++) {
1480 double cc = c[i];
1481 double dd = d[i];
1482 r2[i] = cc + dd;
1483 r[i] = (a[i] == b[i]) ? cc : dd;
1484 }
1485 }
1486
1487 @Test
1488 @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1489 IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1490 IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1491 IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1492 IRNode.STORE_VECTOR, ">0"},
1493 applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
1494 // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4.
1495 private static void testCMoveLNEforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) {
1496 for (int i = 0; i < a.length; i++) {
1497 double cc = c[i];
1498 double dd = d[i];
1499 r2[i] = cc + dd;
1500 r[i] = (a[i] != b[i]) ? cc : dd;
1501 }
1502 }
1503
1504 @Test
1505 @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1506 IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1507 IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1508 IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1509 IRNode.STORE_VECTOR, ">0"},
1510 applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
1511 // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4.
1512 private static void testCMoveLGTforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) {
1513 for (int i = 0; i < a.length; i++) {
1514 double cc = c[i];
1515 double dd = d[i];
1516 r2[i] = cc + dd;
1517 r[i] = (a[i] > b[i]) ? cc : dd;
1518 }
1519 }
1520
1521 @Test
1522 @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1523 IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1524 IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1525 IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1526 IRNode.STORE_VECTOR, ">0"},
1527 applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
1528 // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4.
1529 private static void testCMoveLGEforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) {
1530 for (int i = 0; i < a.length; i++) {
1531 double cc = c[i];
1532 double dd = d[i];
1533 r2[i] = cc + dd;
1534 r[i] = (a[i] >= b[i]) ? cc : dd;
1535 }
1536 }
1537
1538 @Test
1539 @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1540 IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1541 IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1542 IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1543 IRNode.STORE_VECTOR, ">0"},
1544 applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
1545 // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4.
1546 private static void testCMoveLLTforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) {
1547 for (int i = 0; i < a.length; i++) {
1548 double cc = c[i];
1549 double dd = d[i];
1550 r2[i] = cc + dd;
1551 r[i] = (a[i] < b[i]) ? cc : dd;
1552 }
1553 }
1554
1555 @Test
1556 @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1557 IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1558 IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1559 IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
1560 IRNode.STORE_VECTOR, ">0"},
1561 applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
1562 // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4.
1563 private static void testCMoveLLEforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) {
1564 for (int i = 0; i < a.length; i++) {
1565 double cc = c[i];
1566 double dd = d[i];
1567 r2[i] = cc + dd;
1568 r[i] = (a[i] <= b[i]) ? cc : dd;
1569 }
1570 }
1571
1572 // Unsigned comparison: I/L
1573 // I fo I
1574 @Test
1575 @IR(failOn = {IRNode.STORE_VECTOR})
1576 private static void testCMoveUIEQforI(int[] a, int[] b, int[] c, int[] d, int[] r, int[] r2) {
1577 for (int i = 0; i < a.length; i++) {
1578 int cc = c[i];
1579 int dd = d[i];
1580 r2[i] = cc + dd;
1581 r[i] = Integer.compareUnsigned(a[i], b[i]) == 0 ? cc : dd;
1582 }
1583 }
1584
1585 @Test
1586 @IR(failOn = {IRNode.STORE_VECTOR})
1587 private static void testCMoveUINEforI(int[] a, int[] b, int[] c, int[] d, int[] r, int[] r2) {
1588 for (int i = 0; i < a.length; i++) {
1589 int cc = c[i];
1590 int dd = d[i];
1591 r2[i] = cc + dd;
1592 r[i] = Integer.compareUnsigned(a[i], b[i]) != 0 ? cc : dd;
1593 }
1594 }
1595
1596 @Test
1597 @IR(failOn = {IRNode.STORE_VECTOR})
1598 private static void testCMoveUIGTforI(int[] a, int[] b, int[] c, int[] d, int[] r, int[] r2) {
1599 for (int i = 0; i < a.length; i++) {
1600 int cc = c[i];
1601 int dd = d[i];
1602 r2[i] = cc + dd;
1603 r[i] = Integer.compareUnsigned(a[i], b[i]) > 0 ? cc : dd;
1604 }
1605 }
1606
1607 @Test
1608 @IR(failOn = {IRNode.STORE_VECTOR})
1609 private static void testCMoveUIGEforI(int[] a, int[] b, int[] c, int[] d, int[] r, int[] r2) {
1610 for (int i = 0; i < a.length; i++) {
1611 int cc = c[i];
1612 int dd = d[i];
1613 r2[i] = cc + dd;
1614 r[i] = Integer.compareUnsigned(a[i], b[i]) >= 0 ? cc : dd;
1615 }
1616 }
1617
1618 @Test
1619 @IR(failOn = {IRNode.STORE_VECTOR})
1620 private static void testCMoveUILTforI(int[] a, int[] b, int[] c, int[] d, int[] r, int[] r2) {
1621 for (int i = 0; i < a.length; i++) {
1622 int cc = c[i];
1623 int dd = d[i];
1624 r2[i] = cc + dd;
1625 r[i] = Integer.compareUnsigned(a[i], b[i]) < 0 ? cc : dd;
1626 }
1627 }
1628
1629 @Test
1630 @IR(failOn = {IRNode.STORE_VECTOR})
1631 private static void testCMoveUILEforI(int[] a, int[] b, int[] c, int[] d, int[] r, int[] r2) {
1632 for (int i = 0; i < a.length; i++) {
1633 int cc = c[i];
1634 int dd = d[i];
1635 r2[i] = cc + dd;
1636 r[i] = Integer.compareUnsigned(a[i], b[i]) <= 0 ? cc : dd;
1637 }
1638 }
1639
1640 // I fo L
1641 @Test
1642 @IR(failOn = {IRNode.STORE_VECTOR})
1643 private static void testCMoveUIEQforL(int[] a, int[] b, long[] c, long[] d, long[] r, long[] r2) {
1644 for (int i = 0; i < a.length; i++) {
1645 long cc = c[i];
1646 long dd = d[i];
1647 r2[i] = cc + dd;
1648 r[i] = Integer.compareUnsigned(a[i], b[i]) == 0 ? cc : dd;
1649 }
1650 }
1651
1652 @Test
1653 @IR(failOn = {IRNode.STORE_VECTOR})
1654 private static void testCMoveUINEforL(int[] a, int[] b, long[] c, long[] d, long[] r, long[] r2) {
1655 for (int i = 0; i < a.length; i++) {
1656 long cc = c[i];
1657 long dd = d[i];
1658 r2[i] = cc + dd;
1659 r[i] = Integer.compareUnsigned(a[i], b[i]) != 0 ? cc : dd;
1660 }
1661 }
1662
1663 @Test
1664 @IR(failOn = {IRNode.STORE_VECTOR})
1665 private static void testCMoveUIGTforL(int[] a, int[] b, long[] c, long[] d, long[] r, long[] r2) {
1666 for (int i = 0; i < a.length; i++) {
1667 long cc = c[i];
1668 long dd = d[i];
1669 r2[i] = cc + dd;
1670 r[i] = Integer.compareUnsigned(a[i], b[i]) > 0 ? cc : dd;
1671 }
1672 }
1673
1674 @Test
1675 @IR(failOn = {IRNode.STORE_VECTOR})
1676 private static void testCMoveUIGEforL(int[] a, int[] b, long[] c, long[] d, long[] r, long[] r2) {
1677 for (int i = 0; i < a.length; i++) {
1678 long cc = c[i];
1679 long dd = d[i];
1680 r2[i] = cc + dd;
1681 r[i] = Integer.compareUnsigned(a[i], b[i]) >= 0 ? cc : dd;
1682 }
1683 }
1684
1685 @Test
1686 @IR(failOn = {IRNode.STORE_VECTOR})
1687 private static void testCMoveUILTforL(int[] a, int[] b, long[] c, long[] d, long[] r, long[] r2) {
1688 for (int i = 0; i < a.length; i++) {
1689 long cc = c[i];
1690 long dd = d[i];
1691 r2[i] = cc + dd;
1692 r[i] = Integer.compareUnsigned(a[i], b[i]) < 0 ? cc : dd;
1693 }
1694 }
1695
1696 @Test
1697 @IR(failOn = {IRNode.STORE_VECTOR})
1698 private static void testCMoveUILEforL(int[] a, int[] b, long[] c, long[] d, long[] r, long[] r2) {
1699 for (int i = 0; i < a.length; i++) {
1700 long cc = c[i];
1701 long dd = d[i];
1702 r2[i] = cc + dd;
1703 r[i] = Integer.compareUnsigned(a[i], b[i]) <= 0 ? cc : dd;
1704 }
1705 }
1706
1707 // I fo F
1708 @Test
1709 @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1710 IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1711 IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1712 IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1713 IRNode.STORE_VECTOR, ">0"},
1714 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
1715 private static void testCMoveUIEQforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) {
1716 for (int i = 0; i < a.length; i++) {
1717 float cc = c[i];
1718 float dd = d[i];
1719 r2[i] = cc + dd;
1720 r[i] = Integer.compareUnsigned(a[i], b[i]) == 0 ? cc : dd;
1721 }
1722 }
1723
1724 @Test
1725 @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1726 IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1727 IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1728 IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1729 IRNode.STORE_VECTOR, ">0"},
1730 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
1731 private static void testCMoveUINEforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) {
1732 for (int i = 0; i < a.length; i++) {
1733 float cc = c[i];
1734 float dd = d[i];
1735 r2[i] = cc + dd;
1736 r[i] = Integer.compareUnsigned(a[i], b[i]) != 0 ? cc : dd;
1737 }
1738 }
1739
1740 @Test
1741 @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1742 IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1743 IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1744 IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1745 IRNode.STORE_VECTOR, ">0"},
1746 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
1747 private static void testCMoveUIGTforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) {
1748 for (int i = 0; i < a.length; i++) {
1749 float cc = c[i];
1750 float dd = d[i];
1751 r2[i] = cc + dd;
1752 r[i] = Integer.compareUnsigned(a[i], b[i]) > 0 ? cc : dd;
1753 }
1754 }
1755
1756 @Test
1757 @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1758 IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1759 IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1760 IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1761 IRNode.STORE_VECTOR, ">0"},
1762 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
1763 private static void testCMoveUIGEforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) {
1764 for (int i = 0; i < a.length; i++) {
1765 float cc = c[i];
1766 float dd = d[i];
1767 r2[i] = cc + dd;
1768 r[i] = Integer.compareUnsigned(a[i], b[i]) >= 0 ? cc : dd;
1769 }
1770 }
1771
1772 @Test
1773 @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1774 IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1775 IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1776 IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1777 IRNode.STORE_VECTOR, ">0"},
1778 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
1779 private static void testCMoveUILTforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) {
1780 for (int i = 0; i < a.length; i++) {
1781 float cc = c[i];
1782 float dd = d[i];
1783 r2[i] = cc + dd;
1784 r[i] = Integer.compareUnsigned(a[i], b[i]) < 0 ? cc : dd;
1785 }
1786 }
1787
1788 @Test
1789 @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1790 IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1791 IRNode.VECTOR_MASK_CMP_I, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1792 IRNode.VECTOR_BLEND_F, IRNode.VECTOR_SIZE + "min(max_int, max_float)", ">0",
1793 IRNode.STORE_VECTOR, ">0"},
1794 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
1795 private static void testCMoveUILEforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) {
1796 for (int i = 0; i < a.length; i++) {
1797 float cc = c[i];
1798 float dd = d[i];
1799 r2[i] = cc + dd;
1800 r[i] = Integer.compareUnsigned(a[i], b[i]) <= 0 ? cc : dd;
1801 }
1802 }
1803
1804 // I fo D
1805 @Test
1806 @IR(failOn = {IRNode.STORE_VECTOR})
1807 private static void testCMoveUIEQforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) {
1808 for (int i = 0; i < a.length; i++) {
1809 double cc = c[i];
1810 double dd = d[i];
1811 r2[i] = cc + dd;
1812 r[i] = Integer.compareUnsigned(a[i], b[i]) == 0 ? cc : dd;
1813 }
1814 }
1815
1816 @Test
1817 @IR(failOn = {IRNode.STORE_VECTOR})
1818 private static void testCMoveUINEforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) {
1819 for (int i = 0; i < a.length; i++) {
1820 double cc = c[i];
1821 double dd = d[i];
1822 r2[i] = cc + dd;
1823 r[i] = Integer.compareUnsigned(a[i], b[i]) != 0 ? cc : dd;
1824 }
1825 }
1826
1827 @Test
1828 @IR(failOn = {IRNode.STORE_VECTOR})
1829 private static void testCMoveUIGTforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) {
1830 for (int i = 0; i < a.length; i++) {
1831 double cc = c[i];
1832 double dd = d[i];
1833 r2[i] = cc + dd;
1834 r[i] = Integer.compareUnsigned(a[i], b[i]) > 0 ? cc : dd;
1835 }
1836 }
1837
1838 @Test
1839 @IR(failOn = {IRNode.STORE_VECTOR})
1840 private static void testCMoveUIGEforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) {
1841 for (int i = 0; i < a.length; i++) {
1842 double cc = c[i];
1843 double dd = d[i];
1844 r2[i] = cc + dd;
1845 r[i] = Integer.compareUnsigned(a[i], b[i]) >= 0 ? cc : dd;
1846 }
1847 }
1848
1849 @Test
1850 @IR(failOn = {IRNode.STORE_VECTOR})
1851 private static void testCMoveUILTforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) {
1852 for (int i = 0; i < a.length; i++) {
1853 double cc = c[i];
1854 double dd = d[i];
1855 r2[i] = cc + dd;
1856 r[i] = Integer.compareUnsigned(a[i], b[i]) < 0 ? cc : dd;
1857 }
1858 }
1859
1860 @Test
1861 @IR(failOn = {IRNode.STORE_VECTOR})
1862 private static void testCMoveUILEforD(int[] a, int[] b, double[] c, double[] d, double[] r, double[] r2) {
1863 for (int i = 0; i < a.length; i++) {
1864 double cc = c[i];
1865 double dd = d[i];
1866 r2[i] = cc + dd;
1867 r[i] = Integer.compareUnsigned(a[i], b[i]) <= 0 ? cc : dd;
1868 }
1869 }
1870
1871 // L fo I
1872 @Test
1873 @IR(failOn = {IRNode.STORE_VECTOR})
1874 private static void testCMoveULEQforI(long[] a, long[] b, int[] c, int[] d, int[] r, int[] r2) {
1875 for (int i = 0; i < a.length; i++) {
1876 int cc = c[i];
1877 int dd = d[i];
1878 r2[i] = cc + dd;
1879 r[i] = Long.compareUnsigned(a[i], b[i]) == 0 ? cc : dd;
1880 }
1881 }
1882
1883 @Test
1884 @IR(failOn = {IRNode.STORE_VECTOR})
1885 private static void testCMoveULNEforI(long[] a, long[] b, int[] c, int[] d, int[] r, int[] r2) {
1886 for (int i = 0; i < a.length; i++) {
1887 int cc = c[i];
1888 int dd = d[i];
1889 r2[i] = cc + dd;
1890 r[i] = Long.compareUnsigned(a[i], b[i]) != 0 ? cc : dd;
1891 }
1892 }
1893
1894 @Test
1895 @IR(failOn = {IRNode.STORE_VECTOR})
1896 private static void testCMoveULGTforI(long[] a, long[] b, int[] c, int[] d, int[] r, int[] r2) {
1897 for (int i = 0; i < a.length; i++) {
1898 int cc = c[i];
1899 int dd = d[i];
1900 r2[i] = cc + dd;
1901 r[i] = Long.compareUnsigned(a[i], b[i]) > 0 ? cc : dd;
1902 }
1903 }
1904
1905 @Test
1906 @IR(failOn = {IRNode.STORE_VECTOR})
1907 private static void testCMoveULGEforI(long[] a, long[] b, int[] c, int[] d, int[] r, int[] r2) {
1908 for (int i = 0; i < a.length; i++) {
1909 int cc = c[i];
1910 int dd = d[i];
1911 r2[i] = cc + dd;
1912 r[i] = Long.compareUnsigned(a[i], b[i]) >= 0 ? cc : dd;
1913 }
1914 }
1915
1916 @Test
1917 @IR(failOn = {IRNode.STORE_VECTOR})
1918 private static void testCMoveULLTforI(long[] a, long[] b, int[] c, int[] d, int[] r, int[] r2) {
1919 for (int i = 0; i < a.length; i++) {
1920 int cc = c[i];
1921 int dd = d[i];
1922 r2[i] = cc + dd;
1923 r[i] = Long.compareUnsigned(a[i], b[i]) < 0 ? cc : dd;
1924 }
1925 }
1926
1927 @Test
1928 @IR(failOn = {IRNode.STORE_VECTOR})
1929 private static void testCMoveULLEforI(long[] a, long[] b, int[] c, int[] d, int[] r, int[] r2) {
1930 for (int i = 0; i < a.length; i++) {
1931 int cc = c[i];
1932 int dd = d[i];
1933 r2[i] = cc + dd;
1934 r[i] = Long.compareUnsigned(a[i], b[i]) <= 0 ? cc : dd;
1935 }
1936 }
1937
1938 // L fo L
1939 @Test
1940 @IR(failOn = {IRNode.STORE_VECTOR})
1941 private static void testCMoveULEQforL(long[] a, long[] b, long[] c, long[] d, long[] r, long[] r2) {
1942 for (int i = 0; i < a.length; i++) {
1943 long cc = c[i];
1944 long dd = d[i];
1945 r2[i] = cc + dd;
1946 r[i] = Long.compareUnsigned(a[i], b[i]) == 0 ? cc : dd;
1947 }
1948 }
1949
1950 @Test
1951 @IR(failOn = {IRNode.STORE_VECTOR})
1952 private static void testCMoveULNEforL(long[] a, long[] b, long[] c, long[] d, long[] r, long[] r2) {
1953 for (int i = 0; i < a.length; i++) {
1954 long cc = c[i];
1955 long dd = d[i];
1956 r2[i] = cc + dd;
1957 r[i] = Long.compareUnsigned(a[i], b[i]) != 0 ? cc : dd;
1958 }
1959 }
1960
1961 @Test
1962 @IR(failOn = {IRNode.STORE_VECTOR})
1963 private static void testCMoveULGTforL(long[] a, long[] b, long[] c, long[] d, long[] r, long[] r2) {
1964 for (int i = 0; i < a.length; i++) {
1965 long cc = c[i];
1966 long dd = d[i];
1967 r2[i] = cc + dd;
1968 r[i] = Long.compareUnsigned(a[i], b[i]) > 0 ? cc : dd;
1969 }
1970 }
1971
1972 @Test
1973 @IR(failOn = {IRNode.STORE_VECTOR})
1974 private static void testCMoveULGEforL(long[] a, long[] b, long[] c, long[] d, long[] r, long[] r2) {
1975 for (int i = 0; i < a.length; i++) {
1976 long cc = c[i];
1977 long dd = d[i];
1978 r2[i] = cc + dd;
1979 r[i] = Long.compareUnsigned(a[i], b[i]) >= 0 ? cc : dd;
1980 }
1981 }
1982
1983 @Test
1984 @IR(failOn = {IRNode.STORE_VECTOR})
1985 private static void testCMoveULLTforL(long[] a, long[] b, long[] c, long[] d, long[] r, long[] r2) {
1986 for (int i = 0; i < a.length; i++) {
1987 long cc = c[i];
1988 long dd = d[i];
1989 r2[i] = cc + dd;
1990 r[i] = Long.compareUnsigned(a[i], b[i]) < 0 ? cc : dd;
1991 }
1992 }
1993
1994 @Test
1995 @IR(failOn = {IRNode.STORE_VECTOR})
1996 private static void testCMoveULLEforL(long[] a, long[] b, long[] c, long[] d, long[] r, long[] r2) {
1997 for (int i = 0; i < a.length; i++) {
1998 long cc = c[i];
1999 long dd = d[i];
2000 r2[i] = cc + dd;
2001 r[i] = Long.compareUnsigned(a[i], b[i]) <= 0 ? cc : dd;
2002 }
2003 }
2004
2005 // L fo F
2006 @Test
2007 @IR(failOn = {IRNode.STORE_VECTOR})
2008 private static void testCMoveULEQforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) {
2009 for (int i = 0; i < a.length; i++) {
2010 float cc = c[i];
2011 float dd = d[i];
2012 r2[i] = cc + dd;
2013 r[i] = Long.compareUnsigned(a[i], b[i]) == 0 ? cc : dd;
2014 }
2015 }
2016
2017 @Test
2018 @IR(failOn = {IRNode.STORE_VECTOR})
2019 private static void testCMoveULNEforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) {
2020 for (int i = 0; i < a.length; i++) {
2021 float cc = c[i];
2022 float dd = d[i];
2023 r2[i] = cc + dd;
2024 r[i] = Long.compareUnsigned(a[i], b[i]) != 0 ? cc : dd;
2025 }
2026 }
2027
2028 @Test
2029 @IR(failOn = {IRNode.STORE_VECTOR})
2030 private static void testCMoveULGTforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) {
2031 for (int i = 0; i < a.length; i++) {
2032 float cc = c[i];
2033 float dd = d[i];
2034 r2[i] = cc + dd;
2035 r[i] = Long.compareUnsigned(a[i], b[i]) > 0 ? cc : dd;
2036 }
2037 }
2038
2039 @Test
2040 @IR(failOn = {IRNode.STORE_VECTOR})
2041 private static void testCMoveULGEforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) {
2042 for (int i = 0; i < a.length; i++) {
2043 float cc = c[i];
2044 float dd = d[i];
2045 r2[i] = cc + dd;
2046 r[i] = Long.compareUnsigned(a[i], b[i]) >= 0 ? cc : dd;
2047 }
2048 }
2049
2050 @Test
2051 @IR(failOn = {IRNode.STORE_VECTOR})
2052 private static void testCMoveULLTforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) {
2053 for (int i = 0; i < a.length; i++) {
2054 float cc = c[i];
2055 float dd = d[i];
2056 r2[i] = cc + dd;
2057 r[i] = Long.compareUnsigned(a[i], b[i]) < 0 ? cc : dd;
2058 }
2059 }
2060
2061 @Test
2062 @IR(failOn = {IRNode.STORE_VECTOR})
2063 private static void testCMoveULLEforF(long[] a, long[] b, float[] c, float[] d, float[] r, float[] r2) {
2064 for (int i = 0; i < a.length; i++) {
2065 float cc = c[i];
2066 float dd = d[i];
2067 r2[i] = cc + dd;
2068 r[i] = Long.compareUnsigned(a[i], b[i]) <= 0 ? cc : dd;
2069 }
2070 }
2071
2072 // L fo D
2073 @Test
2074 @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2075 IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2076 IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2077 IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2078 IRNode.STORE_VECTOR, ">0"},
2079 applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
2080 // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4.
2081 private static void testCMoveULEQforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) {
2082 for (int i = 0; i < a.length; i++) {
2083 double cc = c[i];
2084 double dd = d[i];
2085 r2[i] = cc + dd;
2086 r[i] = Long.compareUnsigned(a[i], b[i]) == 0 ? cc : dd;
2087 }
2088 }
2089
2090 @Test
2091 @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2092 IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2093 IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2094 IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2095 IRNode.STORE_VECTOR, ">0"},
2096 applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
2097 // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4.
2098 private static void testCMoveULNEforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) {
2099 for (int i = 0; i < a.length; i++) {
2100 double cc = c[i];
2101 double dd = d[i];
2102 r2[i] = cc + dd;
2103 r[i] = Long.compareUnsigned(a[i], b[i]) != 0 ? cc : dd;
2104 }
2105 }
2106
2107 @Test
2108 @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2109 IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2110 IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2111 IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2112 IRNode.STORE_VECTOR, ">0"},
2113 applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
2114 // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4.
2115 private static void testCMoveULGTforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) {
2116 for (int i = 0; i < a.length; i++) {
2117 double cc = c[i];
2118 double dd = d[i];
2119 r2[i] = cc + dd;
2120 r[i] = Long.compareUnsigned(a[i], b[i]) > 0 ? cc : dd;
2121 }
2122 }
2123
2124 @Test
2125 @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2126 IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2127 IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2128 IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2129 IRNode.STORE_VECTOR, ">0"},
2130 applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
2131 // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4.
2132 private static void testCMoveULGEforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) {
2133 for (int i = 0; i < a.length; i++) {
2134 double cc = c[i];
2135 double dd = d[i];
2136 r2[i] = cc + dd;
2137 r[i] = Long.compareUnsigned(a[i], b[i]) >= 0 ? cc : dd;
2138 }
2139 }
2140
2141 @Test
2142 @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2143 IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2144 IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2145 IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2146 IRNode.STORE_VECTOR, ">0"},
2147 applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
2148 // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4.
2149 private static void testCMoveULLTforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) {
2150 for (int i = 0; i < a.length; i++) {
2151 double cc = c[i];
2152 double dd = d[i];
2153 r2[i] = cc + dd;
2154 r[i] = Long.compareUnsigned(a[i], b[i]) < 0 ? cc : dd;
2155 }
2156 }
2157
2158 @Test
2159 @IR(counts = {IRNode.LOAD_VECTOR_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2160 IRNode.LOAD_VECTOR_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2161 IRNode.VECTOR_MASK_CMP_L, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2162 IRNode.VECTOR_BLEND_D, IRNode.VECTOR_SIZE + "min(max_long, max_double)", ">0",
2163 IRNode.STORE_VECTOR, ">0"},
2164 applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"})
2165 // Requires avx2, else L is restricted to 16 byte, and D has 32. That leads to a vector elements mismatch of 2 to 4.
2166 private static void testCMoveULLEforD(long[] a, long[] b, double[] c, double[] d, double[] r, double[] r2) {
2167 for (int i = 0; i < a.length; i++) {
2168 double cc = c[i];
2169 double dd = d[i];
2170 r2[i] = cc + dd;
2171 r[i] = Long.compareUnsigned(a[i], b[i]) <= 0 ? cc : dd;
2172 }
2173 }
2174
2175 @Test
2176 @IR(failOn = {IRNode.STORE_VECTOR})
2177 private static void testCMoveFGTforI(float[] a, float[] b, int[] c, int[] d, int[] r, int[] r2) {
2178 for (int i = 0; i < a.length; i++) {
2179 int cc = c[i];
2180 int dd = d[i];
2181 r2[i] = cc + dd;
2182 r[i] = (a[i] > b[i]) ? cc : dd;
2183 }
2184 }
2185
2186 @Test
2187 @IR(failOn = {IRNode.STORE_VECTOR})
2188 private static void testCMoveFGTforL(float[] a, float[] b, long[] c, long[] d, long[] r, long[] r2) {
2189 for (int i = 0; i < a.length; i++) {
2190 long cc = c[i];
2191 long dd = d[i];
2192 r2[i] = cc + dd;
2193 r[i] = (a[i] > b[i]) ? cc : dd;
2194 }
2195 }
2196
2197 @Test
2198 @IR(counts = {IRNode.LOAD_VECTOR_F, ">0",
2199 IRNode.VECTOR_MASK_CMP_F, ">0",
2200 IRNode.VECTOR_BLEND_F, ">0",
2201 IRNode.STORE_VECTOR, ">0"},
2202 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
2203 private static void testCMoveFGTforF(float[] a, float[] b, float[] c, float[] d, float[] r, float[] r2) {
2204 for (int i = 0; i < a.length; i++) {
2205 float cc = c[i];
2206 float dd = d[i];
2207 r2[i] = cc + dd;
2208 r[i] = (a[i] > b[i]) ? cc : dd;
2209 }
2210 }
2211
2212 @Test
2213 @IR(failOn = {IRNode.STORE_VECTOR})
2214 private static void testCMoveFGTforD(float[] a, float[] b, double[] c, double[] d, double[] r, double[] r2) {
2215 for (int i = 0; i < a.length; i++) {
2216 double cc = c[i];
2217 double dd = d[i];
2218 r2[i] = cc + dd;
2219 r[i] = (a[i] > b[i]) ? cc : dd;
2220 }
2221 }
2222
2223 @Test
2224 @IR(failOn = {IRNode.STORE_VECTOR})
2225 private static void testCMoveDGTforI(double[] a, double[] b, int[] c, int[] d, int[] r, int[] r2) {
2226 for (int i = 0; i < a.length; i++) {
2227 int cc = c[i];
2228 int dd = d[i];
2229 r2[i] = cc + dd;
2230 r[i] = (a[i] > b[i]) ? cc : dd;
2231 }
2232 }
2233
2234 @Test
2235 @IR(failOn = {IRNode.STORE_VECTOR})
2236 private static void testCMoveDGTforL(double[] a, double[] b, long[] c, long[] d, long[] r, long[] r2) {
2237 for (int i = 0; i < a.length; i++) {
2238 long cc = c[i];
2239 long dd = d[i];
2240 r2[i] = cc + dd;
2241 r[i] = (a[i] > b[i]) ? cc : dd;
2242 }
2243 }
2244
2245 @Test
2246 @IR(failOn = {IRNode.STORE_VECTOR})
2247 private static void testCMoveDGTforF(double[] a, double[] b, float[] c, float[] d, float[] r, float[] r2) {
2248 for (int i = 0; i < a.length; i++) {
2249 float cc = c[i];
2250 float dd = d[i];
2251 r2[i] = cc + dd;
2252 r[i] = (a[i] > b[i]) ? cc : dd;
2253 }
2254 }
2255
2256 @Test
2257 @IR(counts = {IRNode.LOAD_VECTOR_D, ">0",
2258 IRNode.VECTOR_MASK_CMP_D, ">0",
2259 IRNode.VECTOR_BLEND_D, ">0",
2260 IRNode.STORE_VECTOR, ">0"},
2261 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
2262 private static void testCMoveDGTforD(double[] a, double[] b, double[] c, double[] d, double[] r, double[] r2) {
2263 for (int i = 0; i < a.length; i++) {
2264 double cc = c[i];
2265 double dd = d[i];
2266 r2[i] = cc + dd;
2267 r[i] = (a[i] > b[i]) ? cc : dd;
2268 }
2269 }
2270
2271 // Use some constants in the comparison
2272 @Test
2273 @IR(counts = {IRNode.LOAD_VECTOR_F, ">0",
2274 IRNode.VECTOR_MASK_CMP_F, ">0",
2275 IRNode.VECTOR_BLEND_F, ">0",
2276 IRNode.STORE_VECTOR, ">0"},
2277 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
2278 private static void testCMoveFGTforFCmpCon1(float a, float[] b, float[] c, float[] d, float[] r, float[] r2) {
2279 for (int i = 0; i < b.length; i++) {
2280 float cc = c[i];
2281 float dd = d[i];
2282 r2[i] = cc + dd;
2283 r[i] = (a > b[i]) ? cc : dd;
2284 }
2285 }
2286
2287 @Test
2288 @IR(counts = {IRNode.LOAD_VECTOR_F, ">0",
2289 IRNode.VECTOR_MASK_CMP_F, ">0",
2290 IRNode.VECTOR_BLEND_F, ">0",
2291 IRNode.STORE_VECTOR, ">0"},
2292 applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"})
2293 private static void testCMoveFGTforFCmpCon2(float[] a, float b, float[] c, float[] d, float[] r, float[] r2) {
2294 for (int i = 0; i < a.length; i++) {
2295 float cc = c[i];
2296 float dd = d[i];
2297 r2[i] = cc + dd;
2298 r[i] = (a[i] > b) ? cc : dd;
2299 }
2300 }
2301
2302 // A case that is currently not supported and is not expected to vectorize
2303 @Test
2304 @IR(failOn = {IRNode.STORE_VECTOR})
2305 private static void testCMoveVDUnsupported() {
2306 double[] doublec = new double[SIZE];
2307 int seed = 1001;
2308 for (int i = 0; i < doublec.length; i++) {
2309 doublec[i] = (i % 2 == 0) ? seed + i : seed - i;
2310 }
2311 }
2312
2313 @Warmup(0)
2314 @Run(test = {"testCMoveVFGT", "testCMoveVFLT","testCMoveVDLE", "testCMoveVDGE", "testCMoveVFEQ", "testCMoveVDNE",
2315 "testCMoveVFGTSwap", "testCMoveVFLTSwap","testCMoveVDLESwap", "testCMoveVDGESwap",
2316 "testCMoveFGTforFConst", "testCMoveFGEforFConst", "testCMoveFLTforFConst",
2317 "testCMoveFLEforFConst", "testCMoveFEQforFConst", "testCMoveFNEQforFConst",
2318 "testCMoveDGTforDConst", "testCMoveDGEforDConst", "testCMoveDLTforDConst",
2319 "testCMoveDLEforDConst", "testCMoveDEQforDConst", "testCMoveDNEQforDConst",
2320 "testCMoveFLTforFConstH2", "testCMoveFLEforFConstH2",
2321 "testCMoveFYYforFConstH2", "testCMoveFXXforFConstH2",
2322 "testCMoveDLTforDConstH2", "testCMoveDLEforDConstH2",
2323 "testCMoveDYYforDConstH2", "testCMoveDXXforDConstH2"})
2324 private void testCMove_runner() {
2325 float[] floata = new float[SIZE];
2326 float[] floatb = new float[SIZE];
2327 float[] floatc = new float[SIZE];
2328 double[] doublea = new double[SIZE];
2329 double[] doubleb = new double[SIZE];
2330 double[] doublec = new double[SIZE];
2331
2332 init(floata);
2333 init(floatb);
2334 init(doublea);
2335 init(doubleb);
2336
2337 testCMoveVFGT(floata, floatb, floatc);
2338 testCMoveVDLE(doublea, doubleb, doublec);
2339 for (int i = 0; i < SIZE; i++) {
2340 Asserts.assertEquals(floatc[i], cmoveFloatGT(floata[i], floatb[i]));
2341 Asserts.assertEquals(doublec[i], cmoveDoubleLE(doublea[i], doubleb[i]));
2342 }
2343
2344 testCMoveVFLT(floata, floatb, floatc);
2345 testCMoveVDGE(doublea, doubleb, doublec);
2346 for (int i = 0; i < SIZE; i++) {
2347 Asserts.assertEquals(floatc[i], cmoveFloatLT(floata[i], floatb[i]));
2348 Asserts.assertEquals(doublec[i], cmoveDoubleGE(doublea[i], doubleb[i]));
2349 }
2350
2351 // Ensure we frequently have equals
2352 for (int i = 0; i < SIZE; i++) {
2353 if (i % 3 == 0) {
2354 floatb[i] = floata[i];
2355 doubleb[i] = doublea[i];
2356 }
2357 }
2358
2359 testCMoveVFEQ(floata, floatb, floatc);
2360 testCMoveVDNE(doublea, doubleb, doublec);
2361 for (int i = 0; i < SIZE; i++) {
2362 Asserts.assertEquals(floatc[i], cmoveFloatEQ(floata[i], floatb[i]));
2363 Asserts.assertEquals(doublec[i], cmoveDoubleNE(doublea[i], doubleb[i]));
2364 }
2365
2366 testCMoveVFGTSwap(floata, floatb, floatc);
2367 testCMoveVDLESwap(doublea, doubleb, doublec);
2368 for (int i = 0; i < SIZE; i++) {
2369 Asserts.assertEquals(floatc[i], cmoveFloatGTSwap(floata[i], floatb[i]));
2370 Asserts.assertEquals(doublec[i], cmoveDoubleLESwap(doublea[i], doubleb[i]));
2371 }
2372
2373 testCMoveVFLTSwap(floata, floatb, floatc);
2374 testCMoveVDGESwap(doublea, doubleb, doublec);
2375 for (int i = 0; i < SIZE; i++) {
2376 Asserts.assertEquals(floatc[i], cmoveFloatLTSwap(floata[i], floatb[i]));
2377 Asserts.assertEquals(doublec[i], cmoveDoubleGESwap(doublea[i], doubleb[i]));
2378 }
2379
2380 // Extensions: compare 2 values, and pick from 2 consts
2381 testCMoveFGTforFConst(floata, floatb, floatc);
2382 testCMoveDGTforDConst(doublea, doubleb, doublec);
2383 for (int i = 0; i < SIZE; i++) {
2384 Asserts.assertEquals(floatc[i], cmoveFGTforFConst(floata[i], floatb[i]));
2385 Asserts.assertEquals(doublec[i], cmoveDGTforDConst(doublea[i], doubleb[i]));
2386 }
2387
2388 testCMoveFGEforFConst(floata, floatb, floatc);
2389 testCMoveDGEforDConst(doublea, doubleb, doublec);
2390 for (int i = 0; i < SIZE; i++) {
2391 Asserts.assertEquals(floatc[i], cmoveFGEforFConst(floata[i], floatb[i]));
2392 Asserts.assertEquals(doublec[i], cmoveDGEforDConst(doublea[i], doubleb[i]));
2393 }
2394
2395 testCMoveFLTforFConst(floata, floatb, floatc);
2396 testCMoveDLTforDConst(doublea, doubleb, doublec);
2397 for (int i = 0; i < SIZE; i++) {
2398 Asserts.assertEquals(floatc[i], cmoveFLTforFConst(floata[i], floatb[i]));
2399 Asserts.assertEquals(doublec[i], cmoveDLTforDConst(doublea[i], doubleb[i]));
2400 }
2401
2402 testCMoveFLEforFConst(floata, floatb, floatc);
2403 testCMoveDLEforDConst(doublea, doubleb, doublec);
2404 for (int i = 0; i < SIZE; i++) {
2405 Asserts.assertEquals(floatc[i], cmoveFLEforFConst(floata[i], floatb[i]));
2406 Asserts.assertEquals(doublec[i], cmoveDLEforDConst(doublea[i], doubleb[i]));
2407 }
2408
2409 testCMoveFEQforFConst(floata, floatb, floatc);
2410 testCMoveDEQforDConst(doublea, doubleb, doublec);
2411 for (int i = 0; i < SIZE; i++) {
2412 Asserts.assertEquals(floatc[i], cmoveFEQforFConst(floata[i], floatb[i]));
2413 Asserts.assertEquals(doublec[i], cmoveDEQforDConst(doublea[i], doubleb[i]));
2414 }
2415
2416 testCMoveFNEQforFConst(floata, floatb, floatc);
2417 testCMoveDNEQforDConst(doublea, doubleb, doublec);
2418 for (int i = 0; i < SIZE; i++) {
2419 Asserts.assertEquals(floatc[i], cmoveFNEQforFConst(floata[i], floatb[i]));
2420 Asserts.assertEquals(doublec[i], cmoveDNEQforDConst(doublea[i], doubleb[i]));
2421 }
2422
2423 // Hand-unrolled (H2) examples:
2424 testCMoveFLTforFConstH2(floata, floatb, floatc);
2425 testCMoveDLTforDConstH2(doublea, doubleb, doublec);
2426 for (int i = 0; i < SIZE; i++) {
2427 Asserts.assertEquals(floatc[i], cmoveFLTforFConst(floata[i], floatb[i]));
2428 Asserts.assertEquals(doublec[i], cmoveDLTforDConst(doublea[i], doubleb[i]));
2429 }
2430
2431 testCMoveFLEforFConstH2(floata, floatb, floatc);
2432 testCMoveDLEforDConstH2(doublea, doubleb, doublec);
2433 for (int i = 0; i < SIZE; i++) {
2434 Asserts.assertEquals(floatc[i], cmoveFLEforFConst(floata[i], floatb[i]));
2435 Asserts.assertEquals(doublec[i], cmoveDLEforDConst(doublea[i], doubleb[i]));
2436 }
2437
2438 testCMoveFYYforFConstH2(floata, floatb, floatc);
2439 testCMoveDYYforDConstH2(doublea, doubleb, doublec);
2440 for (int i = 0; i < SIZE; i+=2) {
2441 Asserts.assertEquals(floatc[i+0], cmoveFLEforFConst(floata[i+0], floatb[i+0]));
2442 Asserts.assertEquals(doublec[i+0], cmoveDLEforDConst(doublea[i+0], doubleb[i+0]));
2443 Asserts.assertEquals(floatc[i+1], cmoveFLTforFConst(floata[i+1], floatb[i+1]));
2444 Asserts.assertEquals(doublec[i+1], cmoveDLTforDConst(doublea[i+1], doubleb[i+1]));
2445 }
2446
2447 testCMoveFXXforFConstH2(floata, floatb, floatc);
2448 testCMoveDXXforDConstH2(doublea, doubleb, doublec);
2449 for (int i = 0; i < SIZE; i+=2) {
2450 Asserts.assertEquals(floatc[i+0], cmoveFLTforFConst(floata[i+0], floatb[i+0]));
2451 Asserts.assertEquals(doublec[i+0], cmoveDLTforDConst(doublea[i+0], doubleb[i+0]));
2452 Asserts.assertEquals(floatc[i+1], cmoveFLEforFConst(floata[i+1], floatb[i+1]));
2453 Asserts.assertEquals(doublec[i+1], cmoveDLEforDConst(doublea[i+1], doubleb[i+1]));
2454 }
2455 }
2456
2457 @Warmup(0)
2458 @Run(test = {// Signed
2459 // I for I
2460 "testCMoveIEQforI",
2461 "testCMoveINEforI",
2462 "testCMoveIGTforI",
2463 "testCMoveIGEforI",
2464 "testCMoveILTforI",
2465 "testCMoveILEforI",
2466 // I for L
2467 "testCMoveIEQforL",
2468 "testCMoveINEforL",
2469 "testCMoveIGTforL",
2470 "testCMoveIGEforL",
2471 "testCMoveILTforL",
2472 "testCMoveILEforL",
2473 // I for F
2474 "testCMoveIEQforF",
2475 "testCMoveINEforF",
2476 "testCMoveIGTforF",
2477 "testCMoveIGEforF",
2478 "testCMoveILTforF",
2479 "testCMoveILEforF",
2480 // I for D
2481 "testCMoveIEQforD",
2482 "testCMoveINEforD",
2483 "testCMoveIGTforD",
2484 "testCMoveIGEforD",
2485 "testCMoveILTforD",
2486 "testCMoveILEforD",
2487 // L for I
2488 "testCMoveLEQforI",
2489 "testCMoveLNEforI",
2490 "testCMoveLGTforI",
2491 "testCMoveLGEforI",
2492 "testCMoveLLTforI",
2493 "testCMoveLLEforI",
2494 // L for L
2495 "testCMoveLEQforL",
2496 "testCMoveLNEforL",
2497 "testCMoveLGTforL",
2498 "testCMoveLGEforL",
2499 "testCMoveLLTforL",
2500 "testCMoveLLEforL",
2501 // L for F
2502 "testCMoveLEQforF",
2503 "testCMoveLNEforF",
2504 "testCMoveLGTforF",
2505 "testCMoveLGEforF",
2506 "testCMoveLLTforF",
2507 "testCMoveLLEforF",
2508 // L for D
2509 "testCMoveLEQforD",
2510 "testCMoveLNEforD",
2511 "testCMoveLGTforD",
2512 "testCMoveLGEforD",
2513 "testCMoveLLTforD",
2514 "testCMoveLLEforD",
2515 // Unsigned
2516 // I for I
2517 "testCMoveUIEQforI",
2518 "testCMoveUINEforI",
2519 "testCMoveUIGTforI",
2520 "testCMoveUIGEforI",
2521 "testCMoveUILTforI",
2522 "testCMoveUILEforI",
2523 // I for L
2524 "testCMoveUIEQforL",
2525 "testCMoveUINEforL",
2526 "testCMoveUIGTforL",
2527 "testCMoveUIGEforL",
2528 "testCMoveUILTforL",
2529 "testCMoveUILEforL",
2530 // I for F
2531 "testCMoveUIEQforF",
2532 "testCMoveUINEforF",
2533 "testCMoveUIGTforF",
2534 "testCMoveUIGEforF",
2535 "testCMoveUILTforF",
2536 "testCMoveUILEforF",
2537 // I for D
2538 "testCMoveUIEQforD",
2539 "testCMoveUINEforD",
2540 "testCMoveUIGTforD",
2541 "testCMoveUIGEforD",
2542 "testCMoveUILTforD",
2543 "testCMoveUILEforD",
2544 // L for I
2545 "testCMoveULEQforI",
2546 "testCMoveULNEforI",
2547 "testCMoveULGTforI",
2548 "testCMoveULGEforI",
2549 "testCMoveULLTforI",
2550 "testCMoveULLEforI",
2551 // L for L
2552 "testCMoveULEQforL",
2553 "testCMoveULNEforL",
2554 "testCMoveULGTforL",
2555 "testCMoveULGEforL",
2556 "testCMoveULLTforL",
2557 "testCMoveULLEforL",
2558 // L for F
2559 "testCMoveULEQforF",
2560 "testCMoveULNEforF",
2561 "testCMoveULGTforF",
2562 "testCMoveULGEforF",
2563 "testCMoveULLTforF",
2564 "testCMoveULLEforF",
2565 // L for D
2566 "testCMoveULEQforD",
2567 "testCMoveULNEforD",
2568 "testCMoveULGTforD",
2569 "testCMoveULGEforD",
2570 "testCMoveULLTforD",
2571 "testCMoveULLEforD",
2572 // Float
2573 "testCMoveFGTforI",
2574 "testCMoveFGTforL",
2575 "testCMoveFGTforF",
2576 "testCMoveFGTforD",
2577 "testCMoveDGTforI",
2578 "testCMoveDGTforL",
2579 "testCMoveDGTforF",
2580 "testCMoveDGTforD",
2581 "testCMoveFGTforFCmpCon1",
2582 "testCMoveFGTforFCmpCon2"})
2583 private void testCMove_runner_two() {
2584 int[] aI = new int[SIZE];
2585 int[] bI = new int[SIZE];
2586 int[] cI = new int[SIZE];
2587 int[] dI = new int[SIZE];
2588 int[] rI = new int[SIZE];
2589 long[] aL = new long[SIZE];
2590 long[] bL = new long[SIZE];
2591 long[] cL = new long[SIZE];
2592 long[] dL = new long[SIZE];
2593 long[] rL = new long[SIZE];
2594 float[] aF = new float[SIZE];
2595 float[] bF = new float[SIZE];
2596 float[] cF = new float[SIZE];
2597 float[] dF = new float[SIZE];
2598 float[] rF = new float[SIZE];
2599 double[] aD = new double[SIZE];
2600 double[] bD = new double[SIZE];
2601 double[] cD = new double[SIZE];
2602 double[] dD = new double[SIZE];
2603 double[] rD = new double[SIZE];
2604
2605 init(aI);
2606 init(bI);
2607 init(cI);
2608 init(dI);
2609 init(aL);
2610 init(bL);
2611 init(cL);
2612 init(dL);
2613 init(aF);
2614 init(bF);
2615 init(cF);
2616 init(dF);
2617 init(aD);
2618 init(bD);
2619 init(cD);
2620 init(dD);
2621
2622 // Signed
2623 // I for I
2624 testCMoveIEQforI(aI, bI, cI, dI, rI, rI);
2625 for (int i = 0; i < SIZE; i++) {
2626 Asserts.assertEquals(rI[i], cmoveIEQforI(aI[i], bI[i], cI[i], dI[i]));
2627 }
2628
2629 testCMoveINEforI(aI, bI, cI, dI, rI, rI);
2630 for (int i = 0; i < SIZE; i++) {
2631 Asserts.assertEquals(rI[i], cmoveINEforI(aI[i], bI[i], cI[i], dI[i]));
2632 }
2633
2634 testCMoveIGTforI(aI, bI, cI, dI, rI, rI);
2635 for (int i = 0; i < SIZE; i++) {
2636 Asserts.assertEquals(rI[i], cmoveIGTforI(aI[i], bI[i], cI[i], dI[i]));
2637 }
2638
2639 testCMoveIGEforI(aI, bI, cI, dI, rI, rI);
2640 for (int i = 0; i < SIZE; i++) {
2641 Asserts.assertEquals(rI[i], cmoveIGEforI(aI[i], bI[i], cI[i], dI[i]));
2642 }
2643
2644 testCMoveILTforI(aI, bI, cI, dI, rI, rI);
2645 for (int i = 0; i < SIZE; i++) {
2646 Asserts.assertEquals(rI[i], cmoveILTforI(aI[i], bI[i], cI[i], dI[i]));
2647 }
2648
2649 testCMoveILEforI(aI, bI, cI, dI, rI, rI);
2650 for (int i = 0; i < SIZE; i++) {
2651 Asserts.assertEquals(rI[i], cmoveILEforI(aI[i], bI[i], cI[i], dI[i]));
2652 }
2653
2654 // I for L
2655 testCMoveIEQforL(aI, bI, cL, dL, rL, rL);
2656 for (int i = 0; i < SIZE; i++) {
2657 Asserts.assertEquals(rL[i], cmoveIEQforL(aI[i], bI[i], cL[i], dL[i]));
2658 }
2659
2660 testCMoveINEforL(aI, bI, cL, dL, rL, rL);
2661 for (int i = 0; i < SIZE; i++) {
2662 Asserts.assertEquals(rL[i], cmoveINEforL(aI[i], bI[i], cL[i], dL[i]));
2663 }
2664
2665 testCMoveIGTforL(aI, bI, cL, dL, rL, rL);
2666 for (int i = 0; i < SIZE; i++) {
2667 Asserts.assertEquals(rL[i], cmoveIGTforL(aI[i], bI[i], cL[i], dL[i]));
2668 }
2669
2670 testCMoveIGEforL(aI, bI, cL, dL, rL, rL);
2671 for (int i = 0; i < SIZE; i++) {
2672 Asserts.assertEquals(rL[i], cmoveIGEforL(aI[i], bI[i], cL[i], dL[i]));
2673 }
2674
2675 testCMoveILTforL(aI, bI, cL, dL, rL, rL);
2676 for (int i = 0; i < SIZE; i++) {
2677 Asserts.assertEquals(rL[i], cmoveILTforL(aI[i], bI[i], cL[i], dL[i]));
2678 }
2679
2680 testCMoveILEforL(aI, bI, cL, dL, rL, rL);
2681 for (int i = 0; i < SIZE; i++) {
2682 Asserts.assertEquals(rL[i], cmoveILEforL(aI[i], bI[i], cL[i], dL[i]));
2683 }
2684
2685 // I for F
2686 testCMoveIEQforF(aI, bI, cF, dF, rF, rF);
2687 for (int i = 0; i < SIZE; i++) {
2688 Asserts.assertEquals(rF[i], cmoveIEQforF(aI[i], bI[i], cF[i], dF[i]));
2689 }
2690
2691 testCMoveINEforF(aI, bI, cF, dF, rF, rF);
2692 for (int i = 0; i < SIZE; i++) {
2693 Asserts.assertEquals(rF[i], cmoveINEforF(aI[i], bI[i], cF[i], dF[i]));
2694 }
2695
2696 testCMoveIGTforF(aI, bI, cF, dF, rF, rF);
2697 for (int i = 0; i < SIZE; i++) {
2698 Asserts.assertEquals(rF[i], cmoveIGTforF(aI[i], bI[i], cF[i], dF[i]));
2699 }
2700
2701 testCMoveIGEforF(aI, bI, cF, dF, rF, rF);
2702 for (int i = 0; i < SIZE; i++) {
2703 Asserts.assertEquals(rF[i], cmoveIGEforF(aI[i], bI[i], cF[i], dF[i]));
2704 }
2705
2706 testCMoveILTforF(aI, bI, cF, dF, rF, rF);
2707 for (int i = 0; i < SIZE; i++) {
2708 Asserts.assertEquals(rF[i], cmoveILTforF(aI[i], bI[i], cF[i], dF[i]));
2709 }
2710
2711 testCMoveILEforF(aI, bI, cF, dF, rF, rF);
2712 for (int i = 0; i < SIZE; i++) {
2713 Asserts.assertEquals(rF[i], cmoveILEforF(aI[i], bI[i], cF[i], dF[i]));
2714 }
2715
2716 // I for D
2717 testCMoveIEQforD(aI, bI, cD, dD, rD, rD);
2718 for (int i = 0; i < SIZE; i++) {
2719 Asserts.assertEquals(rD[i], cmoveIEQforD(aI[i], bI[i], cD[i], dD[i]));
2720 }
2721
2722 testCMoveINEforD(aI, bI, cD, dD, rD, rD);
2723 for (int i = 0; i < SIZE; i++) {
2724 Asserts.assertEquals(rD[i], cmoveINEforD(aI[i], bI[i], cD[i], dD[i]));
2725 }
2726
2727 testCMoveIGTforD(aI, bI, cD, dD, rD, rD);
2728 for (int i = 0; i < SIZE; i++) {
2729 Asserts.assertEquals(rD[i], cmoveIGTforD(aI[i], bI[i], cD[i], dD[i]));
2730 }
2731
2732 testCMoveIGEforD(aI, bI, cD, dD, rD, rD);
2733 for (int i = 0; i < SIZE; i++) {
2734 Asserts.assertEquals(rD[i], cmoveIGEforD(aI[i], bI[i], cD[i], dD[i]));
2735 }
2736
2737 testCMoveILTforD(aI, bI, cD, dD, rD, rD);
2738 for (int i = 0; i < SIZE; i++) {
2739 Asserts.assertEquals(rD[i], cmoveILTforD(aI[i], bI[i], cD[i], dD[i]));
2740 }
2741
2742 testCMoveILEforD(aI, bI, cD, dD, rD, rD);
2743 for (int i = 0; i < SIZE; i++) {
2744 Asserts.assertEquals(rD[i], cmoveILEforD(aI[i], bI[i], cD[i], dD[i]));
2745 }
2746
2747 // L for I
2748 testCMoveLEQforI(aL, bL, cI, dI, rI, rI);
2749 for (int i = 0; i < SIZE; i++) {
2750 Asserts.assertEquals(rI[i], cmoveLEQforI(aL[i], bL[i], cI[i], dI[i]));
2751 }
2752
2753 testCMoveLNEforI(aL, bL, cI, dI, rI, rI);
2754 for (int i = 0; i < SIZE; i++) {
2755 Asserts.assertEquals(rI[i], cmoveLNEforI(aL[i], bL[i], cI[i], dI[i]));
2756 }
2757
2758 testCMoveLGTforI(aL, bL, cI, dI, rI, rI);
2759 for (int i = 0; i < SIZE; i++) {
2760 Asserts.assertEquals(rI[i], cmoveLGTforI(aL[i], bL[i], cI[i], dI[i]));
2761 }
2762
2763 testCMoveLGEforI(aL, bL, cI, dI, rI, rI);
2764 for (int i = 0; i < SIZE; i++) {
2765 Asserts.assertEquals(rI[i], cmoveLGEforI(aL[i], bL[i], cI[i], dI[i]));
2766 }
2767
2768 testCMoveLLTforI(aL, bL, cI, dI, rI, rI);
2769 for (int i = 0; i < SIZE; i++) {
2770 Asserts.assertEquals(rI[i], cmoveLLTforI(aL[i], bL[i], cI[i], dI[i]));
2771 }
2772
2773 testCMoveLLEforI(aL, bL, cI, dI, rI, rI);
2774 for (int i = 0; i < SIZE; i++) {
2775 Asserts.assertEquals(rI[i], cmoveLLEforI(aL[i], bL[i], cI[i], dI[i]));
2776 }
2777
2778 // L for L
2779 testCMoveLEQforL(aL, bL, cL, dL, rL, rL);
2780 for (int i = 0; i < SIZE; i++) {
2781 Asserts.assertEquals(rL[i], cmoveLEQforL(aL[i], bL[i], cL[i], dL[i]));
2782 }
2783
2784 testCMoveLNEforL(aL, bL, cL, dL, rL, rL);
2785 for (int i = 0; i < SIZE; i++) {
2786 Asserts.assertEquals(rL[i], cmoveLNEforL(aL[i], bL[i], cL[i], dL[i]));
2787 }
2788
2789 testCMoveLGTforL(aL, bL, cL, dL, rL, rL);
2790 for (int i = 0; i < SIZE; i++) {
2791 Asserts.assertEquals(rL[i], cmoveLGTforL(aL[i], bL[i], cL[i], dL[i]));
2792 }
2793
2794 testCMoveLGEforL(aL, bL, cL, dL, rL, rL);
2795 for (int i = 0; i < SIZE; i++) {
2796 Asserts.assertEquals(rL[i], cmoveLGEforL(aL[i], bL[i], cL[i], dL[i]));
2797 }
2798
2799 testCMoveLLTforL(aL, bL, cL, dL, rL, rL);
2800 for (int i = 0; i < SIZE; i++) {
2801 Asserts.assertEquals(rL[i], cmoveLLTforL(aL[i], bL[i], cL[i], dL[i]));
2802 }
2803
2804 testCMoveLLEforL(aL, bL, cL, dL, rL, rL);
2805 for (int i = 0; i < SIZE; i++) {
2806 Asserts.assertEquals(rL[i], cmoveLLEforL(aL[i], bL[i], cL[i], dL[i]));
2807 }
2808
2809 // L for F
2810 testCMoveLEQforF(aL, bL, cF, dF, rF, rF);
2811 for (int i = 0; i < SIZE; i++) {
2812 Asserts.assertEquals(rF[i], cmoveLEQforF(aL[i], bL[i], cF[i], dF[i]));
2813 }
2814
2815 testCMoveLNEforF(aL, bL, cF, dF, rF, rF);
2816 for (int i = 0; i < SIZE; i++) {
2817 Asserts.assertEquals(rF[i], cmoveLNEforF(aL[i], bL[i], cF[i], dF[i]));
2818 }
2819
2820 testCMoveLGTforF(aL, bL, cF, dF, rF, rF);
2821 for (int i = 0; i < SIZE; i++) {
2822 Asserts.assertEquals(rF[i], cmoveLGTforF(aL[i], bL[i], cF[i], dF[i]));
2823 }
2824
2825 testCMoveLGEforF(aL, bL, cF, dF, rF, rF);
2826 for (int i = 0; i < SIZE; i++) {
2827 Asserts.assertEquals(rF[i], cmoveLGEforF(aL[i], bL[i], cF[i], dF[i]));
2828 }
2829
2830 testCMoveLLTforF(aL, bL, cF, dF, rF, rF);
2831 for (int i = 0; i < SIZE; i++) {
2832 Asserts.assertEquals(rF[i], cmoveLLTforF(aL[i], bL[i], cF[i], dF[i]));
2833 }
2834
2835 testCMoveLLEforF(aL, bL, cF, dF, rF, rF);
2836 for (int i = 0; i < SIZE; i++) {
2837 Asserts.assertEquals(rF[i], cmoveLLEforF(aL[i], bL[i], cF[i], dF[i]));
2838 }
2839
2840 // L for D
2841 testCMoveLEQforD(aL, bL, cD, dD, rD, rD);
2842 for (int i = 0; i < SIZE; i++) {
2843 Asserts.assertEquals(rD[i], cmoveLEQforD(aL[i], bL[i], cD[i], dD[i]));
2844 }
2845
2846 testCMoveLNEforD(aL, bL, cD, dD, rD, rD);
2847 for (int i = 0; i < SIZE; i++) {
2848 Asserts.assertEquals(rD[i], cmoveLNEforD(aL[i], bL[i], cD[i], dD[i]));
2849 }
2850
2851 testCMoveLGTforD(aL, bL, cD, dD, rD, rD);
2852 for (int i = 0; i < SIZE; i++) {
2853 Asserts.assertEquals(rD[i], cmoveLGTforD(aL[i], bL[i], cD[i], dD[i]));
2854 }
2855
2856 testCMoveLGEforD(aL, bL, cD, dD, rD, rD);
2857 for (int i = 0; i < SIZE; i++) {
2858 Asserts.assertEquals(rD[i], cmoveLGEforD(aL[i], bL[i], cD[i], dD[i]));
2859 }
2860
2861 testCMoveLLTforD(aL, bL, cD, dD, rD, rD);
2862 for (int i = 0; i < SIZE; i++) {
2863 Asserts.assertEquals(rD[i], cmoveLLTforD(aL[i], bL[i], cD[i], dD[i]));
2864 }
2865
2866 testCMoveLLEforD(aL, bL, cD, dD, rD, rD);
2867 for (int i = 0; i < SIZE; i++) {
2868 Asserts.assertEquals(rD[i], cmoveLLEforD(aL[i], bL[i], cD[i], dD[i]));
2869 }
2870
2871 // Unsigned
2872 // I for I
2873 testCMoveUIEQforI(aI, bI, cI, dI, rI, rI);
2874 for (int i = 0; i < SIZE; i++) {
2875 Asserts.assertEquals(rI[i], cmoveUIEQforI(aI[i], bI[i], cI[i], dI[i]));
2876 }
2877
2878 testCMoveUINEforI(aI, bI, cI, dI, rI, rI);
2879 for (int i = 0; i < SIZE; i++) {
2880 Asserts.assertEquals(rI[i], cmoveUINEforI(aI[i], bI[i], cI[i], dI[i]));
2881 }
2882
2883 testCMoveUIGTforI(aI, bI, cI, dI, rI, rI);
2884 for (int i = 0; i < SIZE; i++) {
2885 Asserts.assertEquals(rI[i], cmoveUIGTforI(aI[i], bI[i], cI[i], dI[i]));
2886 }
2887
2888 testCMoveUIGEforI(aI, bI, cI, dI, rI, rI);
2889 for (int i = 0; i < SIZE; i++) {
2890 Asserts.assertEquals(rI[i], cmoveUIGEforI(aI[i], bI[i], cI[i], dI[i]));
2891 }
2892
2893 testCMoveUILTforI(aI, bI, cI, dI, rI, rI);
2894 for (int i = 0; i < SIZE; i++) {
2895 Asserts.assertEquals(rI[i], cmoveUILTforI(aI[i], bI[i], cI[i], dI[i]));
2896 }
2897
2898 testCMoveUILEforI(aI, bI, cI, dI, rI, rI);
2899 for (int i = 0; i < SIZE; i++) {
2900 Asserts.assertEquals(rI[i], cmoveUILEforI(aI[i], bI[i], cI[i], dI[i]));
2901 }
2902
2903 // I for L
2904 testCMoveUIEQforL(aI, bI, cL, dL, rL, rL);
2905 for (int i = 0; i < SIZE; i++) {
2906 Asserts.assertEquals(rL[i], cmoveUIEQforL(aI[i], bI[i], cL[i], dL[i]));
2907 }
2908
2909 testCMoveUINEforL(aI, bI, cL, dL, rL, rL);
2910 for (int i = 0; i < SIZE; i++) {
2911 Asserts.assertEquals(rL[i], cmoveUINEforL(aI[i], bI[i], cL[i], dL[i]));
2912 }
2913
2914 testCMoveUIGTforL(aI, bI, cL, dL, rL, rL);
2915 for (int i = 0; i < SIZE; i++) {
2916 Asserts.assertEquals(rL[i], cmoveUIGTforL(aI[i], bI[i], cL[i], dL[i]));
2917 }
2918
2919 testCMoveUIGEforL(aI, bI, cL, dL, rL, rL);
2920 for (int i = 0; i < SIZE; i++) {
2921 Asserts.assertEquals(rL[i], cmoveUIGEforL(aI[i], bI[i], cL[i], dL[i]));
2922 }
2923
2924 testCMoveUILTforL(aI, bI, cL, dL, rL, rL);
2925 for (int i = 0; i < SIZE; i++) {
2926 Asserts.assertEquals(rL[i], cmoveUILTforL(aI[i], bI[i], cL[i], dL[i]));
2927 }
2928
2929 testCMoveUILEforL(aI, bI, cL, dL, rL, rL);
2930 for (int i = 0; i < SIZE; i++) {
2931 Asserts.assertEquals(rL[i], cmoveUILEforL(aI[i], bI[i], cL[i], dL[i]));
2932 }
2933
2934 // I for F
2935 testCMoveUIEQforF(aI, bI, cF, dF, rF, rF);
2936 for (int i = 0; i < SIZE; i++) {
2937 Asserts.assertEquals(rF[i], cmoveUIEQforF(aI[i], bI[i], cF[i], dF[i]));
2938 }
2939
2940 testCMoveUINEforF(aI, bI, cF, dF, rF, rF);
2941 for (int i = 0; i < SIZE; i++) {
2942 Asserts.assertEquals(rF[i], cmoveUINEforF(aI[i], bI[i], cF[i], dF[i]));
2943 }
2944
2945 testCMoveUIGTforF(aI, bI, cF, dF, rF, rF);
2946 for (int i = 0; i < SIZE; i++) {
2947 Asserts.assertEquals(rF[i], cmoveUIGTforF(aI[i], bI[i], cF[i], dF[i]));
2948 }
2949
2950 testCMoveUIGEforF(aI, bI, cF, dF, rF, rF);
2951 for (int i = 0; i < SIZE; i++) {
2952 Asserts.assertEquals(rF[i], cmoveUIGEforF(aI[i], bI[i], cF[i], dF[i]));
2953 }
2954
2955 testCMoveUILTforF(aI, bI, cF, dF, rF, rF);
2956 for (int i = 0; i < SIZE; i++) {
2957 Asserts.assertEquals(rF[i], cmoveUILTforF(aI[i], bI[i], cF[i], dF[i]));
2958 }
2959
2960 testCMoveUILEforF(aI, bI, cF, dF, rF, rF);
2961 for (int i = 0; i < SIZE; i++) {
2962 Asserts.assertEquals(rF[i], cmoveUILEforF(aI[i], bI[i], cF[i], dF[i]));
2963 }
2964
2965 // I for D
2966 testCMoveUIEQforD(aI, bI, cD, dD, rD, rD);
2967 for (int i = 0; i < SIZE; i++) {
2968 Asserts.assertEquals(rD[i], cmoveUIEQforD(aI[i], bI[i], cD[i], dD[i]));
2969 }
2970
2971 testCMoveUINEforD(aI, bI, cD, dD, rD, rD);
2972 for (int i = 0; i < SIZE; i++) {
2973 Asserts.assertEquals(rD[i], cmoveUINEforD(aI[i], bI[i], cD[i], dD[i]));
2974 }
2975
2976 testCMoveUIGTforD(aI, bI, cD, dD, rD, rD);
2977 for (int i = 0; i < SIZE; i++) {
2978 Asserts.assertEquals(rD[i], cmoveUIGTforD(aI[i], bI[i], cD[i], dD[i]));
2979 }
2980
2981 testCMoveUIGEforD(aI, bI, cD, dD, rD, rD);
2982 for (int i = 0; i < SIZE; i++) {
2983 Asserts.assertEquals(rD[i], cmoveUIGEforD(aI[i], bI[i], cD[i], dD[i]));
2984 }
2985
2986 testCMoveUILTforD(aI, bI, cD, dD, rD, rD);
2987 for (int i = 0; i < SIZE; i++) {
2988 Asserts.assertEquals(rD[i], cmoveUILTforD(aI[i], bI[i], cD[i], dD[i]));
2989 }
2990
2991 testCMoveUILEforD(aI, bI, cD, dD, rD, rD);
2992 for (int i = 0; i < SIZE; i++) {
2993 Asserts.assertEquals(rD[i], cmoveUILEforD(aI[i], bI[i], cD[i], dD[i]));
2994 }
2995
2996 // L for I
2997 testCMoveULEQforI(aL, bL, cI, dI, rI, rI);
2998 for (int i = 0; i < SIZE; i++) {
2999 Asserts.assertEquals(rI[i], cmoveULEQforI(aL[i], bL[i], cI[i], dI[i]));
3000 }
3001
3002 testCMoveULNEforI(aL, bL, cI, dI, rI, rI);
3003 for (int i = 0; i < SIZE; i++) {
3004 Asserts.assertEquals(rI[i], cmoveULNEforI(aL[i], bL[i], cI[i], dI[i]));
3005 }
3006
3007 testCMoveULGTforI(aL, bL, cI, dI, rI, rI);
3008 for (int i = 0; i < SIZE; i++) {
3009 Asserts.assertEquals(rI[i], cmoveULGTforI(aL[i], bL[i], cI[i], dI[i]));
3010 }
3011
3012 testCMoveULGEforI(aL, bL, cI, dI, rI, rI);
3013 for (int i = 0; i < SIZE; i++) {
3014 Asserts.assertEquals(rI[i], cmoveULGEforI(aL[i], bL[i], cI[i], dI[i]));
3015 }
3016
3017 testCMoveULLTforI(aL, bL, cI, dI, rI, rI);
3018 for (int i = 0; i < SIZE; i++) {
3019 Asserts.assertEquals(rI[i], cmoveULLTforI(aL[i], bL[i], cI[i], dI[i]));
3020 }
3021
3022 testCMoveULLEforI(aL, bL, cI, dI, rI, rI);
3023 for (int i = 0; i < SIZE; i++) {
3024 Asserts.assertEquals(rI[i], cmoveULLEforI(aL[i], bL[i], cI[i], dI[i]));
3025 }
3026
3027 // L for L
3028 testCMoveULEQforL(aL, bL, cL, dL, rL, rL);
3029 for (int i = 0; i < SIZE; i++) {
3030 Asserts.assertEquals(rL[i], cmoveULEQforL(aL[i], bL[i], cL[i], dL[i]));
3031 }
3032
3033 testCMoveULNEforL(aL, bL, cL, dL, rL, rL);
3034 for (int i = 0; i < SIZE; i++) {
3035 Asserts.assertEquals(rL[i], cmoveULNEforL(aL[i], bL[i], cL[i], dL[i]));
3036 }
3037
3038 testCMoveULGTforL(aL, bL, cL, dL, rL, rL);
3039 for (int i = 0; i < SIZE; i++) {
3040 Asserts.assertEquals(rL[i], cmoveULGTforL(aL[i], bL[i], cL[i], dL[i]));
3041 }
3042
3043 testCMoveULGEforL(aL, bL, cL, dL, rL, rL);
3044 for (int i = 0; i < SIZE; i++) {
3045 Asserts.assertEquals(rL[i], cmoveULGEforL(aL[i], bL[i], cL[i], dL[i]));
3046 }
3047
3048 testCMoveULLTforL(aL, bL, cL, dL, rL, rL);
3049 for (int i = 0; i < SIZE; i++) {
3050 Asserts.assertEquals(rL[i], cmoveULLTforL(aL[i], bL[i], cL[i], dL[i]));
3051 }
3052
3053 testCMoveULLEforL(aL, bL, cL, dL, rL, rL);
3054 for (int i = 0; i < SIZE; i++) {
3055 Asserts.assertEquals(rL[i], cmoveULLEforL(aL[i], bL[i], cL[i], dL[i]));
3056 }
3057
3058 // L for F
3059 testCMoveULEQforF(aL, bL, cF, dF, rF, rF);
3060 for (int i = 0; i < SIZE; i++) {
3061 Asserts.assertEquals(rF[i], cmoveULEQforF(aL[i], bL[i], cF[i], dF[i]));
3062 }
3063
3064 testCMoveULNEforF(aL, bL, cF, dF, rF, rF);
3065 for (int i = 0; i < SIZE; i++) {
3066 Asserts.assertEquals(rF[i], cmoveULNEforF(aL[i], bL[i], cF[i], dF[i]));
3067 }
3068
3069 testCMoveULGTforF(aL, bL, cF, dF, rF, rF);
3070 for (int i = 0; i < SIZE; i++) {
3071 Asserts.assertEquals(rF[i], cmoveULGTforF(aL[i], bL[i], cF[i], dF[i]));
3072 }
3073
3074 testCMoveULGEforF(aL, bL, cF, dF, rF, rF);
3075 for (int i = 0; i < SIZE; i++) {
3076 Asserts.assertEquals(rF[i], cmoveULGEforF(aL[i], bL[i], cF[i], dF[i]));
3077 }
3078
3079 testCMoveULLTforF(aL, bL, cF, dF, rF, rF);
3080 for (int i = 0; i < SIZE; i++) {
3081 Asserts.assertEquals(rF[i], cmoveULLTforF(aL[i], bL[i], cF[i], dF[i]));
3082 }
3083
3084 testCMoveULLEforF(aL, bL, cF, dF, rF, rF);
3085 for (int i = 0; i < SIZE; i++) {
3086 Asserts.assertEquals(rF[i], cmoveULLEforF(aL[i], bL[i], cF[i], dF[i]));
3087 }
3088
3089 // L for D
3090 testCMoveULEQforD(aL, bL, cD, dD, rD, rD);
3091 for (int i = 0; i < SIZE; i++) {
3092 Asserts.assertEquals(rD[i], cmoveULEQforD(aL[i], bL[i], cD[i], dD[i]));
3093 }
3094
3095 testCMoveULNEforD(aL, bL, cD, dD, rD, rD);
3096 for (int i = 0; i < SIZE; i++) {
3097 Asserts.assertEquals(rD[i], cmoveULNEforD(aL[i], bL[i], cD[i], dD[i]));
3098 }
3099
3100 testCMoveULGTforD(aL, bL, cD, dD, rD, rD);
3101 for (int i = 0; i < SIZE; i++) {
3102 Asserts.assertEquals(rD[i], cmoveULGTforD(aL[i], bL[i], cD[i], dD[i]));
3103 }
3104
3105 testCMoveULGEforD(aL, bL, cD, dD, rD, rD);
3106 for (int i = 0; i < SIZE; i++) {
3107 Asserts.assertEquals(rD[i], cmoveULGEforD(aL[i], bL[i], cD[i], dD[i]));
3108 }
3109
3110 testCMoveULLTforD(aL, bL, cD, dD, rD, rD);
3111 for (int i = 0; i < SIZE; i++) {
3112 Asserts.assertEquals(rD[i], cmoveULLTforD(aL[i], bL[i], cD[i], dD[i]));
3113 }
3114
3115 testCMoveULLEforD(aL, bL, cD, dD, rD, rD);
3116 for (int i = 0; i < SIZE; i++) {
3117 Asserts.assertEquals(rD[i], cmoveULLEforD(aL[i], bL[i], cD[i], dD[i]));
3118 }
3119
3120 // Float
3121 testCMoveFGTforI(aF, bF, cI, dI, rI, rI);
3122 for (int i = 0; i < SIZE; i++) {
3123 Asserts.assertEquals(rI[i], cmoveFGTforI(aF[i], bF[i], cI[i], dI[i]));
3124 }
3125
3126 testCMoveFGTforL(aF, bF, cL, dL, rL, rL);
3127 for (int i = 0; i < SIZE; i++) {
3128 Asserts.assertEquals(rL[i], cmoveFGTforL(aF[i], bF[i], cL[i], dL[i]));
3129 }
3130
3131 testCMoveFGTforF(aF, bF, cF, dF, rF, rF);
3132 for (int i = 0; i < SIZE; i++) {
3133 Asserts.assertEquals(rF[i], cmoveFGTforF(aF[i], bF[i], cF[i], dF[i]));
3134 }
3135
3136 testCMoveFGTforD(aF, bF, cD, dD, rD, rD);
3137 for (int i = 0; i < SIZE; i++) {
3138 Asserts.assertEquals(rD[i], cmoveFGTforD(aF[i], bF[i], cD[i], dD[i]));
3139 }
3140
3141 testCMoveDGTforI(aD, bD, cI, dI, rI, rI);
3142 for (int i = 0; i < SIZE; i++) {
3143 Asserts.assertEquals(rI[i], cmoveDGTforI(aD[i], bD[i], cI[i], dI[i]));
3144 }
3145
3146 testCMoveDGTforL(aD, bD, cL, dL, rL, rL);
3147 for (int i = 0; i < SIZE; i++) {
3148 Asserts.assertEquals(rL[i], cmoveDGTforL(aD[i], bD[i], cL[i], dL[i]));
3149 }
3150
3151 testCMoveDGTforF(aD, bD, cF, dF, rF, rF);
3152 for (int i = 0; i < SIZE; i++) {
3153 Asserts.assertEquals(rF[i], cmoveDGTforF(aD[i], bD[i], cF[i], dF[i]));
3154 }
3155
3156 testCMoveDGTforD(aD, bD, cD, dD, rD, rD);
3157 for (int i = 0; i < SIZE; i++) {
3158 Asserts.assertEquals(rD[i], cmoveDGTforD(aD[i], bD[i], cD[i], dD[i]));
3159 }
3160
3161 // Use some constants/invariants in the comparison
3162 testCMoveFGTforFCmpCon1(aF[0], bF, cF, dF, rF, rF);
3163 for (int i = 0; i < SIZE; i++) {
3164 Asserts.assertEquals(rF[i], cmoveFGTforF(aF[0], bF[i], cF[i], dF[i]));
3165 }
3166
3167 testCMoveFGTforFCmpCon2(aF, bF[0], cF, dF, rF, rF);
3168 for (int i = 0; i < SIZE; i++) {
3169 Asserts.assertEquals(rF[i], cmoveFGTforF(aF[i], bF[0], cF[i], dF[i]));
3170 }
3171 }
3172
3173 private static void init(int[] a) {
3174 for (int i = 0; i < SIZE; i++) {
3175 a[i] = RANDOM.nextInt();
3176 }
3177 }
3178
3179 private static void init(long[] a) {
3180 for (int i = 0; i < SIZE; i++) {
3181 a[i] = RANDOM.nextLong();
3182 }
3183 }
3184
3185 private static void init(float[] a) {
3186 for (int i = 0; i < SIZE; i++) {
3187 a[i] = switch(RANDOM.nextInt() % 20) {
3188 case 0 -> Float.NaN;
3189 case 1 -> 0;
3190 case 2 -> 1;
3191 case 3 -> Float.POSITIVE_INFINITY;
3192 case 4 -> Float.NEGATIVE_INFINITY;
3193 case 5 -> Float.MAX_VALUE;
3194 case 6 -> Float.MIN_VALUE;
3195 case 7, 8, 9 -> RANDOM.nextFloat();
3196 default -> Float.intBitsToFloat(RANDOM.nextInt());
3197 };
3198 }
3199 }
3200
3201 private static void init(double[] a) {
3202 for (int i = 0; i < SIZE; i++) {
3203 a[i] = switch(RANDOM.nextInt() % 20) {
3204 case 0 -> Double.NaN;
3205 case 1 -> 0;
3206 case 2 -> 1;
3207 case 3 -> Double.POSITIVE_INFINITY;
3208 case 4 -> Double.NEGATIVE_INFINITY;
3209 case 5 -> Double.MAX_VALUE;
3210 case 6 -> Double.MIN_VALUE;
3211 case 7, 8, 9 -> RANDOM.nextDouble();
3212 default -> Double.longBitsToDouble(RANDOM.nextLong());
3213 };
3214 }
3215 }
3216 }