8281294: [vectorapi] FIRST_NONZERO reduction operation throws IllegalArgumentExcept on zero vectors

Reviewed-by: jrose
This commit is contained in:
Paul Sandoz 2022-02-10 18:37:21 +00:00
parent 039313d65d
commit 83b6e4bc04
51 changed files with 3272 additions and 937 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;