8278173: [vectorapi] Add x64 intrinsics for unsigned (zero extended) casts

Reviewed-by: psandoz, sviswanathan
This commit is contained in:
Quan Anh Mai 2022-02-15 18:57:53 +00:00 committed by Sandhya Viswanathan
parent a24498b777
commit 0af356bb4b
19 changed files with 466 additions and 62 deletions

View File

@ -4770,11 +4770,20 @@ void Assembler::vpmovzxwd(XMMRegister dst, XMMRegister src, int vector_len) {
assert(vector_len == AVX_128bit? VM_Version::supports_avx() :
vector_len == AVX_256bit? VM_Version::supports_avx2() :
vector_len == AVX_512bit? VM_Version::supports_evex() : 0, " ");
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
emit_int16(0x33, (0xC0 | encode));
}
void Assembler::vpmovzxwq(XMMRegister dst, XMMRegister src, int vector_len) {
assert(vector_len == AVX_128bit? VM_Version::supports_avx() :
vector_len == AVX_256bit? VM_Version::supports_avx2() :
vector_len == AVX_512bit? VM_Version::supports_evex() : 0, " ");
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
emit_int16(0x34, (0xC0 | encode));
}
void Assembler::pmaddwd(XMMRegister dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);

View File

@ -1822,12 +1822,14 @@ private:
void pmovzxbw(XMMRegister dst, XMMRegister src);
void pmovzxbw(XMMRegister dst, Address src);
void pmovzxbd(XMMRegister dst, XMMRegister src);
void vpmovzxbw( XMMRegister dst, Address src, int vector_len);
void pmovzxdq(XMMRegister dst, XMMRegister src);
void vpmovzxbw(XMMRegister dst, Address src, int vector_len);
void vpmovzxbw(XMMRegister dst, XMMRegister src, int vector_len);
void vpmovzxdq(XMMRegister dst, XMMRegister src, int vector_len);
void vpmovzxbd(XMMRegister dst, XMMRegister src, int vector_len);
void vpmovzxbq(XMMRegister dst, XMMRegister src, int vector_len);
void vpmovzxwd(XMMRegister dst, XMMRegister src, int vector_len);
void vpmovzxwq(XMMRegister dst, XMMRegister src, int vector_len);
void pmovzxdq(XMMRegister dst, XMMRegister src);
void vpmovzxdq(XMMRegister dst, XMMRegister src, int vector_len);
void evpmovzxbw(XMMRegister dst, KRegister mask, Address src, int vector_len);
// Sign extend moves
@ -1844,9 +1846,6 @@ private:
void evpmovwb(Address dst, XMMRegister src, int vector_len);
void evpmovwb(Address dst, KRegister mask, XMMRegister src, int vector_len);
void vpmovzxwd(XMMRegister dst, XMMRegister src, int vector_len);
void evpmovdb(Address dst, XMMRegister src, int vector_len);
// Multiply add

View File

