Skip to content

Commit 42a6ead

Browse files
author
Ningsheng Jian
committedOct 21, 2020
8254884: Make sure jvm does not crash with Arm SVE and Vector API
Reviewed-by: vlivanov, adinn
1 parent e5870cf commit 42a6ead

File tree

4 files changed

+132
-16
lines changed

4 files changed

+132
-16
lines changed
 

‎src/hotspot/cpu/aarch64/aarch64_sve.ad

+67-2
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,31 @@ source %{
159159
case Op_ExtractL:
160160
case Op_ExtractS:
161161
case Op_ExtractUB:
162+
// Vector API specific
163+
case Op_AndReductionV:
164+
case Op_OrReductionV:
165+
case Op_XorReductionV:
166+
case Op_MaxReductionV:
167+
case Op_MinReductionV:
168+
case Op_LoadVectorGather:
169+
case Op_StoreVectorScatter:
170+
case Op_VectorBlend:
171+
case Op_VectorCast:
172+
case Op_VectorCastB2X:
173+
case Op_VectorCastD2X:
174+
case Op_VectorCastF2X:
175+
case Op_VectorCastI2X:
176+
case Op_VectorCastL2X:
177+
case Op_VectorCastS2X:
178+
case Op_VectorInsert:
179+
case Op_VectorLoadConst:
180+
case Op_VectorLoadMask:
181+
case Op_VectorLoadShuffle:
182+
case Op_VectorMaskCmp:
183+
case Op_VectorRearrange:
184+
case Op_VectorReinterpret:
185+
case Op_VectorStoreMask:
186+
case Op_VectorTest:
162187
return false;
163188
default:
164189
return true;
@@ -846,9 +871,49 @@ instruct vpopcountI(vReg dst, vReg src) %{
846871

847872
// vector add reduction
848873

874+
instruct reduce_addB(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp) %{
875+
predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
876+
n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE);
877+
match(Set dst (AddReductionVI src1 src2));
878+
effect(TEMP_DEF dst, TEMP tmp);
879+
ins_cost(SVE_COST);
880+
format %{ "sve_uaddv $tmp, $src2\t# vector (sve) (B)\n\t"
881+
"smov $dst, $tmp, B, 0\n\t"
882+
"addw $dst, $dst, $src1\n\t"
883+
"sxtb $dst, $dst\t # add reduction B" %}
884+
ins_encode %{
885+
__ sve_uaddv(as_FloatRegister($tmp$$reg), __ B,
886+
ptrue, as_FloatRegister($src2$$reg));
887+
__ smov($dst$$Register, as_FloatRegister($tmp$$reg), __ B, 0);
888+
__ addw($dst$$Register, $dst$$Register, $src1$$Register);
889+
__ sxtb($dst$$Register, $dst$$Register);
890+
%}
891+
ins_pipe(pipe_slow);
892+
%}
893+
894+
instruct reduce_addS(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp) %{
895+
predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
896+
n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT);
897+
match(Set dst (AddReductionVI src1 src2));
898+
effect(TEMP_DEF dst, TEMP tmp);
899+
ins_cost(SVE_COST);
900+
format %{ "sve_uaddv $tmp, $src2\t# vector (sve) (H)\n\t"
901+
"smov $dst, $tmp, H, 0\n\t"
902+
"addw $dst, $dst, $src1\n\t"
903+
"sxth $dst, $dst\t # add reduction H" %}
904+
ins_encode %{
905+
__ sve_uaddv(as_FloatRegister($tmp$$reg), __ H,
906+
ptrue, as_FloatRegister($src2$$reg));
907+
__ smov($dst$$Register, as_FloatRegister($tmp$$reg), __ H, 0);
908+
__ addw($dst$$Register, $dst$$Register, $src1$$Register);
909+
__ sxth($dst$$Register, $dst$$Register);
910+
%}
911+
ins_pipe(pipe_slow);
912+
%}
913+
849914
instruct reduce_addI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp) %{
850915
predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
851-
(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT));
916+
n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT);
852917
match(Set dst (AddReductionVI src1 src2));
853918
effect(TEMP_DEF dst, TEMP tmp);
854919
ins_cost(SVE_COST);
@@ -866,7 +931,7 @@ instruct reduce_addI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp) %{
866931

867932
instruct reduce_addL(iRegLNoSp dst, iRegL src1, vReg src2, vRegD tmp) %{
868933
predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
869-
(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG));
934+
n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG);
870935
match(Set dst (AddReductionVL src1 src2));
871936
effect(TEMP_DEF dst, TEMP tmp);
872937
ins_cost(SVE_COST);

