8275317: AArch64: Support some type conversion vectorization in SLP
Reviewed-by: thartmann, ngasson
This commit is contained in:
parent
08f65a59a7
commit
9aa30de4bb
@ -2558,6 +2558,14 @@ void SuperWord::output() {
|
|||||||
Node* in = vector_opd(p, 1);
|
Node* in = vector_opd(p, 1);
|
||||||
vn = VectorNode::make(opc, in, NULL, vlen, velt_basic_type(n));
|
vn = VectorNode::make(opc, in, NULL, vlen, velt_basic_type(n));
|
||||||
vlen_in_bytes = vn->as_Vector()->length_in_bytes();
|
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)) {
|
} else if (is_cmov_pack(p)) {
|
||||||
if (can_process_post_loop) {
|
if (can_process_post_loop) {
|
||||||
// do not refactor of flow in post loop context
|
// do not refactor of flow in post loop context
|
||||||
|
@ -224,6 +224,14 @@ int VectorNode::opcode(int sopc, BasicType bt) {
|
|||||||
return Op_StoreVector;
|
return Op_StoreVector;
|
||||||
case Op_MulAddS2I:
|
case Op_MulAddS2I:
|
||||||
return Op_MulAddVS2VI;
|
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:
|
default:
|
||||||
return 0; // Unimplemented
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -75,6 +75,8 @@ public class TestIntFloatVect {
|
|||||||
test_vi_unaln(a1, b1, (int)123, 103.f);
|
test_vi_unaln(a1, b1, (int)123, 103.f);
|
||||||
test_cp_unalndst(a1, a2, b1, b2);
|
test_cp_unalndst(a1, a2, b1, b2);
|
||||||
test_cp_unalnsrc(a1, a2, b1, b2);
|
test_cp_unalnsrc(a1, a2, b1, b2);
|
||||||
|
test_conv_i2f(a1, b1);
|
||||||
|
test_conv_f2i(a1, b1);
|
||||||
}
|
}
|
||||||
// Initialize
|
// Initialize
|
||||||
for (int i=0; i<ARRLEN; i++) {
|
for (int i=0; i<ARRLEN; i++) {
|
||||||
@ -338,6 +340,72 @@ public class TestIntFloatVect {
|
|||||||
errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (int)v);
|
errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (int)v);
|
||||||
errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (float)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 @@ public class TestIntFloatVect {
|
|||||||
}
|
}
|
||||||
end = System.currentTimeMillis();
|
end = System.currentTimeMillis();
|
||||||
System.out.println("test_cp_unalnsrc: " + (end - start));
|
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;
|
return errn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -556,6 +636,16 @@ public class TestIntFloatVect {
|
|||||||
c[i] = d[i+UNALIGN_OFF];
|
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) {
|
static int verify(String text, int i, int elem, int val) {
|
||||||
if (elem != val) {
|
if (elem != val) {
|
||||||
@ -565,7 +655,7 @@ public class TestIntFloatVect {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static int verify(String text, int i, float elem, float val) {
|
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);
|
System.err.println(text + "[" + i + "] = " + elem + " != " + val);
|
||||||
return 1;
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -75,6 +75,8 @@ public class TestLongDoubleVect {
|
|||||||
test_vi_unaln(a1, b1, (long)123, 103.);
|
test_vi_unaln(a1, b1, (long)123, 103.);
|
||||||
test_cp_unalndst(a1, a2, b1, b2);
|
test_cp_unalndst(a1, a2, b1, b2);
|
||||||
test_cp_unalnsrc(a1, a2, b1, b2);
|
test_cp_unalnsrc(a1, a2, b1, b2);
|
||||||
|
test_conv_l2d(a1, b1);
|
||||||
|
test_conv_d2l(a1, b1);
|
||||||
}
|
}
|
||||||
// Initialize
|
// Initialize
|
||||||
for (int i=0; i<ARRLEN; i++) {
|
for (int i=0; i<ARRLEN; i++) {
|
||||||
@ -338,6 +340,72 @@ public class TestLongDoubleVect {
|
|||||||
errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (long)v);
|
errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (long)v);
|
||||||
errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (double)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 @@ public class TestLongDoubleVect {
|
|||||||
}
|
}
|
||||||
end = System.currentTimeMillis();
|
end = System.currentTimeMillis();
|
||||||
System.out.println("test_cp_unalnsrc: " + (end - start));
|
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;
|
return errn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -556,6 +636,16 @@ public class TestLongDoubleVect {
|
|||||||
c[i] = d[i+UNALIGN_OFF];
|
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) {
|
static int verify(String text, int i, long elem, long val) {
|
||||||
if (elem != val) {
|
if (elem != val) {
|
||||||
@ -565,7 +655,7 @@ public class TestLongDoubleVect {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static int verify(String text, int i, double elem, double val) {
|
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);
|
System.err.println(text + "[" + i + "] = " + elem + " != " + val);
|
||||||
return 1;
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -195,6 +195,34 @@ public abstract class TypeVectorOperations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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 = {
|
@Fork(value = 1, jvmArgsPrepend = {
|
||||||
"-XX:+UseSuperWord"
|
"-XX:+UseSuperWord"
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user