8371187: [BigEndian Platforms] Vector lane reversal error

Reviewed-by: mdoerr, amitkumar
This commit is contained in:
Varada M 2026-01-27 10:01:02 +00:00
parent 6fda44172e
commit ee2deaded8
7 changed files with 109 additions and 1 deletions

View File

@ -182,7 +182,44 @@ abstract class AbstractVector<E> extends Vector<E> {
final AbstractVector<?> asVectorRawTemplate(LaneType laneType) {
// NOTE: This assumes that convert0('X')
// respects REGISTER_ENDIAN order.
return convert0('X', vspecies().withLanes(laneType));
return convert0('X', vspecies().withLanes(laneType)).swapIfNeeded(vspecies());
}
@ForceInline
protected static <T> VectorShuffle<T> normalizeSubLanesForSpecies(AbstractSpecies<T> targetSpecies, int subLanesPerSrc) {
final int lanes = targetSpecies.laneCount();
if ((lanes % subLanesPerSrc) != 0) {
throw new IllegalArgumentException("laneCount " + lanes + " not divisible by subLanesPerSrc " + subLanesPerSrc);
}
// Each group corresponds to one source lane.
// For each group, reverse the lanes inside that group.
final int groups = lanes / subLanesPerSrc;
int[] map = new int[lanes];
for (int g = 0; g < groups; ++g) {
int base = g * subLanesPerSrc;
for (int j = 0; j < subLanesPerSrc; ++j) {
map[base + j] = base + (subLanesPerSrc - 1 - j);
}
}
return VectorShuffle.fromArray(targetSpecies, map, 0);
}
@ForceInline
protected final int subLanesToSwap(AbstractSpecies<?> srcSpecies) {
if (java.nio.ByteOrder.nativeOrder() != ByteOrder.BIG_ENDIAN) {
return -1;
}
int sBytes = srcSpecies.elementSize();
int tBytes = vspecies().elementSize();
// No lane reordering needed for same size or widening reinterprets
if (sBytes == tBytes || (sBytes % tBytes) != 0) {
return -1;
}
int subLanesPerSrc = sBytes / tBytes;
return subLanesPerSrc;
}
/*package-private*/
@ -242,6 +279,9 @@ abstract class AbstractVector<E> extends Vector<E> {
/*package-private*/
abstract AbstractVector<E> maybeSwap(ByteOrder bo);
/*package-private*/
abstract AbstractVector<?> swapIfNeeded(AbstractSpecies<?> srcSpecies);
/*package-private*/
@ForceInline
VectorShuffle<Byte> swapBytesShuffle() {

View File

@ -4101,6 +4101,14 @@ public abstract class ByteVector extends AbstractVector<Byte> {
return this;
}
/*package-private*/
@Override
@ForceInline
final
ByteVector swapIfNeeded(AbstractSpecies<?> srcSpecies) {
return this;
}
static final int ARRAY_SHIFT =
31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_BYTE_INDEX_SCALE);
static final long ARRAY_BASE =

View File

@ -3612,6 +3612,18 @@ public abstract class DoubleVector extends AbstractVector<Double> {
return this;
}
@Override
@ForceInline
final
DoubleVector swapIfNeeded(AbstractSpecies<?> srcSpecies) {
int subLanesPerSrc = subLanesToSwap(srcSpecies);
if (subLanesPerSrc < 0) {
return this;
}
VectorShuffle<Double> shuffle = normalizeSubLanesForSpecies(this.vspecies(), subLanesPerSrc);
return (DoubleVector) this.rearrange(shuffle);
}
static final int ARRAY_SHIFT =
31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_DOUBLE_INDEX_SCALE);
static final long ARRAY_BASE =

View File

@ -3562,6 +3562,18 @@ public abstract class FloatVector extends AbstractVector<Float> {
return this;
}
@Override
@ForceInline
final
FloatVector swapIfNeeded(AbstractSpecies<?> srcSpecies) {
int subLanesPerSrc = subLanesToSwap(srcSpecies);
if (subLanesPerSrc < 0) {
return this;
}
VectorShuffle<Float> shuffle = normalizeSubLanesForSpecies(this.vspecies(), subLanesPerSrc);
return (FloatVector) this.rearrange(shuffle);
}
static final int ARRAY_SHIFT =
31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_FLOAT_INDEX_SCALE);
static final long ARRAY_BASE =

View File

@ -3720,6 +3720,18 @@ public abstract class IntVector extends AbstractVector<Integer> {
return this;
}
@Override
@ForceInline
final
IntVector swapIfNeeded(AbstractSpecies<?> srcSpecies) {
int subLanesPerSrc = subLanesToSwap(srcSpecies);
if (subLanesPerSrc < 0) {
return this;
}
VectorShuffle<Integer> shuffle = normalizeSubLanesForSpecies(this.vspecies(), subLanesPerSrc);
return (IntVector) this.rearrange(shuffle);
}
static final int ARRAY_SHIFT =
31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_INT_INDEX_SCALE);
static final long ARRAY_BASE =

View File

@ -3655,6 +3655,18 @@ public abstract class LongVector extends AbstractVector<Long> {
return this;
}
@Override
@ForceInline
final
LongVector swapIfNeeded(AbstractSpecies<?> srcSpecies) {
int subLanesPerSrc = subLanesToSwap(srcSpecies);
if (subLanesPerSrc < 0) {
return this;
}
VectorShuffle<Long> shuffle = normalizeSubLanesForSpecies(this.vspecies(), subLanesPerSrc);
return (LongVector) this.rearrange(shuffle);
}
static final int ARRAY_SHIFT =
31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_LONG_INDEX_SCALE);
static final long ARRAY_BASE =

View File

@ -4074,6 +4074,18 @@ public abstract class ShortVector extends AbstractVector<Short> {
return this;
}
@Override
@ForceInline
final
ShortVector swapIfNeeded(AbstractSpecies<?> srcSpecies) {
int subLanesPerSrc = subLanesToSwap(srcSpecies);
if (subLanesPerSrc < 0) {
return this;
}
VectorShuffle<Short> shuffle = normalizeSubLanesForSpecies(this.vspecies(), subLanesPerSrc);
return (ShortVector) this.rearrange(shuffle);
}
static final int ARRAY_SHIFT =
31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_SHORT_INDEX_SCALE);
static final long ARRAY_BASE =