mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8281294: [vectorapi] FIRST_NONZERO reduction operation throws IllegalArgumentExcept on zero vectors
Reviewed-by: jrose
This commit is contained in:
parent
039313d65d
commit
83b6e4bc04
51 changed files with 3272 additions and 937 deletions
|
@ -2595,7 +2595,8 @@ public abstract class ByteVector extends AbstractVector<Byte> {
|
|||
VectorMask<Byte> m) {
|
||||
m.check(maskClass, this);
|
||||
if (op == FIRST_NONZERO) {
|
||||
ByteVector v = reduceIdentityVector(op).blend(this, m);
|
||||
// FIXME: The JIT should handle this.
|
||||
ByteVector v = broadcast((byte) 0).blend(this, m);
|
||||
return v.reduceLanesTemplate(op);
|
||||
}
|
||||
int opc = opCode(op);
|
||||
|
@ -2610,10 +2611,11 @@ public abstract class ByteVector extends AbstractVector<Byte> {
|
|||
final
|
||||
byte reduceLanesTemplate(VectorOperators.Associative op) {
|
||||
if (op == FIRST_NONZERO) {
|
||||
// FIXME: The JIT should handle this, and other scan ops alos.
|
||||
// FIXME: The JIT should handle this.
|
||||
VectorMask<Byte> thisNZ
|
||||
= this.viewAsIntegralLanes().compare(NE, (byte) 0);
|
||||
return this.lane(thisNZ.firstTrue());
|
||||
int ft = thisNZ.firstTrue();
|
||||
return ft < length() ? this.lane(ft) : (byte) 0;
|
||||
}
|
||||
int opc = opCode(op);
|
||||
return fromBits(VectorSupport.reductionCoerced(
|
||||
|
@ -2646,34 +2648,6 @@ public abstract class ByteVector extends AbstractVector<Byte> {
|
|||
}
|
||||
}
|
||||
|
||||
private
|
||||
@ForceInline
|
||||
ByteVector reduceIdentityVector(VectorOperators.Associative op) {
|
||||
int opc = opCode(op);
|
||||
UnaryOperator<ByteVector> fn
|
||||
= REDUCE_ID_IMPL.find(op, opc, (opc_) -> {
|
||||
switch (opc_) {
|
||||
case VECTOR_OP_ADD:
|
||||
case VECTOR_OP_OR:
|
||||
case VECTOR_OP_XOR:
|
||||
return v -> v.broadcast(0);
|
||||
case VECTOR_OP_MUL:
|
||||
return v -> v.broadcast(1);
|
||||
case VECTOR_OP_AND:
|
||||
return v -> v.broadcast(-1);
|
||||
case VECTOR_OP_MIN:
|
||||
return v -> v.broadcast(MAX_OR_INF);
|
||||
case VECTOR_OP_MAX:
|
||||
return v -> v.broadcast(MIN_OR_INF);
|
||||
default: return null;
|
||||
}
|
||||
});
|
||||
return fn.apply(this);
|
||||
}
|
||||
private static final
|
||||
ImplCache<Associative,UnaryOperator<ByteVector>> REDUCE_ID_IMPL
|
||||
= new ImplCache<>(Associative.class, ByteVector.class);
|
||||
|
||||
private static final byte MIN_OR_INF = Byte.MIN_VALUE;
|
||||
private static final byte MAX_OR_INF = Byte.MAX_VALUE;
|
||||
|
||||
|
|
|
@ -2419,7 +2419,8 @@ public abstract class DoubleVector extends AbstractVector<Double> {
|
|||
VectorMask<Double> m) {
|
||||
m.check(maskClass, this);
|
||||
if (op == FIRST_NONZERO) {
|
||||
DoubleVector v = reduceIdentityVector(op).blend(this, m);
|
||||
// FIXME: The JIT should handle this.
|
||||
DoubleVector v = broadcast((double) 0).blend(this, m);
|
||||
return v.reduceLanesTemplate(op);
|
||||
}
|
||||
int opc = opCode(op);
|
||||
|
@ -2434,10 +2435,11 @@ public abstract class DoubleVector extends AbstractVector<Double> {
|
|||
final
|
||||
double reduceLanesTemplate(VectorOperators.Associative op) {
|
||||
if (op == FIRST_NONZERO) {
|
||||
// FIXME: The JIT should handle this, and other scan ops alos.
|
||||
// FIXME: The JIT should handle this.
|
||||
VectorMask<Long> thisNZ
|
||||
= this.viewAsIntegralLanes().compare(NE, (long) 0);
|
||||
return this.lane(thisNZ.firstTrue());
|
||||
int ft = thisNZ.firstTrue();
|
||||
return ft < length() ? this.lane(ft) : (double) 0;
|
||||
}
|
||||
int opc = opCode(op);
|
||||
return fromBits(VectorSupport.reductionCoerced(
|
||||
|
@ -2464,30 +2466,6 @@ public abstract class DoubleVector extends AbstractVector<Double> {
|
|||
}
|
||||
}
|
||||
|
||||
private
|
||||
@ForceInline
|
||||
DoubleVector reduceIdentityVector(VectorOperators.Associative op) {
|
||||
int opc = opCode(op);
|
||||
UnaryOperator<DoubleVector> fn
|
||||
= REDUCE_ID_IMPL.find(op, opc, (opc_) -> {
|
||||
switch (opc_) {
|
||||
case VECTOR_OP_ADD:
|
||||
return v -> v.broadcast(0);
|
||||
case VECTOR_OP_MUL:
|
||||
return v -> v.broadcast(1);
|
||||
case VECTOR_OP_MIN:
|
||||
return v -> v.broadcast(MAX_OR_INF);
|
||||
case VECTOR_OP_MAX:
|
||||
return v -> v.broadcast(MIN_OR_INF);
|
||||
default: return null;
|
||||
}
|
||||
});
|
||||
return fn.apply(this);
|
||||
}
|
||||
private static final
|
||||
ImplCache<Associative,UnaryOperator<DoubleVector>> REDUCE_ID_IMPL
|
||||
= new ImplCache<>(Associative.class, DoubleVector.class);
|
||||
|
||||
private static final double MIN_OR_INF = Double.NEGATIVE_INFINITY;
|
||||
private static final double MAX_OR_INF = Double.POSITIVE_INFINITY;
|
||||
|
||||
|
|
|
@ -2439,7 +2439,8 @@ public abstract class FloatVector extends AbstractVector<Float> {
|
|||
VectorMask<Float> m) {
|
||||
m.check(maskClass, this);
|
||||
if (op == FIRST_NONZERO) {
|
||||
FloatVector v = reduceIdentityVector(op).blend(this, m);
|
||||
// FIXME: The JIT should handle this.
|
||||
FloatVector v = broadcast((float) 0).blend(this, m);
|
||||
return v.reduceLanesTemplate(op);
|
||||
}
|
||||
int opc = opCode(op);
|
||||
|
@ -2454,10 +2455,11 @@ public abstract class FloatVector extends AbstractVector<Float> {
|
|||
final
|
||||
float reduceLanesTemplate(VectorOperators.Associative op) {
|
||||
if (op == FIRST_NONZERO) {
|
||||
// FIXME: The JIT should handle this, and other scan ops alos.
|
||||
// FIXME: The JIT should handle this.
|
||||
VectorMask<Integer> thisNZ
|
||||
= this.viewAsIntegralLanes().compare(NE, (int) 0);
|
||||
return this.lane(thisNZ.firstTrue());
|
||||
int ft = thisNZ.firstTrue();
|
||||
return ft < length() ? this.lane(ft) : (float) 0;
|
||||
}
|
||||
int opc = opCode(op);
|
||||
return fromBits(VectorSupport.reductionCoerced(
|
||||
|
@ -2484,30 +2486,6 @@ public abstract class FloatVector extends AbstractVector<Float> {
|
|||
}
|
||||
}
|
||||
|
||||
private
|
||||
@ForceInline
|
||||
FloatVector reduceIdentityVector(VectorOperators.Associative op) {
|
||||
int opc = opCode(op);
|
||||
UnaryOperator<FloatVector> fn
|
||||
= REDUCE_ID_IMPL.find(op, opc, (opc_) -> {
|
||||
switch (opc_) {
|
||||
case VECTOR_OP_ADD:
|
||||
return v -> v.broadcast(0);
|
||||
case VECTOR_OP_MUL:
|
||||
return v -> v.broadcast(1);
|
||||
case VECTOR_OP_MIN:
|
||||
return v -> v.broadcast(MAX_OR_INF);
|
||||
case VECTOR_OP_MAX:
|
||||
return v -> v.broadcast(MIN_OR_INF);
|
||||
default: return null;
|
||||
}
|
||||
});
|
||||
return fn.apply(this);
|
||||
}
|
||||
private static final
|
||||
ImplCache<Associative,UnaryOperator<FloatVector>> REDUCE_ID_IMPL
|
||||
= new ImplCache<>(Associative.class, FloatVector.class);
|
||||
|
||||
private static final float MIN_OR_INF = Float.NEGATIVE_INFINITY;
|
||||
private static final float MAX_OR_INF = Float.POSITIVE_INFINITY;
|
||||
|
||||
|
|
|
@ -2594,7 +2594,8 @@ public abstract class IntVector extends AbstractVector<Integer> {
|
|||
VectorMask<Integer> m) {
|
||||
m.check(maskClass, this);
|
||||
if (op == FIRST_NONZERO) {
|
||||
IntVector v = reduceIdentityVector(op).blend(this, m);
|
||||
// FIXME: The JIT should handle this.
|
||||
IntVector v = broadcast((int) 0).blend(this, m);
|
||||
return v.reduceLanesTemplate(op);
|
||||
}
|
||||
int opc = opCode(op);
|
||||
|
@ -2609,10 +2610,11 @@ public abstract class IntVector extends AbstractVector<Integer> {
|
|||
final
|
||||
int reduceLanesTemplate(VectorOperators.Associative op) {
|
||||
if (op == FIRST_NONZERO) {
|
||||
// FIXME: The JIT should handle this, and other scan ops alos.
|
||||
// FIXME: The JIT should handle this.
|
||||
VectorMask<Integer> thisNZ
|
||||
= this.viewAsIntegralLanes().compare(NE, (int) 0);
|
||||
return this.lane(thisNZ.firstTrue());
|
||||
int ft = thisNZ.firstTrue();
|
||||
return ft < length() ? this.lane(ft) : (int) 0;
|
||||
}
|
||||
int opc = opCode(op);
|
||||
return fromBits(VectorSupport.reductionCoerced(
|
||||
|
@ -2645,34 +2647,6 @@ public abstract class IntVector extends AbstractVector<Integer> {
|
|||
}
|
||||
}
|
||||
|
||||
private
|
||||
@ForceInline
|
||||
IntVector reduceIdentityVector(VectorOperators.Associative op) {
|
||||
int opc = opCode(op);
|
||||
UnaryOperator<IntVector> fn
|
||||
= REDUCE_ID_IMPL.find(op, opc, (opc_) -> {
|
||||
switch (opc_) {
|
||||
case VECTOR_OP_ADD:
|
||||
case VECTOR_OP_OR:
|
||||
case VECTOR_OP_XOR:
|
||||
return v -> v.broadcast(0);
|
||||
case VECTOR_OP_MUL:
|
||||
return v -> v.broadcast(1);
|
||||
case VECTOR_OP_AND:
|
||||
return v -> v.broadcast(-1);
|
||||
case VECTOR_OP_MIN:
|
||||
return v -> v.broadcast(MAX_OR_INF);
|
||||
case VECTOR_OP_MAX:
|
||||
return v -> v.broadcast(MIN_OR_INF);
|
||||
default: return null;
|
||||
}
|
||||
});
|
||||
return fn.apply(this);
|
||||
}
|
||||
private static final
|
||||
ImplCache<Associative,UnaryOperator<IntVector>> REDUCE_ID_IMPL
|
||||
= new ImplCache<>(Associative.class, IntVector.class);
|
||||
|
||||
private static final int MIN_OR_INF = Integer.MIN_VALUE;
|
||||
private static final int MAX_OR_INF = Integer.MAX_VALUE;
|
||||
|
||||
|
|
|
@ -2460,7 +2460,8 @@ public abstract class LongVector extends AbstractVector<Long> {
|
|||
VectorMask<Long> m) {
|
||||
m.check(maskClass, this);
|
||||
if (op == FIRST_NONZERO) {
|
||||
LongVector v = reduceIdentityVector(op).blend(this, m);
|
||||
// FIXME: The JIT should handle this.
|
||||
LongVector v = broadcast((long) 0).blend(this, m);
|
||||
return v.reduceLanesTemplate(op);
|
||||
}
|
||||
int opc = opCode(op);
|
||||
|
@ -2475,10 +2476,11 @@ public abstract class LongVector extends AbstractVector<Long> {
|
|||
final
|
||||
long reduceLanesTemplate(VectorOperators.Associative op) {
|
||||
if (op == FIRST_NONZERO) {
|
||||
// FIXME: The JIT should handle this, and other scan ops alos.
|
||||
// FIXME: The JIT should handle this.
|
||||
VectorMask<Long> thisNZ
|
||||
= this.viewAsIntegralLanes().compare(NE, (long) 0);
|
||||
return this.lane(thisNZ.firstTrue());
|
||||
int ft = thisNZ.firstTrue();
|
||||
return ft < length() ? this.lane(ft) : (long) 0;
|
||||
}
|
||||
int opc = opCode(op);
|
||||
return fromBits(VectorSupport.reductionCoerced(
|
||||
|
@ -2511,34 +2513,6 @@ public abstract class LongVector extends AbstractVector<Long> {
|
|||
}
|
||||
}
|
||||
|
||||
private
|
||||
@ForceInline
|
||||
LongVector reduceIdentityVector(VectorOperators.Associative op) {
|
||||
int opc = opCode(op);
|
||||
UnaryOperator<LongVector> fn
|
||||
= REDUCE_ID_IMPL.find(op, opc, (opc_) -> {
|
||||
switch (opc_) {
|
||||
case VECTOR_OP_ADD:
|
||||
case VECTOR_OP_OR:
|
||||
case VECTOR_OP_XOR:
|
||||
return v -> v.broadcast(0);
|
||||
case VECTOR_OP_MUL:
|
||||
return v -> v.broadcast(1);
|
||||
case VECTOR_OP_AND:
|
||||
return v -> v.broadcast(-1);
|
||||
case VECTOR_OP_MIN:
|
||||
return v -> v.broadcast(MAX_OR_INF);
|
||||
case VECTOR_OP_MAX:
|
||||
return v -> v.broadcast(MIN_OR_INF);
|
||||
default: return null;
|
||||
}
|
||||
});
|
||||
return fn.apply(this);
|
||||
}
|
||||
private static final
|
||||
ImplCache<Associative,UnaryOperator<LongVector>> REDUCE_ID_IMPL
|
||||
= new ImplCache<>(Associative.class, LongVector.class);
|
||||
|
||||
private static final long MIN_OR_INF = Long.MIN_VALUE;
|
||||
private static final long MAX_OR_INF = Long.MAX_VALUE;
|
||||
|
||||
|
|
|
@ -2595,7 +2595,8 @@ public abstract class ShortVector extends AbstractVector<Short> {
|
|||
VectorMask<Short> m) {
|
||||
m.check(maskClass, this);
|
||||
if (op == FIRST_NONZERO) {
|
||||
ShortVector v = reduceIdentityVector(op).blend(this, m);
|
||||
// FIXME: The JIT should handle this.
|
||||
ShortVector v = broadcast((short) 0).blend(this, m);
|
||||
return v.reduceLanesTemplate(op);
|
||||
}
|
||||
int opc = opCode(op);
|
||||
|
@ -2610,10 +2611,11 @@ public abstract class ShortVector extends AbstractVector<Short> {
|
|||
final
|
||||
short reduceLanesTemplate(VectorOperators.Associative op) {
|
||||
if (op == FIRST_NONZERO) {
|
||||
// FIXME: The JIT should handle this, and other scan ops alos.
|
||||
// FIXME: The JIT should handle this.
|
||||
VectorMask<Short> thisNZ
|
||||
= this.viewAsIntegralLanes().compare(NE, (short) 0);
|
||||
return this.lane(thisNZ.firstTrue());
|
||||
int ft = thisNZ.firstTrue();
|
||||
return ft < length() ? this.lane(ft) : (short) 0;
|
||||
}
|
||||
int opc = opCode(op);
|
||||
return fromBits(VectorSupport.reductionCoerced(
|
||||
|
@ -2646,34 +2648,6 @@ public abstract class ShortVector extends AbstractVector<Short> {
|
|||
}
|
||||
}
|
||||
|
||||
private
|
||||
@ForceInline
|
||||
ShortVector reduceIdentityVector(VectorOperators.Associative op) {
|
||||
int opc = opCode(op);
|
||||
UnaryOperator<ShortVector> fn
|
||||
= REDUCE_ID_IMPL.find(op, opc, (opc_) -> {
|
||||
switch (opc_) {
|
||||
case VECTOR_OP_ADD:
|
||||
case VECTOR_OP_OR:
|
||||
case VECTOR_OP_XOR:
|
||||
return v -> v.broadcast(0);
|
||||
case VECTOR_OP_MUL:
|
||||
return v -> v.broadcast(1);
|
||||
case VECTOR_OP_AND:
|
||||
return v -> v.broadcast(-1);
|
||||
case VECTOR_OP_MIN:
|
||||
return v -> v.broadcast(MAX_OR_INF);
|
||||
case VECTOR_OP_MAX:
|
||||
return v -> v.broadcast(MIN_OR_INF);
|
||||
default: return null;
|
||||
}
|
||||
});
|
||||
return fn.apply(this);
|
||||
}
|
||||
private static final
|
||||
ImplCache<Associative,UnaryOperator<ShortVector>> REDUCE_ID_IMPL
|
||||
= new ImplCache<>(Associative.class, ShortVector.class);
|
||||
|
||||
private static final short MIN_OR_INF = Short.MIN_VALUE;
|
||||
private static final short MAX_OR_INF = Short.MAX_VALUE;
|
||||
|
||||
|
|
|
@ -3021,7 +3021,8 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
|
|||
VectorMask<$Boxtype$> m) {
|
||||
m.check(maskClass, this);
|
||||
if (op == FIRST_NONZERO) {
|
||||
$abstractvectortype$ v = reduceIdentityVector(op).blend(this, m);
|
||||
// FIXME: The JIT should handle this.
|
||||
$abstractvectortype$ v = broadcast(($type$) 0).blend(this, m);
|
||||
return v.reduceLanesTemplate(op);
|
||||
}
|
||||
int opc = opCode(op);
|
||||
|
@ -3036,10 +3037,11 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
|
|||
final
|
||||
$type$ reduceLanesTemplate(VectorOperators.Associative op) {
|
||||
if (op == FIRST_NONZERO) {
|
||||
// FIXME: The JIT should handle this, and other scan ops alos.
|
||||
// FIXME: The JIT should handle this.
|
||||
VectorMask<$Boxbitstype$> thisNZ
|
||||
= this.viewAsIntegralLanes().compare(NE, ($bitstype$) 0);
|
||||
return this.lane(thisNZ.firstTrue());
|
||||
int ft = thisNZ.firstTrue();
|
||||
return ft < length() ? this.lane(ft) : ($type$) 0;
|
||||
}
|
||||
int opc = opCode(op);
|
||||
return fromBits(VectorSupport.reductionCoerced(
|
||||
|
@ -3074,38 +3076,6 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
|
|||
}
|
||||
}
|
||||
|
||||
private
|
||||
@ForceInline
|
||||
$abstractvectortype$ reduceIdentityVector(VectorOperators.Associative op) {
|
||||
int opc = opCode(op);
|
||||
UnaryOperator<$abstractvectortype$> fn
|
||||
= REDUCE_ID_IMPL.find(op, opc, (opc_) -> {
|
||||
switch (opc_) {
|
||||
case VECTOR_OP_ADD:
|
||||
#if[BITWISE]
|
||||
case VECTOR_OP_OR:
|
||||
case VECTOR_OP_XOR:
|
||||
#end[BITWISE]
|
||||
return v -> v.broadcast(0);
|
||||
case VECTOR_OP_MUL:
|
||||
return v -> v.broadcast(1);
|
||||
#if[BITWISE]
|
||||
case VECTOR_OP_AND:
|
||||
return v -> v.broadcast(-1);
|
||||
#end[BITWISE]
|
||||
case VECTOR_OP_MIN:
|
||||
return v -> v.broadcast(MAX_OR_INF);
|
||||
case VECTOR_OP_MAX:
|
||||
return v -> v.broadcast(MIN_OR_INF);
|
||||
default: return null;
|
||||
}
|
||||
});
|
||||
return fn.apply(this);
|
||||
}
|
||||
private static final
|
||||
ImplCache<Associative,UnaryOperator<$abstractvectortype$>> REDUCE_ID_IMPL
|
||||
= new ImplCache<>(Associative.class, $Type$Vector.class);
|
||||
|
||||
#if[FP]
|
||||
private static final $type$ MIN_OR_INF = $Boxtype$.NEGATIVE_INFINITY;
|
||||
private static final $type$ MAX_OR_INF = $Boxtype$.POSITIVE_INFINITY;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue