2
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
27
* @summary Test forced vectorization, and check IR for vector instructions
28
* @requires vm.compiler2.enabled
29
* @library /test/lib /
30
* @run driver compiler.vectorization.TestOptionVectorizeIR
33
package compiler.vectorization;
34
import compiler.lib.ir_framework.*;
36
public class TestOptionVectorizeIR {
37
static int RANGE = 1024*2;
38
static int ITER = 100;
39
int[] gold1 = new int[RANGE];
40
int[] gold2 = new int[RANGE];
41
int[] gold3 = new int[RANGE];
42
int[] gold4 = new int[RANGE];
43
int[] gold5 = new int[RANGE];
44
int[] gold6 = new int[RANGE];
46
long[] gold10 = new long[RANGE];
47
long[] gold11 = new long[RANGE];
48
long[] gold12 = new long[RANGE];
49
long[] gold13 = new long[RANGE];
51
short[] gold20 = new short[RANGE];
52
short[] gold21 = new short[RANGE];
53
short[] gold22 = new short[RANGE];
54
short[] gold23 = new short[RANGE];
56
byte[] gold30 = new byte[RANGE];
57
byte[] gold31 = new byte[RANGE];
58
byte[] gold32 = new byte[RANGE];
59
byte[] gold33 = new byte[RANGE];
61
char[] gold40 = new char[RANGE];
62
char[] gold41 = new char[RANGE];
63
char[] gold42 = new char[RANGE];
64
char[] gold43 = new char[RANGE];
66
float[] gold50 = new float[RANGE];
67
float[] gold51 = new float[RANGE];
68
float[] gold52 = new float[RANGE];
69
float[] gold53 = new float[RANGE];
71
double[] gold60 = new double[RANGE];
72
double[] gold61 = new double[RANGE];
73
double[] gold62 = new double[RANGE];
74
double[] gold63 = new double[RANGE];
76
public static void main(String args[]) {
77
TestFramework.runWithFlags("-XX:CompileCommand=option,compiler.vectorization.TestOptionVectorizeIR::test*,Vectorize");
80
TestOptionVectorizeIR() {
81
// compute the gold standard in interpreter mode
163
public void runTest1() {
164
int[] data = new int[RANGE];
166
verify("test1", data, gold1);
171
public void runTest2() {
172
int[] data = new int[RANGE];
175
verify("test2", data, gold2);
180
public void runTest3() {
181
int[] data = new int[RANGE];
184
verify("test3", data, gold3);
189
public void runTest4() {
190
int[] data = new int[RANGE];
193
verify("test4", data, gold4);
198
public void runTest5() {
199
int[] data = new int[RANGE];
202
verify("test5", data, gold5);
207
public void runTest6() {
208
int[] data = new int[RANGE];
211
verify("test6", data, gold6);
215
static void test1(int[] data) {
216
for (int j = 0; j < RANGE; j++) {
217
// Vectorizes even if it is not forced
223
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.ADD_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
224
applyIf = {"AlignVector", "false"},
225
applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
226
static void test2(int[] data) {
227
for (int j = 0; j < RANGE - 1; j++) {
228
// Only vectorizes if forced, because of offset by 1
229
data[j] = data[j] + data[j + 1];
234
@IR(counts = {IRNode.LOAD_VECTOR_I, "> 0", IRNode.REPLICATE_I, "> 0", IRNode.ADD_VI, "> 0", IRNode.MUL_VI, "> 0", IRNode.STORE_VECTOR, "> 0"},
235
applyIf = {"AlignVector", "false"},
236
applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
237
static void test3(int[] data, int A, int B) {
238
for (int j = 0; j < RANGE - 1; j++) {
239
// Only vectorizes if forced, because of offset by 1
240
data[j] = A * data[j] + B * data[j + 1];
245
static void test4(int[] data) {
246
for (int j = 0; j < RANGE - 1; j++) {
247
// write forward -> cyclic dependency -> cannot vectorize
248
// independent(s1, s2) for adjacent loads should detect this
249
data[j + 1] = data[j];
254
static void test5(int[] data) {
255
for (int j = 0; j < RANGE - 3; j++) {
256
// write forward -> cyclic dependency -> cannot vectorize
257
// independent(s1, s2) for adjacent loads cannot detect this
258
// Checks with memory_alignment are disabled via compile option
259
data[j + 2] = data[j];
264
static void test6(int[] data) {
265
for (int j = 0; j < RANGE - 3; j++) {
266
// write forward -> cyclic dependency -> cannot vectorize
267
// independent(s1, s2) for adjacent loads cannot detect this
268
// Checks with memory_alignment are disabled via compile option
269
data[j + 3] = data[j];
273
// ------------------------- Long -----------------------------
276
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
277
applyIf = {"AlignVector", "false"},
278
applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
279
static void test10(long[] data) {
280
for (int j = 2; j < RANGE - 2; j++) {
281
data[j] += data[j + 2];
286
@IR(counts = {IRNode.LOAD_VECTOR_L, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"},
287
applyIf = {"AlignVector", "false"},
288
applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
289
static void test11(long[] data) {
290
for (int j = 2; j < RANGE - 2; j++) {
291
data[j] += data[j + 1];
296
static void test12(long[] data) {
297
for (int j = 2; j < RANGE - 2; j++) {
298
data[j] += data[j - 1];
303
static void test13(long[] data) {
304
// 128-bit vectors -> can vectorize because only 2 elements
305
for (int j = 2; j < RANGE - 2; j++) {
306
data[j] += data[j - 2];
310
@Run(test = "test10")
312
public void runTest10() {
313
long[] data = new long[RANGE];
316
verify("test10", data, gold10);
319
@Run(test = "test11")
321
public void runTest11() {
322
long[] data = new long[RANGE];
325
verify("test11", data, gold11);
328
@Run(test = "test12")
330
public void runTest12() {
331
long[] data = new long[RANGE];
334
verify("test12", data, gold12);
337
@Run(test = "test13")
339
public void runTest13() {
340
long[] data = new long[RANGE];
343
verify("test13", data, gold13);
347
// ------------------------- Short -----------------------------
350
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.ADD_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
351
applyIf = {"AlignVector", "false"},
352
applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
353
static void test20(short[] data) {
354
for (int j = 2; j < RANGE - 2; j++) {
355
data[j] += data[j + 2];
360
@IR(counts = {IRNode.LOAD_VECTOR_S, "> 0", IRNode.ADD_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
361
applyIf = {"AlignVector", "false"},
362
applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
363
static void test21(short[] data) {
364
for (int j = 2; j < RANGE - 2; j++) {
365
data[j] += data[j + 1];
370
static void test22(short[] data) {
371
for (int j = 2; j < RANGE - 2; j++) {
372
data[j] += data[j - 1];
377
static void test23(short[] data) {
378
for (int j = 2; j < RANGE - 2; j++) {
379
data[j] += data[j - 2];
383
@Run(test = "test20")
385
public void runTest20() {
386
short[] data = new short[RANGE];
389
verify("test20", data, gold20);
392
@Run(test = "test21")
394
public void runTest21() {
395
short[] data = new short[RANGE];
398
verify("test21", data, gold21);
401
@Run(test = "test22")
403
public void runTest22() {
404
short[] data = new short[RANGE];
407
verify("test22", data, gold22);
410
@Run(test = "test23")
412
public void runTest23() {
413
short[] data = new short[RANGE];
416
verify("test23", data, gold23);
420
// ------------------------- Byte -----------------------------
423
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.ADD_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
424
applyIf = {"AlignVector", "false"},
425
applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
426
static void test30(byte[] data) {
427
for (int j = 2; j < RANGE - 2; j++) {
428
data[j] += data[j + 2];
433
@IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.ADD_VB, "> 0", IRNode.STORE_VECTOR, "> 0"},
434
applyIf = {"AlignVector", "false"},
435
applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
436
static void test31(byte[] data) {
437
for (int j = 2; j < RANGE - 2; j++) {
438
data[j] += data[j + 1];
443
static void test32(byte[] data) {
444
for (int j = 2; j < RANGE - 2; j++) {
445
data[j] += data[j - 1];
450
static void test33(byte[] data) {
451
for (int j = 2; j < RANGE - 2; j++) {
452
data[j] += data[j - 2];
456
@Run(test = "test30")
458
public void runTest30() {
459
byte[] data = new byte[RANGE];
462
verify("test30", data, gold30);
465
@Run(test = "test31")
467
public void runTest31() {
468
byte[] data = new byte[RANGE];
471
verify("test31", data, gold31);
474
@Run(test = "test32")
476
public void runTest32() {
477
byte[] data = new byte[RANGE];
480
verify("test32", data, gold32);
483
@Run(test = "test33")
485
public void runTest33() {
486
byte[] data = new byte[RANGE];
489
verify("test33", data, gold33);
493
// ------------------------- Char -----------------------------
496
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.ADD_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
497
applyIf = {"AlignVector", "false"},
498
applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
499
static void test40(char[] data) {
500
for (int j = 2; j < RANGE - 2; j++) {
501
data[j] += data[j + 2];
506
@IR(counts = {IRNode.LOAD_VECTOR_C, "> 0", IRNode.ADD_VS, "> 0", IRNode.STORE_VECTOR, "> 0"},
507
applyIf = {"AlignVector", "false"},
508
applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
509
static void test41(char[] data) {
510
for (int j = 2; j < RANGE - 2; j++) {
511
data[j] += data[j + 1];
516
static void test42(char[] data) {
517
for (int j = 2; j < RANGE - 2; j++) {
518
data[j] += data[j - 1];
523
static void test43(char[] data) {
524
for (int j = 2; j < RANGE - 2; j++) {
525
data[j] += data[j - 2];
529
@Run(test = "test40")
531
public void runTest40() {
532
char[] data = new char[RANGE];
535
verify("test40", data, gold40);
538
@Run(test = "test41")
540
public void runTest41() {
541
char[] data = new char[RANGE];
544
verify("test41", data, gold41);
547
@Run(test = "test42")
549
public void runTest42() {
550
char[] data = new char[RANGE];
553
verify("test42", data, gold42);
556
@Run(test = "test43")
558
public void runTest43() {
559
char[] data = new char[RANGE];
562
verify("test43", data, gold43);
565
// ------------------------- Float -----------------------------
568
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.ADD_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
569
applyIf = {"AlignVector", "false"},
570
applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
571
static void test50(float[] data) {
572
for (int j = 2; j < RANGE - 2; j++) {
573
data[j] += data[j + 2];
578
@IR(counts = {IRNode.LOAD_VECTOR_F, "> 0", IRNode.ADD_VF, "> 0", IRNode.STORE_VECTOR, "> 0"},
579
applyIf = {"AlignVector", "false"},
580
applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
581
static void test51(float[] data) {
582
for (int j = 2; j < RANGE - 2; j++) {
583
data[j] += data[j + 1];
588
static void test52(float[] data) {
589
for (int j = 2; j < RANGE - 2; j++) {
590
data[j] += data[j - 1];
595
static void test53(float[] data) {
596
for (int j = 2; j < RANGE - 2; j++) {
597
data[j] += data[j - 2];
601
@Run(test = "test50")
603
public void runTest50() {
604
float[] data = new float[RANGE];
607
verify("test50", data, gold50);
610
@Run(test = "test51")
612
public void runTest51() {
613
float[] data = new float[RANGE];
616
verify("test51", data, gold51);
619
@Run(test = "test52")
621
public void runTest52() {
622
float[] data = new float[RANGE];
625
verify("test52", data, gold52);
628
@Run(test = "test53")
630
public void runTest53() {
631
float[] data = new float[RANGE];
634
verify("test53", data, gold53);
637
// ------------------------- Double -----------------------------
640
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.ADD_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
641
applyIf = {"AlignVector", "false"},
642
applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
643
static void test60(double[] data) {
644
for (int j = 2; j < RANGE - 2; j++) {
645
data[j] += data[j + 2];
650
@IR(counts = {IRNode.LOAD_VECTOR_D, "> 0", IRNode.ADD_VD, "> 0", IRNode.STORE_VECTOR, "> 0"},
651
applyIf = {"AlignVector", "false"},
652
applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
653
static void test61(double[] data) {
654
for (int j = 2; j < RANGE - 2; j++) {
655
data[j] += data[j + 1];
660
static void test62(double[] data) {
661
for (int j = 2; j < RANGE - 2; j++) {
662
data[j] += data[j - 1];
667
static void test63(double[] data) {
668
// 128-bit vectors -> can vectorize because only 2 elements
669
for (int j = 2; j < RANGE - 2; j++) {
670
data[j] += data[j - 2];
674
@Run(test = "test60")
676
public void runTest60() {
677
double[] data = new double[RANGE];
680
verify("test60", data, gold60);
683
@Run(test = "test61")
685
public void runTest61() {
686
double[] data = new double[RANGE];
689
verify("test61", data, gold61);
692
@Run(test = "test62")
694
public void runTest62() {
695
double[] data = new double[RANGE];
698
verify("test62", data, gold62);
701
@Run(test = "test63")
703
public void runTest63() {
704
double[] data = new double[RANGE];
707
verify("test63", data, gold63);
710
static void init(long[] data) {
711
for (int j = 0; j < RANGE; j++) {
716
static void init(short[] data) {
717
for (int j = 0; j < RANGE; j++) {
722
static void init(byte[] data) {
723
for (int j = 0; j < RANGE; j++) {
728
static void init(char[] data) {
729
for (int j = 0; j < RANGE; j++) {
735
static void init(float[] data) {
736
for (int j = 0; j < RANGE; j++) {
742
static void init(double[] data) {
743
for (int j = 0; j < RANGE; j++) {
748
static void verify(String name, int[] data, int[] gold) {
749
for (int i = 0; i < RANGE; i++) {
750
if (data[i] != gold[i]) {
751
throw new RuntimeException(" Invalid " + name + " result: data[" + i + "]: " + data[i] + " != " + gold[i]);
756
static void verify(String name, long[] data, long[] gold) {
757
for (int i = 0; i < RANGE; i++) {
758
if (data[i] != gold[i]) {
759
throw new RuntimeException(" Invalid " + name + " result: data[" + i + "]: " + data[i] + " != " + gold[i]);
764
static void verify(String name, short[] data, short[] gold) {
765
for (int i = 0; i < RANGE; i++) {
766
if (data[i] != gold[i]) {
767
throw new RuntimeException(" Invalid " + name + " result: data[" + i + "]: " + data[i] + " != " + gold[i]);
772
static void verify(String name, byte[] data, byte[] gold) {
773
for (int i = 0; i < RANGE; i++) {
774
if (data[i] != gold[i]) {
775
throw new RuntimeException(" Invalid " + name + " result: data[" + i + "]: " + data[i] + " != " + gold[i]);
780
static void verify(String name, char[] data, char[] gold) {
781
for (int i = 0; i < RANGE; i++) {
782
if (data[i] != gold[i]) {
783
throw new RuntimeException(" Invalid " + name + " result: data[" + i + "]: " + data[i] + " != " + gold[i]);
788
static void verify(String name, float[] data, float[] gold) {
789
for (int i = 0; i < RANGE; i++) {
790
if (data[i] != gold[i]) {
791
throw new RuntimeException(" Invalid " + name + " result: data[" + i + "]: " + data[i] + " != " + gold[i]);
796
static void verify(String name, double[] data, double[] gold) {
797
for (int i = 0; i < RANGE; i++) {
798
if (data[i] != gold[i]) {
799
throw new RuntimeException(" Invalid " + name + " result: data[" + i + "]: " + data[i] + " != " + gold[i]);