Skip to content

Commit 31c3b19

Browse files
author
Paul Sandoz
committed
8346174: UMAX/UMIN are missing from XXXVector::reductionOperations
Reviewed-by: qamai, jbhateja
1 parent c75b1d4 commit 31c3b19

27 files changed

+3586
-1
lines changed

src/hotspot/share/opto/vectorIntrinsics.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -1386,8 +1386,9 @@ bool LibraryCallKit::inline_vector_reduction() {
13861386
int opc = VectorSupport::vop2ideal(opr->get_con(), elem_bt);
13871387
int sopc = ReductionNode::opcode(opc, elem_bt);
13881388

1389+
// Ensure reduction operation for lanewise operation
13891390
// When using mask, mask use type needs to be VecMaskUseLoad.
1390-
if (!arch_supports_vector(sopc, num_elem, elem_bt, is_masked_op ? VecMaskUseLoad : VecMaskNotUsed)) {
1391+
if (sopc == opc || !arch_supports_vector(sopc, num_elem, elem_bt, is_masked_op ? VecMaskUseLoad : VecMaskNotUsed)) {
13911392
log_if_needed(" ** not supported: arity=1 op=%d/reduce vlen=%d etype=%s is_masked_op=%d",
13921393
sopc, num_elem, type2name(elem_bt), is_masked_op ? 1 : 0);
13931394
return false;

src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java

+4
Original file line numberDiff line numberDiff line change
@@ -2868,6 +2868,10 @@ private static ReductionOperation<ByteVector, VectorMask<Byte>> reductionOperati
28682868
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (byte) Math.min(a, b)));
28692869
case VECTOR_OP_MAX: return (v, m) ->
28702870
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (byte) Math.max(a, b)));
2871+
case VECTOR_OP_UMIN: return (v, m) ->
2872+
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (byte) VectorMath.minUnsigned(a, b)));
2873+
case VECTOR_OP_UMAX: return (v, m) ->
2874+
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (byte) VectorMath.maxUnsigned(a, b)));
28712875
case VECTOR_OP_AND: return (v, m) ->
28722876
toBits(v.rOp((byte)-1, m, (i, a, b) -> (byte)(a & b)));
28732877
case VECTOR_OP_OR: return (v, m) ->

src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java

+4
Original file line numberDiff line numberDiff line change
@@ -2853,6 +2853,10 @@ private static ReductionOperation<IntVector, VectorMask<Integer>> reductionOpera
28532853
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (int) Math.min(a, b)));
28542854
case VECTOR_OP_MAX: return (v, m) ->
28552855
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (int) Math.max(a, b)));
2856+
case VECTOR_OP_UMIN: return (v, m) ->
2857+
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (int) VectorMath.minUnsigned(a, b)));
2858+
case VECTOR_OP_UMAX: return (v, m) ->
2859+
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (int) VectorMath.maxUnsigned(a, b)));
28562860
case VECTOR_OP_AND: return (v, m) ->
28572861
toBits(v.rOp((int)-1, m, (i, a, b) -> (int)(a & b)));
28582862
case VECTOR_OP_OR: return (v, m) ->

src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java

+4
Original file line numberDiff line numberDiff line change
@@ -2719,6 +2719,10 @@ private static ReductionOperation<LongVector, VectorMask<Long>> reductionOperati
27192719
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (long) Math.min(a, b)));
27202720
case VECTOR_OP_MAX: return (v, m) ->
27212721
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (long) Math.max(a, b)));
2722+
case VECTOR_OP_UMIN: return (v, m) ->
2723+
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (long) VectorMath.minUnsigned(a, b)));
2724+
case VECTOR_OP_UMAX: return (v, m) ->
2725+
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (long) VectorMath.maxUnsigned(a, b)));
27222726
case VECTOR_OP_AND: return (v, m) ->
27232727
toBits(v.rOp((long)-1, m, (i, a, b) -> (long)(a & b)));
27242728
case VECTOR_OP_OR: return (v, m) ->

src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java

+4
Original file line numberDiff line numberDiff line change
@@ -2869,6 +2869,10 @@ private static ReductionOperation<ShortVector, VectorMask<Short>> reductionOpera
28692869
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (short) Math.min(a, b)));
28702870
case VECTOR_OP_MAX: return (v, m) ->
28712871
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (short) Math.max(a, b)));
2872+
case VECTOR_OP_UMIN: return (v, m) ->
2873+
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (short) VectorMath.minUnsigned(a, b)));
2874+
case VECTOR_OP_UMAX: return (v, m) ->
2875+
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (short) VectorMath.maxUnsigned(a, b)));
28722876
case VECTOR_OP_AND: return (v, m) ->
28732877
toBits(v.rOp((short)-1, m, (i, a, b) -> (short)(a & b)));
28742878
case VECTOR_OP_OR: return (v, m) ->

src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template

