Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8275317: AArch64: Support some type conversion vectorization in SLP #6145

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -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"
})