Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/hotspot/share/opto/vectorIntrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2145,9 +2145,10 @@ bool LibraryCallKit::inline_vector_broadcast_int() {
}

Node* cnt = argument(6);
const TypeInt* cnt_type = cnt->bottom_type()->isa_int();

ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
const TypeInt* cnt_type = cnt->bottom_type()->isa_int();

// If CPU supports vector constant rotate instructions pass it directly
bool is_const_rotate = is_rotate && cnt_type && cnt_type->is_con() &&
Expand Down Expand Up @@ -2716,13 +2717,13 @@ bool LibraryCallKit::inline_vector_select_from_two_vectors() {
}
Node* opd2 = unbox_vector(argument(6), vbox_type, elem_bt, num_elem);
if (opd2 == nullptr) {
log_if_needed(" ** unbox failed v1=%s",
log_if_needed(" ** unbox failed v2=%s",
NodeClassNames[argument(6)->Opcode()]);
return false;
}
Node* opd3 = unbox_vector(argument(7), vbox_type, elem_bt, num_elem);
if (opd3 == nullptr) {
log_if_needed(" ** unbox failed v1=%s",
log_if_needed(" ** unbox failed v3=%s",
NodeClassNames[argument(7)->Opcode()]);
return false;
}
Expand Down
7 changes: 3 additions & 4 deletions src/hotspot/share/opto/vectornode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2113,10 +2113,9 @@ Node* SelectFromTwoVectorNode::Ideal(PhaseGVN* phase, bool can_reshape) {

const TypeVect* index_vect_type = index_vec->bottom_type()->is_vect();
BasicType index_elem_bt = index_vect_type->element_basic_type();
assert(!is_floating_point_type(index_elem_bt), "");

// Downcast index vector to a type agnostic shuffle representation, shuffle indices
// are held in a byte vector which are later massaged to target specific permutation
// are held in a byte vector which are later transformed to target specific permutation
// index format by subsequent VectorLoadShuffle.
int cast_vopc = VectorCastNode::opcode(0, index_elem_bt, true);
Node* index_byte_vec = phase->transform(VectorCastNode::make(cast_vopc, index_vec, T_BYTE, num_elem));
Copy link
Contributor

Choose a reason for hiding this comment

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

This cast assumes that the indices cannot have more than 8 bits. This would allow vector lengths of up to 256. This is fine for intel. But as far as I know ARM has in principle longer vectors - up to 2048 bytes. Should we maybe add some assert here to make sure we never badly truncate the index?

Copy link
Member Author

@jatin-bhateja jatin-bhateja Sep 17, 2024

Choose a reason for hiding this comment

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

Shuffle overhaul is on our todo list, its a know limitation which we tried lifting once, yes you read it correctly, its a limitation for AARCH64 SVE once a 2048 bits vector systems are available, IIRC current max vector size on any available AARCH64 system is 256 bits, with Neoverse V2 they shrink the vector size back to 16 bytes.

Copy link
Contributor

Choose a reason for hiding this comment

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

Are there any asserts that would catch this?

Expand All @@ -2127,14 +2126,14 @@ Node* SelectFromTwoVectorNode::Ideal(PhaseGVN* phase, bool can_reshape) {
// Compute the blend mask for merging two indipendently permututed vectors
// using shuff index in two vector index range [0, VLEN * 2).
BoolTest::mask pred = BoolTest::le;
ConINode* pred_node = (ConINode*)phase->makecon(TypeInt::make(pred));
ConINode* pred_node = phase->makecon(TypeInt::make(pred))->as_ConI();
const TypeVect* vmask_type = TypeVect::makemask(T_BYTE, num_elem);
Node* mask = phase->transform(new VectorMaskCmpNode(pred, index_byte_vec, bcast_lane_cnt_m1_vec, pred_node, vmask_type));

// Rearrange expects the indexes to lie within single vector index range [0, VLEN).
index_byte_vec = phase->transform(VectorNode::make(Op_AndV, index_byte_vec, bcast_lane_cnt_m1_vec, index_byte_vec->bottom_type()->is_vect()));

// Load indexes from byte vector and appropriatly massage them to target specific
// Load indexes from byte vector and appropriatly transform them to target specific
// permutation index format.
index_vec = phase->transform(new VectorLoadShuffleNode(index_byte_vec, index_vect_type));

Expand Down
11 changes: 7 additions & 4 deletions src/hotspot/share/opto/vectornode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1613,12 +1613,15 @@ class VectorRearrangeNode : public VectorNode {
};


// Selects elements from second and third vector based on the indices held in
// first vector two input vectors based on the indexes held in first vector.
// Select elements from two source vectors based on the wrapped indexes held in
// the first vector.
class SelectFromTwoVectorNode : public VectorNode {
public:
SelectFromTwoVectorNode(Node* index, Node* src1, Node* src2, const TypeVect* vt)
: VectorNode(index, src1, src2, vt) {}
SelectFromTwoVectorNode(Node* indexes, Node* src1, Node* src2, const TypeVect* vt)
: VectorNode(indexes, src1, src2, vt) {
assert(is_integral_type(indexes->bottom_type()->is_vect()->element_basic_type()),
"indexes must be an integral vector");
}

Node* Ideal(PhaseGVN* phase, bool can_reshape);
virtual int Opcode() const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2594,11 +2594,11 @@ final ByteVector selectFromTemplate(ByteVector v,
@ForceInline
final ByteVector selectFromTemplate(Class<? extends Vector<Byte>> indexVecClass,
ByteVector v1, ByteVector v2) {
int twoVectorLen = length() * 2;
ByteVector wrapped_indexes = this.lanewise(VectorOperators.AND, twoVectorLen - 1);
return (ByteVector)VectorSupport.selectFromTwoVectorOp(getClass(), indexVecClass, byte.class, byte.class,
length(), wrapped_indexes, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)
int twoVectorLenMask = (length() << 1) - 1;
ByteVector wrapped_indexes = this.lanewise(VectorOperators.AND, twoVectorLenMask);
return VectorSupport.selectFromTwoVectorOp(getClass(), indexVecClass, byte.class, byte.class,
length(), wrapped_indexes, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2436,13 +2436,12 @@ final DoubleVector selectFromTemplate(DoubleVector v,
@ForceInline
final DoubleVector selectFromTemplate(Class<? extends Vector<Long>> indexVecClass,
DoubleVector v1, DoubleVector v2) {
int twoVectorLen = length() * 2;
LongVector wrapped_indexes = this.convert(VectorOperators.D2L, 0)
.lanewise(VectorOperators.AND, twoVectorLen - 1)
.reinterpretAsLongs();
return (DoubleVector)VectorSupport.selectFromTwoVectorOp(getClass(), indexVecClass , double.class,
long.class, length(), wrapped_indexes, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)
int twoVectorLenMask = (length() << 1) - 1;
Vector<Long> wrapped_indexes = this.convert(VectorOperators.D2L, 0)
.lanewise(VectorOperators.AND, twoVectorLenMask);
return VectorSupport.selectFromTwoVectorOp(getClass(), indexVecClass , double.class, long.class,
length(), wrapped_indexes, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2448,13 +2448,12 @@ final FloatVector selectFromTemplate(FloatVector v,
@ForceInline
final FloatVector selectFromTemplate(Class<? extends Vector<Integer>> indexVecClass,
FloatVector v1, FloatVector v2) {
int twoVectorLen = length() * 2;
IntVector wrapped_indexes = this.convert(VectorOperators.F2I, 0)
.lanewise(VectorOperators.AND, twoVectorLen - 1)
.reinterpretAsInts();
return (FloatVector)VectorSupport.selectFromTwoVectorOp(getClass(), indexVecClass , float.class,
int.class, length(), wrapped_indexes, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)
int twoVectorLenMask = (length() << 1) - 1;
Vector<Integer> wrapped_indexes = this.convert(VectorOperators.F2I, 0)
.lanewise(VectorOperators.AND, twoVectorLenMask);
return VectorSupport.selectFromTwoVectorOp(getClass(), indexVecClass , float.class, int.class,
length(), wrapped_indexes, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2579,11 +2579,11 @@ final IntVector selectFromTemplate(IntVector v,
@ForceInline
final IntVector selectFromTemplate(Class<? extends Vector<Integer>> indexVecClass,
IntVector v1, IntVector v2) {
int twoVectorLen = length() * 2;
IntVector wrapped_indexes = this.lanewise(VectorOperators.AND, twoVectorLen - 1);
return (IntVector)VectorSupport.selectFromTwoVectorOp(getClass(), indexVecClass, int.class, int.class,
length(), wrapped_indexes, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)
int twoVectorLenMask = (length() << 1) - 1;
IntVector wrapped_indexes = this.lanewise(VectorOperators.AND, twoVectorLenMask);
return VectorSupport.selectFromTwoVectorOp(getClass(), indexVecClass, int.class, int.class,
length(), wrapped_indexes, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2445,11 +2445,11 @@ final LongVector selectFromTemplate(LongVector v,
@ForceInline
final LongVector selectFromTemplate(Class<? extends Vector<Long>> indexVecClass,
LongVector v1, LongVector v2) {
int twoVectorLen = length() * 2;
LongVector wrapped_indexes = this.lanewise(VectorOperators.AND, twoVectorLen - 1);
return (LongVector)VectorSupport.selectFromTwoVectorOp(getClass(), indexVecClass, long.class, long.class,
length(), wrapped_indexes, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)
int twoVectorLenMask = (length() << 1) - 1;
LongVector wrapped_indexes = this.lanewise(VectorOperators.AND, twoVectorLenMask);
return VectorSupport.selectFromTwoVectorOp(getClass(), indexVecClass, long.class, long.class,
length(), wrapped_indexes, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2595,11 +2595,11 @@ final ShortVector selectFromTemplate(ShortVector v,
@ForceInline
final ShortVector selectFromTemplate(Class<? extends Vector<Short>> indexVecClass,
ShortVector v1, ShortVector v2) {
int twoVectorLen = length() * 2;
ShortVector wrapped_indexes = this.lanewise(VectorOperators.AND, twoVectorLen - 1);
return (ShortVector)VectorSupport.selectFromTwoVectorOp(getClass(), indexVecClass, short.class, short.class,
length(), wrapped_indexes, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)
int twoVectorLenMask = (length() << 1) - 1;
ShortVector wrapped_indexes = this.lanewise(VectorOperators.AND, twoVectorLenMask);
return VectorSupport.selectFromTwoVectorOp(getClass(), indexVecClass, short.class, short.class,
length(), wrapped_indexes, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2971,20 +2971,19 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
@ForceInline
final $abstractvectortype$ selectFromTemplate(Class<? extends Vector<$Boxbitstype$>> indexVecClass,
$abstractvectortype$ v1, $abstractvectortype$ v2) {
int twoVectorLen = length() * 2;
int twoVectorLenMask = (length() << 1) - 1;
#if[FP]
$abstractbitsvectortype$ wrapped_indexes = this.convert(VectorOperators.{#if[intOrFloat]?F2I:D2L}, 0)
.lanewise(VectorOperators.AND, twoVectorLen - 1)
.reinterpretAs$Bitstype$s();
return ($Type$Vector)VectorSupport.selectFromTwoVectorOp(getClass(), indexVecClass , $type$.class,
$bitstype$.class, length(), wrapped_indexes, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)
Vector<$Boxbitstype$> wrapped_indexes = this.convert(VectorOperators.{#if[intOrFloat]?F2I:D2L}, 0)
.lanewise(VectorOperators.AND, twoVectorLenMask);
return VectorSupport.selectFromTwoVectorOp(getClass(), indexVecClass , $type$.class, $bitstype$.class,
length(), wrapped_indexes, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)
);
#else[FP]
$abstractvectortype$ wrapped_indexes = this.lanewise(VectorOperators.AND, twoVectorLen - 1);
return ($Type$Vector)VectorSupport.selectFromTwoVectorOp(getClass(), indexVecClass, $type$.class, $type$.class,
length(), wrapped_indexes, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)
$abstractvectortype$ wrapped_indexes = this.lanewise(VectorOperators.AND, twoVectorLenMask);
return VectorSupport.selectFromTwoVectorOp(getClass(), indexVecClass, $type$.class, $type$.class,
length(), wrapped_indexes, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3)
);
#end[FP]
}
Expand Down
16 changes: 8 additions & 8 deletions test/jdk/jdk/incubator/vector/Byte128VectorTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -315,20 +315,20 @@ static void assertexpandArraysEquals(byte[] r, byte[] a, boolean[] m, int vector

static void assertSelectFromTwoVectorEquals(byte[] r, byte[] order, byte[] a, byte[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
int idx = i + j;
boolean is_exceptional_idx = (int)order[idx] >= vector_len;
int oidx = is_exceptional_idx ? ((int)order[idx] - vector_len) : (int)order[idx];
idx = i + j;
wrapped_index =(((int)order[idx]) & (2 * vector_len -1));
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
int idx = i + j;
boolean is_exceptional_idx = (int)order[idx] >= vector_len;
int oidx = is_exceptional_idx ? ((int)order[idx] - vector_len) : (int)order[idx];
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + (int)order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}

Expand Down Expand Up @@ -1010,7 +1010,7 @@ public Object[][] boolUnaryOpProvider() {
static final List<IntFunction<byte[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("byte[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (byte)(RAND.nextInt(SPECIES.length() * 2)));
i -> (byte)(RAND.nextInt()));
})
);

Expand Down
16 changes: 8 additions & 8 deletions test/jdk/jdk/incubator/vector/Byte256VectorTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -315,20 +315,20 @@ static void assertexpandArraysEquals(byte[] r, byte[] a, boolean[] m, int vector

static void assertSelectFromTwoVectorEquals(byte[] r, byte[] order, byte[] a, byte[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
int idx = i + j;
boolean is_exceptional_idx = (int)order[idx] >= vector_len;
int oidx = is_exceptional_idx ? ((int)order[idx] - vector_len) : (int)order[idx];
idx = i + j;
wrapped_index =(((int)order[idx]) & (2 * vector_len -1));
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
int idx = i + j;
boolean is_exceptional_idx = (int)order[idx] >= vector_len;
int oidx = is_exceptional_idx ? ((int)order[idx] - vector_len) : (int)order[idx];
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + (int)order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}

Expand Down Expand Up @@ -1010,7 +1010,7 @@ public Object[][] boolUnaryOpProvider() {
static final List<IntFunction<byte[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("byte[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (byte)(RAND.nextInt(SPECIES.length() * 2)));
i -> (byte)(RAND.nextInt()));
})
);

Expand Down
Loading