+6
Original file line numberDiff line numberDiff line change
@@ -3406,6 +3406,12 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
34063406
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> ($type$) Math.min(a, b)));
34073407
case VECTOR_OP_MAX: return (v, m) ->
34083408
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> ($type$) Math.max(a, b)));
3409+
#if[!FP]
3410+
case VECTOR_OP_UMIN: return (v, m) ->
3411+
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> ($type$) VectorMath.minUnsigned(a, b)));
3412+
case VECTOR_OP_UMAX: return (v, m) ->
3413+
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> ($type$) VectorMath.maxUnsigned(a, b)));
3414+
#end[!FP]
34093415
#if[BITWISE]
34103416
case VECTOR_OP_AND: return (v, m) ->
34113417
toBits(v.rOp(($type$)-1, m, (i, a, b) -> ($type$)(a & b)));

test/jdk/jdk/incubator/vector/Byte128VectorTests.java

+178
Original file line numberDiff line numberDiff line change
@@ -3912,6 +3912,184 @@ static void MAXReduceByte128VectorTestsMasked(IntFunction<byte[]> fa, IntFunctio
39123912
Byte128VectorTests::MAXReduceMasked, Byte128VectorTests::MAXReduceAllMasked);
39133913
}
39143914

3915+
static byte UMINReduce(byte[] a, int idx) {
3916+
byte res = Byte.MAX_VALUE;
3917+
for (int i = idx; i < (idx + SPECIES.length()); i++) {
3918+
res = (byte) VectorMath.minUnsigned(res, a[i]);
3919+
}
3920+
3921+
return res;
3922+
}
3923+
3924+
static byte UMINReduceAll(byte[] a) {
3925+
byte res = Byte.MAX_VALUE;
3926+
for (int i = 0; i < a.length; i += SPECIES.length()) {
3927+
res = (byte) VectorMath.minUnsigned(res, UMINReduce(a, i));
3928+
}
3929+
3930+
return res;
3931+
}
3932+
3933+
@Test(dataProvider = "byteUnaryOpProvider")
3934+
static void UMINReduceByte128VectorTests(IntFunction<byte[]> fa) {
3935+
byte[] a = fa.apply(SPECIES.length());
3936+
byte[] r = fr.apply(SPECIES.length());
3937+
byte ra = Byte.MAX_VALUE;
3938+
3939+
for (int ic = 0; ic < INVOC_COUNT; ic++) {
3940+
for (int i = 0; i < a.length; i += SPECIES.length()) {
3941+
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
3942+
r[i] = av.reduceLanes(VectorOperators.UMIN);
3943+
}
3944+
}
3945+
3946+
for (int ic = 0; ic < INVOC_COUNT; ic++) {
3947+
ra = Byte.MAX_VALUE;
3948+
for (int i = 0; i < a.length; i += SPECIES.length()) {
3949+
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
3950+
ra = (byte) VectorMath.minUnsigned(ra, av.reduceLanes(VectorOperators.UMIN));
3951+
}
3952+
}
3953+
3954+
assertReductionArraysEquals(r, ra, a,
3955+
Byte128VectorTests::UMINReduce, Byte128VectorTests::UMINReduceAll);
3956+
}
3957+
3958+
static byte UMINReduceMasked(byte[] a, int idx, boolean[] mask) {
3959+
byte res = Byte.MAX_VALUE;
3960+
for (int i = idx; i < (idx + SPECIES.length()); i++) {
3961+
if (mask[i % SPECIES.length()])
3962+
res = (byte) VectorMath.minUnsigned(res, a[i]);
3963+
}
3964+
3965+
return res;
3966+
}
3967+
3968+
static byte UMINReduceAllMasked(byte[] a, boolean[] mask) {
3969+
byte res = Byte.MAX_VALUE;
3970+
for (int i = 0; i < a.length; i += SPECIES.length()) {
3971+
res = (byte) VectorMath.minUnsigned(res, UMINReduceMasked(a, i, mask));
3972+
}
3973+
3974+
return res;
3975+
}
3976+
3977+
@Test(dataProvider = "byteUnaryOpMaskProvider")
3978+
static void UMINReduceByte128VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<boolean[]> fm) {
3979+
byte[] a = fa.apply(SPECIES.length());
3980+
byte[] r = fr.apply(SPECIES.length());
3981+
boolean[] mask = fm.apply(SPECIES.length());
3982+
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3983+
byte ra = Byte.MAX_VALUE;
3984+
3985+
for (int ic = 0; ic < INVOC_COUNT; ic++) {
3986+
for (int i = 0; i < a.length; i += SPECIES.length()) {
3987+
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
3988+
r[i] = av.reduceLanes(VectorOperators.UMIN, vmask);
3989+
}
3990+
}
3991+
3992+
for (int ic = 0; ic < INVOC_COUNT; ic++) {
3993+
ra = Byte.MAX_VALUE;
3994+
for (int i = 0; i < a.length; i += SPECIES.length()) {
3995+
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
3996+
ra = (byte) VectorMath.minUnsigned(ra, av.reduceLanes(VectorOperators.UMIN, vmask));
3997+
}
3998+
}
3999+
4000+
assertReductionArraysEqualsMasked(r, ra, a, mask,
4001+
Byte128VectorTests::UMINReduceMasked, Byte128VectorTests::UMINReduceAllMasked);
4002+
}
4003+
4004+
static byte UMAXReduce(byte[] a, int idx) {
4005+
byte res = Byte.MIN_VALUE;
4006+
for (int i = idx; i < (idx + SPECIES.length()); i++) {
4007+
res = (byte) VectorMath.maxUnsigned(res, a[i]);
4008+
}
4009+
4010+
return res;
4011+
}
4012+
4013+
static byte UMAXReduceAll(byte[] a) {
4014+
byte res = Byte.MIN_VALUE;
4015+
for (int i = 0; i < a.length; i += SPECIES.length()) {
4016+
res = (byte) VectorMath.maxUnsigned(res, UMAXReduce(a, i));
4017+
}
4018+
4019+
return res;
4020+
}
4021+
4022+
@Test(dataProvider = "byteUnaryOpProvider")
4023+
static void UMAXReduceByte128VectorTests(IntFunction<byte[]> fa) {
4024+
byte[] a = fa.apply(SPECIES.length());
4025+
byte[] r = fr.apply(SPECIES.length());
4026+
byte ra = Byte.MIN_VALUE;
4027+
4028+
for (int ic = 0; ic < INVOC_COUNT; ic++) {
4029+
for (int i = 0; i < a.length; i += SPECIES.length()) {
4030+
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
4031+
r[i] = av.reduceLanes(VectorOperators.UMAX);
4032+
}
4033+
}
4034+
4035+
for (int ic = 0; ic < INVOC_COUNT; ic++) {
4036+
ra = Byte.MIN_VALUE;
4037+
for (int i = 0; i < a.length; i += SPECIES.length()) {
4038+
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
4039+
ra = (byte) VectorMath.maxUnsigned(ra, av.reduceLanes(VectorOperators.UMAX));
4040+
}
4041+
}
4042+
4043+
assertReductionArraysEquals(r, ra, a,
4044+
Byte128VectorTests::UMAXReduce, Byte128VectorTests::UMAXReduceAll);
4045+
}
4046+
4047+
static byte UMAXReduceMasked(byte[] a, int idx, boolean[] mask) {
4048+
byte res = Byte.MIN_VALUE;
4049+
for (int i = idx; i < (idx + SPECIES.length()); i++) {
4050+
if (mask[i % SPECIES.length()])
4051+
res = (byte) VectorMath.maxUnsigned(res, a[i]);
4052+
}
4053+
4054+
return res;
4055+
}
4056+
4057+
static byte UMAXReduceAllMasked(byte[] a, boolean[] mask) {
4058+
byte res = Byte.MIN_VALUE;
4059+
for (int i = 0; i < a.length; i += SPECIES.length()) {
4060+
res = (byte) VectorMath.maxUnsigned(res, UMAXReduceMasked(a, i, mask));
4061+
}
4062+
4063+
return res;
4064+
}
4065+
4066+
@Test(dataProvider = "byteUnaryOpMaskProvider")
4067+
static void UMAXReduceByte128VectorTestsMasked(IntFunction<byte[]> fa, IntFunction<boolean[]> fm) {
4068+
byte[] a = fa.apply(SPECIES.length());
4069+
byte[] r = fr.apply(SPECIES.length());
4070+
boolean[] mask = fm.apply(SPECIES.length());
4071+
VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
4072+
byte ra = Byte.MIN_VALUE;
4073+
4074+
for (int ic = 0; ic < INVOC_COUNT; ic++) {
4075+
for (int i = 0; i < a.length; i += SPECIES.length()) {
4076+
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
4077+
r[i] = av.reduceLanes(VectorOperators.UMAX, vmask);
4078+
}
4079+
}
4080+
4081+
for (int ic = 0; ic < INVOC_COUNT; ic++) {
4082+
ra = Byte.MIN_VALUE;
4083+
for (int i = 0; i < a.length; i += SPECIES.length()) {
4084+
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
4085+
ra = (byte) VectorMath.maxUnsigned(ra, av.reduceLanes(VectorOperators.UMAX, vmask));
4086+
}
4087+
}
4088+
4089+
assertReductionArraysEqualsMasked(r, ra, a, mask,
4090+
Byte128VectorTests::UMAXReduceMasked, Byte128VectorTests::UMAXReduceAllMasked);
4091+
}
4092+
39154093
static byte FIRST_NONZEROReduce(byte[] a, int idx) {
39164094
byte res = (byte) 0;
39174095
for (int i = idx; i < (idx + SPECIES.length()); i++) {

0 commit comments

Comments
 (0)