@ -4094,6 +4094,33 @@ void C2_MacroAssembler::vector_castF2I_evex(XMMRegister dst, XMMRegister src, XM
bind(done);
}
void C2_MacroAssembler::vector_unsigned_cast(XMMRegister dst, XMMRegister src, int vlen_enc,
BasicType from_elem_bt, BasicType to_elem_bt) {
switch (from_elem_bt) {
case T_BYTE:
switch (to_elem_bt) {
case T_SHORT: vpmovzxbw(dst, src, vlen_enc); break;
case T_INT: vpmovzxbd(dst, src, vlen_enc); break;
case T_LONG: vpmovzxbq(dst, src, vlen_enc); break;
default: ShouldNotReachHere();
}
break;
case T_SHORT:
switch (to_elem_bt) {
case T_INT: vpmovzxwd(dst, src, vlen_enc); break;
case T_LONG: vpmovzxwq(dst, src, vlen_enc); break;
default: ShouldNotReachHere();
}
break;
case T_INT:
assert(to_elem_bt == T_LONG, "");
vpmovzxdq(dst, src, vlen_enc);
break;
default:
ShouldNotReachHere();
}
}
void C2_MacroAssembler::evpternlog(XMMRegister dst, int func, KRegister mask, XMMRegister src2, XMMRegister src3,
bool merge, BasicType bt, int vlen_enc) {
if (bt == T_INT) {

View File

@ -308,6 +308,9 @@ public:
KRegister ktmp1, KRegister ktmp2, AddressLiteral double_sign_flip,
Register scratch, int vec_enc);
void vector_unsigned_cast(XMMRegister dst, XMMRegister src, int vlen_enc,
BasicType from_elem_bt, BasicType to_elem_bt);
void evpternlog(XMMRegister dst, int func, KRegister mask, XMMRegister src2, XMMRegister src3,
bool merge, BasicType bt, int vlen_enc);

View File

@ -1457,6 +1457,9 @@ const bool Matcher::match_rule_supported(int opcode) {
case Op_VectorCastL2X:
case Op_VectorCastF2X:
case Op_VectorCastD2X:
case Op_VectorUCastB2X:
case Op_VectorUCastS2X:
case Op_VectorUCastI2X:
if (UseAVX < 1) { // enabled for AVX only
return false;
}
@ -7211,6 +7214,22 @@ instruct vcastDtoL_reg_evex(vec dst, vec src, vec xtmp1, vec xtmp2, kReg ktmp1,
ins_pipe( pipe_slow );
%}
instruct vucast(vec dst, vec src) %{
match(Set dst (VectorUCastB2X src));
match(Set dst (VectorUCastS2X src));
match(Set dst (VectorUCastI2X src));
format %{ "vector_ucast $dst,$src\t!" %}
ins_encode %{
assert(UseAVX > 0, "required");
BasicType from_elem_bt = Matcher::vector_element_basic_type(this, $src);
BasicType to_elem_bt = Matcher::vector_element_basic_type(this);
int vlen_enc = vector_length_encoding(this);
__ vector_unsigned_cast($dst$$XMMRegister, $src$$XMMRegister, vlen_enc, from_elem_bt, to_elem_bt);
%}
ins_pipe( pipe_slow );
%}
// --------------------------------- VectorMaskCmp --------------------------------------
instruct vcmpFD(legVec dst, legVec src1, legVec src2, immI8 cond) %{

View File

@ -4234,6 +4234,7 @@ bool MatchRule::is_vector() const {
"VectorRearrange","VectorLoadShuffle", "VectorLoadConst",
"VectorCastB2X", "VectorCastS2X", "VectorCastI2X",
"VectorCastL2X", "VectorCastF2X", "VectorCastD2X",
"VectorUCastB2X", "VectorUCastS2X", "VectorUCastI2X",
"VectorMaskWrapper","VectorMaskCmp","VectorReinterpret","LoadVectorMasked","StoreVectorMasked",
"FmaVD","FmaVF","PopCountVI", "PopCountVL", "VectorLongToMask",
// Next are vector mask ops.

View File

@ -479,6 +479,9 @@ macro(VectorCastI2X)
macro(VectorCastL2X)
macro(VectorCastF2X)
macro(VectorCastD2X)
macro(VectorUCastB2X)
macro(VectorUCastS2X)
macro(VectorUCastI2X)
macro(VectorInsert)
macro(MaskAll)
macro(AndVMask)

View File

@ -2370,9 +2370,11 @@ bool LibraryCallKit::inline_vector_convert() {
return false;
}
assert(opr->get_con() == VectorSupport::VECTOR_OP_CAST ||
assert(opr->get_con() == VectorSupport::VECTOR_OP_CAST ||
opr->get_con() == VectorSupport::VECTOR_OP_UCAST ||
opr->get_con() == VectorSupport::VECTOR_OP_REINTERPRET, "wrong opcode");
bool is_cast = (opr->get_con() == VectorSupport::VECTOR_OP_CAST);
bool is_cast = (opr->get_con() == VectorSupport::VECTOR_OP_CAST || opr->get_con() == VectorSupport::VECTOR_OP_UCAST);
bool is_ucast = (opr->get_con() == VectorSupport::VECTOR_OP_UCAST);
ciKlass* vbox_klass_from = vector_klass_from->const_oop()->as_instance()->java_lang_Class_klass();
ciKlass* vbox_klass_to = vector_klass_to->const_oop()->as_instance()->java_lang_Class_klass();
@ -2457,7 +2459,7 @@ bool LibraryCallKit::inline_vector_convert() {
if (is_mask && is_floating_point_type(elem_bt_from)) {
new_elem_bt_from = elem_bt_from == T_FLOAT ? T_INT : T_LONG;
}
int cast_vopc = VectorCastNode::opcode(new_elem_bt_from);
int cast_vopc = VectorCastNode::opcode(new_elem_bt_from, !is_ucast);
// Make sure that cast is implemented to particular type/size combination.
if (!arch_supports_vector(cast_vopc, num_elem_to, elem_bt_to, VecMaskNotUsed)) {
if (C->print_intrinsics()) {

View File

@ -1093,23 +1093,27 @@ VectorStoreMaskNode* VectorStoreMaskNode::make(PhaseGVN& gvn, Node* in, BasicTyp
VectorCastNode* VectorCastNode::make(int vopc, Node* n1, BasicType bt, uint vlen) {
const TypeVect* vt = TypeVect::make(bt, vlen);
switch (vopc) {
case Op_VectorCastB2X: return new VectorCastB2XNode(n1, vt);
case Op_VectorCastS2X: return new VectorCastS2XNode(n1, vt);
case Op_VectorCastI2X: return new VectorCastI2XNode(n1, vt);
case Op_VectorCastL2X: return new VectorCastL2XNode(n1, vt);
case Op_VectorCastF2X: return new VectorCastF2XNode(n1, vt);
case Op_VectorCastD2X: return new VectorCastD2XNode(n1, vt);
case Op_VectorCastB2X: return new VectorCastB2XNode(n1, vt);
case Op_VectorCastS2X: return new VectorCastS2XNode(n1, vt);
case Op_VectorCastI2X: return new VectorCastI2XNode(n1, vt);
case Op_VectorCastL2X: return new VectorCastL2XNode(n1, vt);
case Op_VectorCastF2X: return new VectorCastF2XNode(n1, vt);
case Op_VectorCastD2X: return new VectorCastD2XNode(n1, vt);
case Op_VectorUCastB2X: return new VectorUCastB2XNode(n1, vt);
case Op_VectorUCastS2X: return new VectorUCastS2XNode(n1, vt);
case Op_VectorUCastI2X: return new VectorUCastI2XNode(n1, vt);
default:
assert(false, "unknown node: %s", NodeClassNames[vopc]);
return NULL;
}
}
int VectorCastNode::opcode(BasicType bt) {
int VectorCastNode::opcode(BasicType bt, bool is_signed) {
assert((is_integral_type(bt) && bt != T_LONG) || is_signed, "");
switch (bt) {
case T_BYTE: return Op_VectorCastB2X;
case T_SHORT: return Op_VectorCastS2X;
case T_INT: return Op_VectorCastI2X;
case T_BYTE: return is_signed ? Op_VectorCastB2X : Op_VectorUCastB2X;
case T_SHORT: return is_signed ? Op_VectorCastS2X : Op_VectorUCastS2X;
case T_INT: return is_signed ? Op_VectorCastI2X : Op_VectorUCastI2X;
case T_LONG: return Op_VectorCastL2X;
case T_FLOAT: return Op_VectorCastF2X;
case T_DOUBLE: return Op_VectorCastD2X;

View File

@ -1468,7 +1468,7 @@ class VectorCastNode : public VectorNode {
virtual int Opcode() const;
static VectorCastNode* make(int vopc, Node* n1, BasicType bt, uint vlen);
static int opcode(BasicType bt);
static int opcode(BasicType bt, bool is_signed = true);
static bool implemented(BasicType bt, uint vlen);
virtual Node* Identity(PhaseGVN* phase);
@ -1522,6 +1522,30 @@ class VectorCastD2XNode : public VectorCastNode {
virtual int Opcode() const;
};
class VectorUCastB2XNode : public VectorCastNode {
public:
VectorUCastB2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
assert(in->bottom_type()->is_vect()->element_basic_type() == T_BYTE, "must be byte");
}
virtual int Opcode() const;
};
class VectorUCastS2XNode : public VectorCastNode {
public:
VectorUCastS2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
assert(in->bottom_type()->is_vect()->element_basic_type() == T_SHORT, "must be short");
}
virtual int Opcode() const;
};
class VectorUCastI2XNode : public VectorCastNode {
public:
VectorUCastI2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) {
assert(in->bottom_type()->is_vect()->element_basic_type() == T_INT, "must be int");
}
virtual int Opcode() const;
};
class VectorInsertNode : public VectorNode {
public:
VectorInsertNode(Node* vsrc, Node* new_val, ConINode* pos, const TypeVect* vt) : VectorNode(vsrc, new_val, (Node*)pos, vt) {

View File

@ -76,17 +76,18 @@ class VectorSupport : AllStatic {
// Convert
VECTOR_OP_CAST = 17,
VECTOR_OP_REINTERPRET = 18,
VECTOR_OP_UCAST = 18,
VECTOR_OP_REINTERPRET = 19,
// Mask manipulation operations
VECTOR_OP_MASK_TRUECOUNT = 19,
VECTOR_OP_MASK_FIRSTTRUE = 20,
VECTOR_OP_MASK_LASTTRUE = 21,
VECTOR_OP_MASK_TOLONG = 22,
VECTOR_OP_MASK_TRUECOUNT = 20,
VECTOR_OP_MASK_FIRSTTRUE = 21,
VECTOR_OP_MASK_LASTTRUE = 22,
VECTOR_OP_MASK_TOLONG = 23,
// Rotate operations
VECTOR_OP_LROTATE = 23,
VECTOR_OP_RROTATE = 24,
VECTOR_OP_LROTATE = 24,
VECTOR_OP_RROTATE = 25,
// Vector Math Library
VECTOR_OP_TAN = 101,

View File

@ -1847,6 +1847,9 @@
declare_c2_type(VectorCastL2XNode, VectorNode) \
declare_c2_type(VectorCastF2XNode, VectorNode) \
declare_c2_type(VectorCastD2XNode, VectorNode) \
declare_c2_type(VectorUCastB2XNode, VectorNode) \
declare_c2_type(VectorUCastS2XNode, VectorNode) \
declare_c2_type(VectorUCastI2XNode, VectorNode) \
declare_c2_type(VectorInsertNode, VectorNode) \
declare_c2_type(VectorUnboxNode, VectorNode) \
declare_c2_type(VectorReinterpretNode, VectorNode) \

View File

@ -63,17 +63,18 @@ public class VectorSupport {
public static final int VECTOR_OP_URSHIFT = 16;
public static final int VECTOR_OP_CAST = 17;
public static final int VECTOR_OP_REINTERPRET = 18;
public static final int VECTOR_OP_UCAST = 18;
public static final int VECTOR_OP_REINTERPRET = 19;
// Mask manipulation operations
public static final int VECTOR_OP_MASK_TRUECOUNT = 19;
public static final int VECTOR_OP_MASK_FIRSTTRUE = 20;
public static final int VECTOR_OP_MASK_LASTTRUE = 21;
public static final int VECTOR_OP_MASK_TOLONG = 22;
public static final int VECTOR_OP_MASK_TRUECOUNT = 20;
public static final int VECTOR_OP_MASK_FIRSTTRUE = 21;
public static final int VECTOR_OP_MASK_LASTTRUE = 22;
public static final int VECTOR_OP_MASK_TOLONG = 23;
// Rotate operations
public static final int VECTOR_OP_LROTATE = 23;
public static final int VECTOR_OP_RROTATE = 24;
public static final int VECTOR_OP_LROTATE = 24;
public static final int VECTOR_OP_RROTATE = 25;
// Math routines
public static final int VECTOR_OP_TAN = 101;

View File

@ -639,6 +639,25 @@ abstract class AbstractVector<E> extends Vector<E> {
throw new AssertionError();
}
/**
* Helper function for all sorts of lane-wise unsigned conversions.
* This function kicks in after intrinsic failure.
*/
/*package-private*/
@ForceInline
final <F>
AbstractVector<F> defaultUCast(AbstractSpecies<F> dsp) {
AbstractSpecies<?> vsp = this.vspecies();
if (vsp.elementSize() >= dsp.elementSize()) {
// clip in place
return this.convert0('C', dsp);
} else {
// extend in place, but remove unwanted sign extension
long mask = -1L >>> -vsp.elementSize();
return (AbstractVector<F>) this.convert0('C', dsp).lanewise(AND, dsp.broadcast(mask));
}
}
// Constant-folded access to conversion intrinsics:
/**
@ -658,6 +677,7 @@ abstract class AbstractVector<E> extends Vector<E> {
final <F>
AbstractVector<F> convert0(char kind, AbstractSpecies<F> rsp) {
// Derive some JIT-time constants:
Class<?> vtype;
Class<?> etype; // fill in after switch (constant)
int vlength; // fill in after switch (mark type profile?)
Class<?> rvtype; // fill in after switch (mark type profile)
@ -665,9 +685,22 @@ abstract class AbstractVector<E> extends Vector<E> {
int rlength;
switch (kind) {
case 'Z': // lane-wise size change, maybe with sign clip
// Maybe this should be an intrinsic also.
AbstractSpecies<?> rspi = rsp.asIntegral();
AbstractVector<?> bitv = resizeLanes0(this, rspi);
AbstractSpecies<?> vsp = this.vspecies();
AbstractSpecies<?> vspi = vsp.asIntegral();
AbstractVector<?> biti = vspi == vsp ? this : this.convert0('X', vspi);
rtype = rspi.elementType();
rlength = rspi.laneCount();
etype = vspi.elementType();
vlength = vspi.laneCount();
rvtype = rspi.dummyVector().getClass();
vtype = vspi.dummyVector().getClass();
int opc = vspi.elementSize() < rspi.elementSize() ? VectorSupport.VECTOR_OP_UCAST : VectorSupport.VECTOR_OP_CAST;
AbstractVector<?> bitv = VectorSupport.convert(opc,
vtype, etype, vlength,
rvtype, rtype, rlength,
biti, rspi,
AbstractVector::defaultUCast);
return (rspi == rsp ? bitv.check0(rsp) : bitv.convert0('X', rsp));
case 'C': // lane-wise cast (but not identity)
rtype = rsp.elementType();
@ -675,8 +708,9 @@ abstract class AbstractVector<E> extends Vector<E> {
etype = this.elementType(); // (profile)
vlength = this.length(); // (profile)
rvtype = rsp.dummyVector().getClass(); // (profile)
vtype = this.getClass();
return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST,
this.getClass(), etype, vlength,
vtype, etype, vlength,
rvtype, rtype, rlength,
this, rsp,
AbstractVector::defaultCast);
@ -686,8 +720,9 @@ abstract class AbstractVector<E> extends Vector<E> {
etype = this.elementType(); // (profile)
vlength = this.length(); // (profile)
rvtype = rsp.dummyVector().getClass(); // (profile)
vtype = this.getClass();
return VectorSupport.convert(VectorSupport.VECTOR_OP_REINTERPRET,
this.getClass(), etype, vlength,
vtype, etype, vlength,
rvtype, rtype, rlength,
this, rsp,
AbstractVector::defaultReinterpret);
@ -695,24 +730,6 @@ abstract class AbstractVector<E> extends Vector<E> {
throw new AssertionError();
}
@ForceInline
private static <F>
AbstractVector<F>
resizeLanes0(AbstractVector<?> v, AbstractSpecies<F> rspi) {
AbstractSpecies<?> dsp = v.vspecies();
int sizeChange = rspi.elementSize() - dsp.elementSize();
AbstractSpecies<?> dspi = dsp.asIntegral();
if (dspi != dsp) v = v.convert0('R', dspi);
if (sizeChange <= 0) { // clip in place
return v.convert0('C', rspi);
}
// extend in place, but remove unwanted sign extension
long mask = -1L >>> -dsp.elementSize();
return (AbstractVector<F>)
v.convert0('C', rspi)
.lanewise(AND, rspi.broadcast(mask));
}
// Byte buffer wrappers.
static ByteBuffer wrapper(ByteBuffer bb, ByteOrder bo) {
return bb.duplicate().order(bo);

View File

@ -95,10 +95,12 @@ enum LaneType {
return printName;
}
@ForceInline
LaneType asIntegral() {
return asIntegral.check();
}
@ForceInline
LaneType asFloating() {
if (asFloating == null) {
throw badElementType(elementType, "either int or long, to reinterpret as float or double");

View File

@ -163,6 +163,9 @@ public class IRNode {
public static final String VECTOR_CAST_L2X = START + "VectorCastL2X" + MID + END;
public static final String VECTOR_CAST_F2X = START + "VectorCastF2X" + MID + END;
public static final String VECTOR_CAST_D2X = START + "VectorCastD2X" + MID + END;
public static final String VECTOR_UCAST_B2X = START + "VectorUCastB2X" + MID + END;
public static final String VECTOR_UCAST_S2X = START + "VectorUCastS2X" + MID + END;
public static final String VECTOR_UCAST_I2X = START + "VectorUCastI2X" + MID + END;
public static final String VECTOR_REINTERPRET = START + "VectorReinterpret" + MID + END;
/**

View File

@ -1362,4 +1362,268 @@ public class TestVectorCast {
public static void runD512toF256() throws Throwable {
runCastHelper(D2F, DSPEC512, FSPEC256);
}
@Test
@IR(counts = {UB2X_NODE, "1"})
public static void testUB64toS64(byte[] input, short[] output) {
vectorCast(ZERO_EXTEND_B2S, BSPEC64, SSPEC64, input, output);
}
@Run(test = "testUB64toS64")
public static void runUB64toS64() throws Throwable {
runCastHelper(ZERO_EXTEND_B2S, BSPEC64, SSPEC64);
}
@Test
@IR(counts = {UB2X_NODE, "1"})
public static void testUB64toS128(byte[] input, short[] output) {
vectorCast(ZERO_EXTEND_B2S, BSPEC64, SSPEC128, input, output);
}
@Run(test = "testUB64toS128")
public static void runUB64toS128() throws Throwable {
runCastHelper(ZERO_EXTEND_B2S, BSPEC64, SSPEC128);
}
@Test
@IR(counts = {UB2X_NODE, "1"})
public static void testUB128toS256(byte[] input, short[] output) {
vectorCast(ZERO_EXTEND_B2S, BSPEC128, SSPEC256, input, output);
}
@Run(test = "testUB128toS256")
public static void runUB128toS256() throws Throwable {
runCastHelper(ZERO_EXTEND_B2S, BSPEC128, SSPEC256);
}
@Test
@IR(counts = {UB2X_NODE, "1"})
public static void testUB256toS512(byte[] input, short[] output) {
vectorCast(ZERO_EXTEND_B2S, BSPEC256, SSPEC512, input, output);
}
@Run(test = "testUB256toS512")
public static void runUB256toS512() throws Throwable {
runCastHelper(ZERO_EXTEND_B2S, BSPEC256, SSPEC512);
}
@Test
@IR(counts = {UB2X_NODE, "1"})
public static void testUB64toI64(byte[] input, int[] output) {
vectorCast(ZERO_EXTEND_B2I, BSPEC64, ISPEC64, input, output);
}
@Run(test = "testUB64toI64")
public static void runUB64toI64() throws Throwable {
runCastHelper(ZERO_EXTEND_B2I, BSPEC64, ISPEC64);
}
@Test
@IR(counts = {UB2X_NODE, "1"})
public static void testUB64toI128(byte[] input, int[] output) {
vectorCast(ZERO_EXTEND_B2I, BSPEC64, ISPEC128, input, output);
}
@Run(test = "testUB64toI128")
public static void runUB64toI128() throws Throwable {
runCastHelper(ZERO_EXTEND_B2I, BSPEC64, ISPEC128);
}
@Test
@IR(counts = {UB2X_NODE, "1"})
public static void testUB64toI256(byte[] input, int[] output) {
vectorCast(ZERO_EXTEND_B2I, BSPEC64, ISPEC256, input, output);
}
@Run(test = "testUB64toI256")
public static void runUB64toI256() throws Throwable {
runCastHelper(ZERO_EXTEND_B2I, BSPEC64, ISPEC256);
}
@Test
@IR(counts = {UB2X_NODE, "1"})
public static void testUB128toI512(byte[] input, int[] output) {
vectorCast(ZERO_EXTEND_B2I, BSPEC128, ISPEC512, input, output);
}
@Run(test = "testUB128toI512")
public static void runUB128toI512() throws Throwable {
runCastHelper(ZERO_EXTEND_B2I, BSPEC128, ISPEC512);
}
@Test
@IR(counts = {UB2X_NODE, "1"})
public static void testUB64toL64(byte[] input, long[] output) {
vectorCast(ZERO_EXTEND_B2L, BSPEC64, LSPEC64, input, output);
}
@Run(test = "testUB64toL64")
public static void runUB64toL64() throws Throwable {
runCastHelper(ZERO_EXTEND_B2L, BSPEC64, LSPEC64);
}
@Test
@IR(counts = {UB2X_NODE, "1"})
public static void testUB64toL128(byte[] input, long[] output) {
vectorCast(ZERO_EXTEND_B2L, BSPEC64, LSPEC128, input, output);
}
@Run(test = "testUB64toL128")
public static void runUB64toL128() throws Throwable {
runCastHelper(ZERO_EXTEND_B2L, BSPEC64, LSPEC128);
}
@Test
@IR(counts = {UB2X_NODE, "1"})
public static void testUB64toL256(byte[] input, long[] output) {
vectorCast(ZERO_EXTEND_B2L, BSPEC64, LSPEC256, input, output);
}
@Run(test = "testUB64toL256")
public static void runUB64toL256() throws Throwable {
runCastHelper(ZERO_EXTEND_B2L, BSPEC64, LSPEC256);
}
@Test
@IR(counts = {UB2X_NODE, "1"})
public static void testUB64toL512(byte[] input, long[] output) {
vectorCast(ZERO_EXTEND_B2L, BSPEC64, LSPEC512, input, output);
}
@Run(test = "testUB64toL512")
public static void runUB64toL512() throws Throwable {
runCastHelper(ZERO_EXTEND_B2L, BSPEC64, LSPEC512);
}
@Test
@IR(counts = {US2X_NODE, "1"})
public static void testUS64toI64(short[] input, int[] output) {
vectorCast(ZERO_EXTEND_S2I, SSPEC64, ISPEC64, input, output);
}
@Run(test = "testUS64toI64")
public static void runUS64toI64() throws Throwable {
runCastHelper(ZERO_EXTEND_S2I, SSPEC64, ISPEC64);
}
@Test
@IR(counts = {US2X_NODE, "1"})
public static void testUS64toI128(short[] input, int[] output) {
vectorCast(ZERO_EXTEND_S2I, SSPEC64, ISPEC128, input, output);
}
@Run(test = "testUS64toI128")
public static void runUS64toI128() throws Throwable {
runCastHelper(ZERO_EXTEND_S2I, SSPEC64, ISPEC128);
}
@Test
@IR(counts = {US2X_NODE, "1"})
public static void testUS128toI256(short[] input, int[] output) {
vectorCast(ZERO_EXTEND_S2I, SSPEC128, ISPEC256, input, output);
}
@Run(test = "testUS128toI256")
public static void runUS128toI256() throws Throwable {
runCastHelper(ZERO_EXTEND_S2I, SSPEC128, ISPEC256);
}
@Test
@IR(counts = {US2X_NODE, "1"})
public static void testUS256toI512(short[] input, int[] output) {
vectorCast(ZERO_EXTEND_S2I, SSPEC256, ISPEC512, input, output);
}
@Run(test = "testUS256toI512")
public static void runUS256toI512() throws Throwable {
runCastHelper(ZERO_EXTEND_S2I, SSPEC256, ISPEC512);
}
@Test
@IR(counts = {US2X_NODE, "1"})
public static void testUS64toL64(short[] input, long[] output) {
vectorCast(ZERO_EXTEND_S2L, SSPEC64, LSPEC64, input, output);
}
@Run(test = "testUS64toL64")
public static void runUS64toL64() throws Throwable {
runCastHelper(ZERO_EXTEND_S2L, SSPEC64, LSPEC64);
}
@Test
@IR(counts = {US2X_NODE, "1"})
public static void testUS64toL128(short[] input, long[] output) {
vectorCast(ZERO_EXTEND_S2L, SSPEC64, LSPEC128, input, output);
}
@Run(test = "testUS64toL128")
public static void runUS64toL128() throws Throwable {
runCastHelper(ZERO_EXTEND_S2L, SSPEC64, LSPEC128);
}
@Test
@IR(counts = {US2X_NODE, "1"})
public static void testUS64toL256(short[] input, long[] output) {
vectorCast(ZERO_EXTEND_S2L, SSPEC64, LSPEC256, input, output);
}
@Run(test = "testUS64toL256")
public static void runUS64toL256() throws Throwable {
runCastHelper(ZERO_EXTEND_S2L, SSPEC64, LSPEC256);
}
@Test
@IR(counts = {US2X_NODE, "1"})
public static void testUS128toL512(short[] input, long[] output) {
vectorCast(ZERO_EXTEND_S2L, SSPEC128, LSPEC512, input, output);
}
@Run(test = "testUS128toL512")
public static void runUS128toL512() throws Throwable {
runCastHelper(ZERO_EXTEND_S2L, SSPEC128, LSPEC512);
}
@Test
@IR(counts = {UI2X_NODE, "1"})
public static void testUI64toL64(int[] input, long[] output) {
vectorCast(ZERO_EXTEND_I2L, ISPEC64, LSPEC64, input, output);
}
@Run(test = "testUI64toL64")
public static void runUI64toL64() throws Throwable {
runCastHelper(ZERO_EXTEND_I2L, ISPEC64, LSPEC64);
}
@Test
@IR(counts = {UI2X_NODE, "1"})
public static void testUI64toL128(int[] input, long[] output) {
vectorCast(ZERO_EXTEND_I2L, ISPEC64, LSPEC128, input, output);
}
@Run(test = "testUI64toL128")
public static void runUI64toL128() throws Throwable {
runCastHelper(ZERO_EXTEND_I2L, ISPEC64, LSPEC128);
}
@Test
@IR(counts = {UI2X_NODE, "1"})
public static void testUI128toL256(int[] input, long[] output) {
vectorCast(ZERO_EXTEND_I2L, ISPEC128, LSPEC256, input, output);
}
@Run(test = "testUI128toL256")
public static void runUI128toL256() throws Throwable {
runCastHelper(ZERO_EXTEND_I2L, ISPEC128, LSPEC256);
}
@Test
@IR(counts = {UI2X_NODE, "1"})
public static void testUI256toL512(int[] input, long[] output) {
vectorCast(ZERO_EXTEND_I2L, ISPEC256, LSPEC512, input, output);
}
@Run(test = "testUI256toL512")
public static void runUI256toL512() throws Throwable {
runCastHelper(ZERO_EXTEND_I2L, ISPEC256, LSPEC512);
}
}

View File

@ -63,7 +63,14 @@ public class TestCastMethods {
makePair(FSPEC64, DSPEC128),
makePair(FSPEC128, DSPEC256),
makePair(DSPEC128, FSPEC64),
makePair(DSPEC256, FSPEC128)
makePair(DSPEC256, FSPEC128),
makePair(BSPEC64, SSPEC64, true),
makePair(BSPEC64, SSPEC128, true),
makePair(BSPEC64, ISPEC128, true),
makePair(SSPEC64, ISPEC64, true),
makePair(SSPEC64, ISPEC128, true),
makePair(SSPEC64, LSPEC128, true),
makePair(ISPEC64, LSPEC128, true)
);
public static final List<VectorSpeciesPair> AVX2_CAST_TESTS = Stream.concat(AVX1_CAST_TESTS.stream(), Stream.of(
@ -82,7 +89,13 @@ public class TestCastMethods {
makePair(LSPEC256, BSPEC64),
makePair(LSPEC256, SSPEC64),
makePair(LSPEC256, ISPEC128),
makePair(FSPEC256, ISPEC256)
makePair(FSPEC256, ISPEC256),
makePair(BSPEC128, SSPEC256, true),
makePair(BSPEC64, ISPEC256, true),
makePair(BSPEC64, LSPEC256, true),
makePair(SSPEC128, ISPEC256, true),
makePair(SSPEC64, LSPEC256, true),
makePair(ISPEC128, LSPEC256, true)
)).toList();
public static final List<VectorSpeciesPair> AVX512_CAST_TESTS = Stream.concat(AVX2_CAST_TESTS.stream(), Stream.of(
@ -104,12 +117,18 @@ public class TestCastMethods {
makePair(LSPEC512, ISPEC256),
makePair(FSPEC512, ISPEC512),
makePair(FSPEC256, DSPEC512),
makePair(DSPEC512, FSPEC256)
makePair(DSPEC512, FSPEC256),
makePair(BSPEC128, ISPEC512, true),
makePair(BSPEC64, LSPEC512, true),
makePair(SSPEC256, ISPEC512, true),
makePair(SSPEC128, LSPEC512, true),
makePair(ISPEC256, LSPEC512, true)
)).toList();
public static final List<VectorSpeciesPair> AVX512BW_CAST_TESTS = Stream.concat(AVX512_CAST_TESTS.stream(), Stream.of(
makePair(BSPEC256, SSPEC512),
makePair(SSPEC512, BSPEC256)
makePair(SSPEC512, BSPEC256),
makePair(BSPEC256, SSPEC512, true)
)).toList();
public static final List<VectorSpeciesPair> AVX512DQ_CAST_TESTS = Stream.concat(AVX512_CAST_TESTS.stream(), Stream.of(

View File

@ -75,6 +75,9 @@ public class VectorReshapeHelper {
public static final String L2X_NODE = IRNode.VECTOR_CAST_L2X;
public static final String F2X_NODE = IRNode.VECTOR_CAST_F2X;
public static final String D2X_NODE = IRNode.VECTOR_CAST_D2X;
public static final String UB2X_NODE = IRNode.VECTOR_UCAST_B2X;
public static final String US2X_NODE = IRNode.VECTOR_UCAST_S2X;
public static final String UI2X_NODE = IRNode.VECTOR_UCAST_I2X;
public static final String REINTERPRET_NODE = IRNode.VECTOR_REINTERPRET;
public static void runMainHelper(Class<?> testClass, Stream<VectorSpeciesPair> testMethods, String... flags) {
@ -104,7 +107,7 @@ public class VectorReshapeHelper {
VectorSpecies<T> isp, VectorSpecies<U> osp) throws Throwable {
var random = RandomGenerator.getDefault();
boolean isUnsignedCast = castOp.name().startsWith("ZERO");
String testMethodName = VectorSpeciesPair.makePair(isp, osp).format();
String testMethodName = VectorSpeciesPair.makePair(isp, osp, isUnsignedCast).format();
var caller = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).getCallerClass();
var testMethod = MethodHandles.lookup().findStatic(caller,
testMethodName,