Skip to content

Commit

Permalink
8346174: UMAX/UMIN are missing from XXXVector::reductionOperations
Browse files Browse the repository at this point in the history
Reviewed-by: jbhateja
Backport-of: 31c3b19
  • Loading branch information
Paul Sandoz committed Dec 18, 2024
1 parent 2cc14fa commit 0225372
Show file tree
Hide file tree
Showing 27 changed files with 3,586 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/hotspot/share/opto/vectorIntrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1637,8 +1637,9 @@ bool LibraryCallKit::inline_vector_reduction() {
int opc = VectorSupport::vop2ideal(opr->get_con(), elem_bt);
int sopc = ReductionNode::opcode(opc, elem_bt);

// Ensure reduction operation for lanewise operation
// When using mask, mask use type needs to be VecMaskUseLoad.
if (!arch_supports_vector(sopc, num_elem, elem_bt, is_masked_op ? VecMaskUseLoad : VecMaskNotUsed)) {
if (sopc == opc || !arch_supports_vector(sopc, num_elem, elem_bt, is_masked_op ? VecMaskUseLoad : VecMaskNotUsed)) {
log_if_needed(" ** not supported: arity=1 op=%d/reduce vlen=%d etype=%s is_masked_op=%d",
sopc, num_elem, type2name(elem_bt), is_masked_op ? 1 : 0);
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2869,6 +2869,10 @@ private static ReductionOperation<ByteVector, VectorMask<Byte>> reductionOperati
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (byte) Math.min(a, b)));
case VECTOR_OP_MAX: return (v, m) ->
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (byte) Math.max(a, b)));
case VECTOR_OP_UMIN: return (v, m) ->
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (byte) VectorMath.minUnsigned(a, b)));
case VECTOR_OP_UMAX: return (v, m) ->
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (byte) VectorMath.maxUnsigned(a, b)));
case VECTOR_OP_AND: return (v, m) ->
toBits(v.rOp((byte)-1, m, (i, a, b) -> (byte)(a & b)));
case VECTOR_OP_OR: return (v, m) ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2854,6 +2854,10 @@ private static ReductionOperation<IntVector, VectorMask<Integer>> reductionOpera
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (int) Math.min(a, b)));
case VECTOR_OP_MAX: return (v, m) ->
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (int) Math.max(a, b)));
case VECTOR_OP_UMIN: return (v, m) ->
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (int) VectorMath.minUnsigned(a, b)));
case VECTOR_OP_UMAX: return (v, m) ->
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (int) VectorMath.maxUnsigned(a, b)));
case VECTOR_OP_AND: return (v, m) ->
toBits(v.rOp((int)-1, m, (i, a, b) -> (int)(a & b)));
case VECTOR_OP_OR: return (v, m) ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2720,6 +2720,10 @@ private static ReductionOperation<LongVector, VectorMask<Long>> reductionOperati
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (long) Math.min(a, b)));
case VECTOR_OP_MAX: return (v, m) ->
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (long) Math.max(a, b)));
case VECTOR_OP_UMIN: return (v, m) ->
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (long) VectorMath.minUnsigned(a, b)));
case VECTOR_OP_UMAX: return (v, m) ->
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (long) VectorMath.maxUnsigned(a, b)));
case VECTOR_OP_AND: return (v, m) ->
toBits(v.rOp((long)-1, m, (i, a, b) -> (long)(a & b)));
case VECTOR_OP_OR: return (v, m) ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2870,6 +2870,10 @@ private static ReductionOperation<ShortVector, VectorMask<Short>> reductionOpera
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (short) Math.min(a, b)));
case VECTOR_OP_MAX: return (v, m) ->
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (short) Math.max(a, b)));
case VECTOR_OP_UMIN: return (v, m) ->
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (short) VectorMath.minUnsigned(a, b)));
case VECTOR_OP_UMAX: return (v, m) ->
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (short) VectorMath.maxUnsigned(a, b)));
case VECTOR_OP_AND: return (v, m) ->
toBits(v.rOp((short)-1, m, (i, a, b) -> (short)(a & b)));
case VECTOR_OP_OR: return (v, m) ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3375,6 +3375,12 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> ($type$) Math.min(a, b)));
case VECTOR_OP_MAX: return (v, m) ->
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> ($type$) Math.max(a, b)));
#if[!FP]
case VECTOR_OP_UMIN: return (v, m) ->
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> ($type$) VectorMath.minUnsigned(a, b)));
case VECTOR_OP_UMAX: return (v, m) ->
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> ($type$) VectorMath.maxUnsigned(a, b)));
#end[!FP]
#if[BITWISE]
case VECTOR_OP_AND: return (v, m) ->
toBits(v.rOp(($type$)-1, m, (i, a, b) -> ($type$)(a & b)));
Expand Down
178 changes: 178 additions & 0 deletions test/jdk/jdk/incubator/vector/Byte128VectorTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -3912,6 +3912,184 @@ static void MAXReduceByte128VectorTestsMasked(IntFunction<byte[]> fa, IntFunctio
Byte128VectorTests::MAXReduceMasked, Byte128VectorTests::MAXReduceAllMasked);
}

