Skip to content
Permalink
Browse files
8275317: AArch64: Support some type conversion vectorization in SLP
Reviewed-by: thartmann, ngasson
  • Loading branch information
Faye Gao authored and TobiHartmann committed Nov 17, 2021
1 parent 08f65a5 commit 9aa30de4bb55357ddf0900e6103062f02e85753b
Showing 5 changed files with 229 additions and 5 deletions.
@@ -2558,6 +2558,14 @@ void SuperWord::output() {
Node* in = vector_opd(p, 1);
vn = VectorNode::make(opc, in, NULL, vlen, velt_basic_type(n));
vlen_in_bytes = vn->as_Vector()->length_in_bytes();
} else if (opc == Op_ConvI2F || opc == Op_ConvL2D ||
opc == Op_ConvF2I || opc == Op_ConvD2L) {
assert(n->req() == 2, "only one input expected");
BasicType bt = velt_basic_type(n);
int vopc = VectorNode::opcode(opc, bt);
Node* in = vector_opd(p, 1);
vn = VectorCastNode::make(vopc, in, bt, vlen);
vlen_in_bytes = vn->as_Vector()->length_in_bytes();
} else if (is_cmov_pack(p)) {
if (can_process_post_loop) {
// do not refactor of flow in post loop context
@@ -224,6 +224,14 @@ int VectorNode::opcode(int sopc, BasicType bt) {
return Op_StoreVector;
case Op_MulAddS2I:
return Op_MulAddVS2VI;
case Op_ConvI2F:
return Op_VectorCastI2X;
case Op_ConvL2D:
return Op_VectorCastL2X;
case Op_ConvF2I:
return Op_VectorCastF2X;
case Op_ConvD2L:
return Op_VectorCastD2X;

default:
return 0; // Unimplemented
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@ static int test() {
test_vi_unaln(a1, b1, (int)123, 103.f);
test_cp_unalndst(a1, a2, b1, b2);
test_cp_unalnsrc(a1, a2, b1, b2);
test_conv_i2f(a1, b1);
test_conv_f2i(a1, b1);
}
// Initialize
for (int i=0; i<ARRLEN; i++) {
@@ -338,6 +340,72 @@ static int test() {
errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (int)v);
errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (float)v);
}
// Reset to test conversion from int to float.
for (int i=0; i<ARRLEN; i++) {
a1[i] = (int)i;
}
test_conv_i2f(a1, b1);
for (int i=0; i<ARRLEN; i++) {
errn += verify("test_conv_i2f: a1", i, b1[i], (float)i);
}
// Reset to test conversion from float to int.
for (int i=0; i<ARRLEN; i++) {
b1[i] = (float)(i+1);
}
test_conv_f2i(a1, b1);
for (int i=0; i<ARRLEN; i++) {
errn += verify("test_conv_f2i: a1", i, a1[i], (i+1));
}
// Reset to test NAN conversion from int to float.
for (int i=0; i<ARRLEN; i++) {
a1[i] = Integer.MIN_VALUE;
}
test_conv_i2f(a1, b1);
for (int i=0; i<ARRLEN; i++) {
errn += verify("test_conv_i2f: a1", i, b1[i], (float)Integer.MIN_VALUE);
}
for (int i=0; i<ARRLEN; i++) {
a1[i] = Integer.MAX_VALUE;
}
test_conv_i2f(a1, b1);
for (int i=0; i<ARRLEN; i++) {
errn += verify("test_conv_i2f: a1", i, b1[i], (float)Integer.MAX_VALUE);
}
for (int i=0; i<ARRLEN; i++) {
b1[i] = Float.NaN;
}
test_conv_f2i(a1, b1);
for (int i=0; i<ARRLEN; i++) {
errn += verify("test_conv_f2i: a1", i, a1[i], (int)Float.NaN);
}
for (int i=0; i<ARRLEN; i++) {
b1[i] = Float.POSITIVE_INFINITY;
}
test_conv_f2i(a1, b1);
for (int i=0; i<ARRLEN; i++) {
errn += verify("test_conv_f2i: a1", i, a1[i], (int)Float.POSITIVE_INFINITY);
}
for (int i=0; i<ARRLEN; i++) {
b1[i] = Float.NEGATIVE_INFINITY;
}
test_conv_f2i(a1, b1);
for (int i=0; i<ARRLEN; i++) {
errn += verify("test_conv_f2i: a1", i, a1[i], (int)Float.NEGATIVE_INFINITY);
}
for (int i=0; i<ARRLEN; i++) {
b1[i] = 0.0f;
}
test_conv_f2i(a1, b1);
for (int i=0; i<ARRLEN; i++) {
errn += verify("test_conv_f2i: a1", i, a1[i], (int)0.0);
}
for (int i=0; i<ARRLEN; i++) {
b1[i] = -0.0f;
}
test_conv_f2i(a1, b1);
for (int i=0; i<ARRLEN; i++) {
errn += verify("test_conv_f2i: a1", i, a1[i], (int)(-0.0));
}

}

@@ -448,6 +516,18 @@ static int test() {
}
end = System.currentTimeMillis();
System.out.println("test_cp_unalnsrc: " + (end - start));
start = System.currentTimeMillis();
for (int i=0; i<ITERS; i++) {
test_conv_i2f(a1, b1);
}
end = System.currentTimeMillis();
System.out.println("test_conv_i2f: " + (end - start));
start = System.currentTimeMillis();
for (int i=0; i<ITERS; i++) {
test_conv_f2i(a1, b1);
}
end = System.currentTimeMillis();
System.out.println("test_conv_f2i: " + (end - start));
return errn;
}