‎src/hotspot/cpu/aarch64/aarch64_sve_ad.m4

+53-3
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,31 @@ source %{
146146
case Op_ExtractL:
147147
case Op_ExtractS:
148148
case Op_ExtractUB:
149+
// Vector API specific
150+
case Op_AndReductionV:
151+
case Op_OrReductionV:
152+
case Op_XorReductionV:
153+
case Op_MaxReductionV:
154+
case Op_MinReductionV:
155+
case Op_LoadVectorGather:
156+
case Op_StoreVectorScatter:
157+
case Op_VectorBlend:
158+
case Op_VectorCast:
159+
case Op_VectorCastB2X:
160+
case Op_VectorCastD2X:
161+
case Op_VectorCastF2X:
162+
case Op_VectorCastI2X:
163+
case Op_VectorCastL2X:
164+
case Op_VectorCastS2X:
165+
case Op_VectorInsert:
166+
case Op_VectorLoadConst:
167+
case Op_VectorLoadMask:
168+
case Op_VectorLoadShuffle:
169+
case Op_VectorMaskCmp:
170+
case Op_VectorRearrange:
171+
case Op_VectorReinterpret:
172+
case Op_VectorStoreMask:
173+
case Op_VectorTest:
149174
return false;
150175
default:
151176
return true;
@@ -507,15 +532,38 @@ instruct vpopcountI(vReg dst, vReg src) %{
507532
__ sve_cnt(as_FloatRegister($dst$$reg), __ S, ptrue, as_FloatRegister($src$$reg));
508533
%}
509534
ins_pipe(pipe_slow);
510-
%}
535+
%}dnl
511536

537+
dnl
538+
dnl REDUCE_ADD_EXT($1, $2, $3, $4, $5, $6, $7 )
539+
dnl REDUCE_ADD_EXT(insn_name, op_name, reg_dst, reg_src, size, elem_type, insn1)
540+
define(`REDUCE_ADD_EXT', `
541+
instruct $1($3 dst, $4 src1, vReg src2, vRegD tmp) %{
542+
predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
543+
n->in(2)->bottom_type()->is_vect()->element_basic_type() == $6);
544+
match(Set dst ($2 src1 src2));
545+
effect(TEMP_DEF dst, TEMP tmp);
546+
ins_cost(SVE_COST);
547+
format %{ "sve_uaddv $tmp, $src2\t# vector (sve) ($5)\n\t"
548+
"smov $dst, $tmp, $5, 0\n\t"
549+
"addw $dst, $dst, $src1\n\t"
550+
"$7 $dst, $dst\t # add reduction $5" %}
551+
ins_encode %{
552+
__ sve_uaddv(as_FloatRegister($tmp$$reg), __ $5,
553+
ptrue, as_FloatRegister($src2$$reg));
554+
__ smov($dst$$Register, as_FloatRegister($tmp$$reg), __ $5, 0);
555+
__ addw($dst$$Register, $dst$$Register, $src1$$Register);
556+
__ $7($dst$$Register, $dst$$Register);
557+
%}
558+
ins_pipe(pipe_slow);
559+
%}')dnl
512560
dnl
513561
dnl REDUCE_ADD($1, $2, $3, $4, $5, $6, $7 )
514562
dnl REDUCE_ADD(insn_name, op_name, reg_dst, reg_src, size, elem_type, insn1)
515563
define(`REDUCE_ADD', `
516564
instruct $1($3 dst, $4 src1, vReg src2, vRegD tmp) %{
517565
predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
518-
ELEMENT_SHORT_CHAR($6, n->in(2)));
566+
n->in(2)->bottom_type()->is_vect()->element_basic_type() == $6);
519567
match(Set dst ($2 src1 src2));
520568
effect(TEMP_DEF dst, TEMP tmp);
521569
ins_cost(SVE_COST);
@@ -545,8 +593,10 @@ instruct $1($3 src1_dst, vReg src2) %{
545593
%}
546594
ins_pipe(pipe_slow);
547595
%}')dnl
548-
dnl
596+
549597
// vector add reduction
598+
REDUCE_ADD_EXT(reduce_addB, AddReductionVI, iRegINoSp, iRegIorL2I, B, T_BYTE, sxtb)
599+
REDUCE_ADD_EXT(reduce_addS, AddReductionVI, iRegINoSp, iRegIorL2I, H, T_SHORT, sxth)
550600
REDUCE_ADD(reduce_addI, AddReductionVI, iRegINoSp, iRegIorL2I, S, T_INT, addw)
551601
REDUCE_ADD(reduce_addL, AddReductionVL, iRegLNoSp, iRegL, D, T_LONG, add)
552602
REDUCE_ADDF(reduce_addF, AddReductionVF, vRegF, S)

