For the following Vector API case:
static byte[] a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
static byte[] b = new byte[16];
static byte[] c = new byte[16];
private static void func(boolean print) {
ByteVector av = ByteVector.fromArray(SPECIES_128, a, 0);
ByteVector bv = (ByteVector)av.reinterpretShape(SPECIES_64, 0);
bv.intoArray(b, 0);
ByteVector cv = (ByteVector)bv.reinterpretShape(SPECIES_128, 0);
cv.intoArray(c, 0)���
}
It first reinterprets vector from "SPECIES_128" to "SPECIES_64" and then reinterprets back to "SPECIES_128"; The final results in array "b" and "c" are expected to be:
b = [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0]
c = [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0]
However, the current results with C2 is:
b = [ 0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0]
c = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
The results in array "c" is not right which should be zeros for the higher parts. This issue happens both on x86 and aarch64 platform.
The root cause is the incorrect optimization for "VectorReinterpretNode". See the codes below:
Node* VectorReinterpretNode::Identity(PhaseGVN *phase) {
Node* n = in(1);
if (n->Opcode() == Op_VectorReinterpret) {
if (Type::cmp(bottom_type(), n->in(1)->bottom_type()) == 0) {
return n->in(1);
}
}
return this;
}
The node will be optimized out if the bottom_type is equal to it's input's input's bottom_type. This is right if there is no truncation happens during the whole process. Otherwise, the above issue happens if there is truncation.