@@ -556,6 +636,16 @@ static void test_cp_unalnsrc(int[] a, int[] b, float[] c, float[] d) {
c[i] = d[i+UNALIGN_OFF];
}
}
static void test_conv_i2f(int[] a, float[] b){
for (int i = 0; i < a.length; i+=1) {
b[i] = (float)a[i];
}
}
static void test_conv_f2i(int[] a, float[] b){
for (int i = 0; i < a.length; i+=1) {
a[i] = (int)b[i];
}
}

static int verify(String text, int i, int elem, int val) {
if (elem != val) {
@@ -565,7 +655,7 @@ static int verify(String text, int i, int elem, int val) {
return 0;
}
static int verify(String text, int i, float elem, float val) {
if (elem != val) {
if (elem != val && !(Float.isNaN(elem) && Float.isNaN(val))) {
System.err.println(text + "[" + i + "] = " + elem + " != " + val);
return 1;
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,8 @@ static int test() {
test_vi_unaln(a1, b1, (long)123, 103.);
test_cp_unalndst(a1, a2, b1, b2);
test_cp_unalnsrc(a1, a2, b1, b2);
test_conv_l2d(a1, b1);
test_conv_d2l(a1, b1);
}
// Initialize
for (int i=0; i<ARRLEN; i++) {
@@ -338,6 +340,72 @@ static int test() {
errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (long)v);
errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (double)v);
}
// Reset to test conversion from int to float.
for (int i=0; i<ARRLEN; i++) {
a1[i] = (long)i;
}
test_conv_l2d(a1, b1);
for (int i=0; i<ARRLEN; i++) {
errn += verify("test_conv_l2d: a1", i, b1[i], (double)i);
}
// Reset to test conversion from float to int.
for (int i=0; i<ARRLEN; i++) {
b1[i] = (double)(i+1);
}
test_conv_d2l(a1, b1);
for (int i=0; i<ARRLEN; i++) {
errn += verify("test_conv_d2l: a1", i, a1[i], (long)(i+1));
}
// Reset to test special conversion from int to float.
for (int i=0; i<ARRLEN; i++) {
b1[i] = Double.NaN;
}
test_conv_d2l(a1, b1);
for (int i=0; i<ARRLEN; i++) {
errn += verify("test_conv_d2l: a1", i, a1[i], (long)Double.NaN);
}
for (int i=0; i<ARRLEN; i++) {
a1[i] = Long.MIN_VALUE;
}
test_conv_l2d(a1, b1);
for (int i=0; i<ARRLEN; i++) {
errn += verify("test_conv_l2d: a1", i, b1[i], (double)Long.MIN_VALUE);
}
for (int i=0; i<ARRLEN; i++) {
a1[i] = Long.MAX_VALUE;
}
test_conv_l2d(a1, b1);
for (int i=0; i<ARRLEN; i++) {
errn += verify("test_conv_l2d: a1", i, b1[i], (double)Long.MAX_VALUE);
}
for (int i=0; i<ARRLEN; i++) {
b1[i] = Double.POSITIVE_INFINITY;
}
test_conv_d2l(a1, b1);
for (int i=0; i<ARRLEN; i++) {
errn += verify("test_conv_d2l: a1", i, a1[i], (long)Double.POSITIVE_INFINITY);
}
for (int i=0; i<ARRLEN; i++) {
b1[i] = Double.NEGATIVE_INFINITY;
}
test_conv_d2l(a1, b1);
for (int i=0; i<ARRLEN; i++) {
errn += verify("test_conv_d2l: a1", i, a1[i], (long)Double.NEGATIVE_INFINITY);
}
for (int i=0; i<ARRLEN; i++) {
b1[i] = 0.0;
}
test_conv_d2l(a1, b1);
for (int i=0; i<ARRLEN; i++) {
errn += verify("test_conv_d2l: a1", i, a1[i], (long)0.0);
}
for (int i=0; i<ARRLEN; i++) {
b1[i] = -0.0;
}
test_conv_d2l(a1, b1);
for (int i=0; i<ARRLEN; i++) {
errn += verify("test_conv_d2l: a1", i, a1[i], (long)(-0.0));
}

}

@@ -448,6 +516,18 @@ static int test() {
}
end = System.currentTimeMillis();
System.out.println("test_cp_unalnsrc: " + (end - start));
start = System.currentTimeMillis();
for (int i=0; i<ITERS; i++) {
test_conv_l2d(a1, b1);
}
end = System.currentTimeMillis();
System.out.println("test_conv_l2d: " + (end - start));
start = System.currentTimeMillis();
for (int i=0; i<ITERS; i++) {
test_conv_d2l(a1, b1);
}
end = System.currentTimeMillis();
System.out.println("test_conv_d2l: " + (end - start));
return errn;
}

@@ -556,6 +636,16 @@ static void test_cp_unalnsrc(long[] a, long[] b, double[] c, double[] d) {
c[i] = d[i+UNALIGN_OFF];
}
}
static void test_conv_l2d(long[] a, double[] b){
for (int i = 0; i < a.length; i+=1) {
b[i] = (double)a[i];
}
}
static void test_conv_d2l(long[] a, double[] b){
for (int i = 0; i < a.length; i+=1) {
a[i] = (long)b[i];
}
}

static int verify(String text, int i, long elem, long val) {
if (elem != val) {
@@ -565,7 +655,7 @@ static int verify(String text, int i, long elem, long val) {
return 0;
}
static int verify(String text, int i, double elem, double val) {
if (elem != val) {
if (elem != val && !(Double.isNaN(elem) && Double.isNaN(val))) {
System.err.println(text + "[" + i + "] = " + elem + " != " + val);
return 1;
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -195,6 +195,34 @@ public void negD() {
}
}

@Benchmark
public void convert_i2f() {
for (int i = 0; i < COUNT; i++) {
resF[i] = (float) ints[i];
}
}

@Benchmark
public void convert_f2i() {
for (int i = 0; i < COUNT; i++) {
resI[i] = (int) floats[i];
}
}

@Benchmark
public void convert_l2d() {
for (int i = 0; i < COUNT; i++) {
resD[i] = (double) longs[i];
}
}

@Benchmark
public void convert_d2l() {
for (int i = 0; i < COUNT; i++) {
resL[i] = (long) doubles[i];
}
}

@Fork(value = 1, jvmArgsPrepend = {
"-XX:+UseSuperWord"
})

1 comment on commit 9aa30de

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 9aa30de Nov 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.