‎src/hotspot/share/opto/output.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -892,9 +892,9 @@ void PhaseOutput::FillLocArray( int idx, MachSafePointNode* sfpt, Node *local,
892892
? Location::int_in_long : Location::normal ));
893893
} else if( t->base() == Type::NarrowOop ) {
894894
array->append(new_loc_value( C->regalloc(), regnum, Location::narrowoop ));
895-
} else if ( t->base() == Type::VectorS || t->base() == Type::VectorD ||
896-
t->base() == Type::VectorX || t->base() == Type::VectorY ||
897-
t->base() == Type::VectorZ) {
895+
} else if (t->base() == Type::VectorA || t->base() == Type::VectorS ||
896+
t->base() == Type::VectorD || t->base() == Type::VectorX ||
897+
t->base() == Type::VectorY || t->base() == Type::VectorZ) {
898898
array->append(new_loc_value( C->regalloc(), regnum, Location::vector ));
899899
} else {
900900
array->append(new_loc_value( C->regalloc(), regnum, C->regalloc()->is_oop(local) ? Location::oop : Location::normal ));

‎src/hotspot/share/opto/vectorIntrinsics.cpp

+9-8
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,8 @@ bool LibraryCallKit::inline_vector_mem_operation(bool is_store) {
597597
// Since we are using byte array, we need to double check that the byte operations are supported by backend.
598598
if (using_byte_array) {
599599
int byte_num_elem = num_elem * type2aelembytes(elem_bt);
600-
if (!arch_supports_vector(is_store ? Op_StoreVector : Op_LoadVector, byte_num_elem, T_BYTE, VecMaskNotUsed)) {
600+
if (!arch_supports_vector(is_store ? Op_StoreVector : Op_LoadVector, byte_num_elem, T_BYTE, VecMaskNotUsed)
601+
|| !arch_supports_vector(Op_VectorReinterpret, byte_num_elem, T_BYTE, VecMaskNotUsed)) {
601602
if (C->print_intrinsics()) {
602603
tty->print_cr(" ** not supported: arity=%d op=%s vlen=%d*8 etype=%s/8 ismask=no",
603604
is_store, is_store ? "store" : "load",
@@ -620,9 +621,9 @@ bool LibraryCallKit::inline_vector_mem_operation(bool is_store) {
620621
return false; // not supported
621622
}
622623
} else {
623-
if (!arch_supports_vector(Op_StoreVector, num_elem, elem_bt, VecMaskUseStore)) {
624-
return false; // not supported
625-
}
624+
if (!arch_supports_vector(Op_StoreVector, num_elem, elem_bt, VecMaskUseStore)) {
625+
return false; // not supported
626+
}
626627
}
627628
}
628629

@@ -660,11 +661,11 @@ bool LibraryCallKit::inline_vector_mem_operation(bool is_store) {
660661
} else {
661662
// Special handle for masks
662663
if (is_mask) {
663-
vload = gvn().transform(LoadVectorNode::make(0, control(), memory(addr), addr, addr_type, num_elem, T_BOOLEAN));
664-
const TypeVect* to_vect_type = TypeVect::make(elem_bt, num_elem);
665-
vload = gvn().transform(new VectorLoadMaskNode(vload, to_vect_type));
664+
vload = gvn().transform(LoadVectorNode::make(0, control(), memory(addr), addr, addr_type, num_elem, T_BOOLEAN));
665+
const TypeVect* to_vect_type = TypeVect::make(elem_bt, num_elem);
666+
vload = gvn().transform(new VectorLoadMaskNode(vload, to_vect_type));
666667
} else {
667-
vload = gvn().transform(LoadVectorNode::make(0, control(), memory(addr), addr, addr_type, num_elem, elem_bt));
668+
vload = gvn().transform(LoadVectorNode::make(0, control(), memory(addr), addr, addr_type, num_elem, elem_bt));
668669
}
669670
}
670671
Node* box = box_vector(vload, vbox_type, elem_bt, num_elem);

1 commit comments

Comments
 (1)

bridgekeeper[bot] commented on Oct 21, 2020

@bridgekeeper[bot]
Please sign in to comment.