static byte UMINReduce(byte[] a, int idx) {
byte res = Byte.MAX_VALUE;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (byte) VectorMath.minUnsigned(res, a[i]);
}

return res;
}

static byte UMINReduceAll(byte[] a) {
byte res = Byte.MAX_VALUE;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (byte) VectorMath.minUnsigned(res, UMINReduce(a, i));
}

return res;
}

@Test(dataProvider = "byteUnaryOpProvider")
static void UMINReduceByte128VectorTests(IntFunction<byte[]> fa) {
byte[] a = fa.apply(SPECIES.length());
byte[] r = fr.apply(SPECIES.length());
byte ra = Byte.MAX_VALUE;

for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < a.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.UMIN);
}
}

for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Byte.MAX_VALUE;
for (int i = 0; i < a.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
ra = (byte) VectorMath.minUnsigned(ra, av.reduceLanes(VectorOperators.UMIN));
}
}

assertReductionArraysEquals(r, ra, a,
Byte128VectorTests::UMINReduce, Byte128VectorTests::UMINReduceAll);
}

static byte UMINReduceMasked(byte[] a, int idx, boolean[] mask) {
byte res = Byte.MAX_VALUE;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (byte) VectorMath.minUnsigned(res, a[i]);
}

return res;
}

static byte UMINReduceAllMasked(byte[] a, boolean[] mask) {
byte res = Byte.MAX_VALUE;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (byte) VectorMath.minUnsigned(res, UMINReduceMasked(a, i, mask));
}

return res;
}

@Test(dataProvider = "byteUnaryOpMaskProvider")
static void UMINReduceByte128VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<boolean[]> fm) {
byte[] a = fa.apply(SPECIES.length());
byte[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
byte ra = Byte.MAX_VALUE;

for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < a.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.UMIN, vmask);
}
}

for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Byte.MAX_VALUE;
for (int i = 0; i < a.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
ra = (byte) VectorMath.minUnsigned(ra, av.reduceLanes(VectorOperators.UMIN, vmask));
}
}

assertReductionArraysEqualsMasked(r, ra, a, mask,
Byte128VectorTests::UMINReduceMasked, Byte128VectorTests::UMINReduceAllMasked);
}

static byte UMAXReduce(byte[] a, int idx) {
byte res = Byte.MIN_VALUE;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (byte) VectorMath.maxUnsigned(res, a[i]);
}

return res;
}

static byte UMAXReduceAll(byte[] a) {
byte res = Byte.MIN_VALUE;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (byte) VectorMath.maxUnsigned(res, UMAXReduce(a, i));
}

return res;
}

@Test(dataProvider = "byteUnaryOpProvider")
static void UMAXReduceByte128VectorTests(IntFunction<byte[]> fa) {
byte[] a = fa.apply(SPECIES.length());
byte[] r = fr.apply(SPECIES.length());
byte ra = Byte.MIN_VALUE;

for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < a.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.UMAX);
}
}

for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Byte.MIN_VALUE;
for (int i = 0; i < a.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
ra = (byte) VectorMath.maxUnsigned(ra, av.reduceLanes(VectorOperators.UMAX));
}
}

assertReductionArraysEquals(r, ra, a,
Byte128VectorTests::UMAXReduce, Byte128VectorTests::UMAXReduceAll);
}

static byte UMAXReduceMasked(byte[] a, int idx, boolean[] mask) {
byte res = Byte.MIN_VALUE;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (byte) VectorMath.maxUnsigned(res, a[i]);
}

return res;
}

static byte UMAXReduceAllMasked(byte[] a, boolean[] mask) {
byte res = Byte.MIN_VALUE;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (byte) VectorMath.maxUnsigned(res, UMAXReduceMasked(a, i, mask));
}

return res;
}

@Test(dataProvider = "byteUnaryOpMaskProvider")
static void UMAXReduceByte128VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<boolean[]> fm) {
byte[] a = fa.apply(SPECIES.length());
byte[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
byte ra = Byte.MIN_VALUE;

for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < a.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.UMAX, vmask);
}
}

for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Byte.MIN_VALUE;
for (int i = 0; i < a.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
ra = (byte) VectorMath.maxUnsigned(ra, av.reduceLanes(VectorOperators.UMAX, vmask));
}
}

assertReductionArraysEqualsMasked(r, ra, a, mask,
Byte128VectorTests::UMAXReduceMasked, Byte128VectorTests::UMAXReduceAllMasked);
}

static byte FIRST_NONZEROReduce(byte[] a, int idx) {
byte res = (byte) 0;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
Expand Down
Loading

0 comments on commit 0225372

Please sign in to comment.