mirror of
https://github.com/openjdk/jdk.git
synced 2026-06-10 20:45:17 +00:00
Implement bitwise_blend in IGVN
The latest changes: 1. Defined a new IR `VectorBitwiseBlendNode` 2. Do the optimization in IGVN: // XorV(a, AndV(sel, XorV(a, b))) => VectorBitwiseBlend(a, b, sel) // XorV(a, AndV(sel, XorV(a, b)), mask) => // VectorBlend(a, VectorBitwiseBlend(a, b, sel), mask) 3. Adjust the ad file match rules to match `VectorBitwiseBlendNode`. 4. Adjust the JTReg tests to check `VectorBitwiseBlendNode`.
This commit is contained in:
parent
a4e3e393f5
commit
b3fe4a975f
@ -317,6 +317,13 @@ source %{
|
||||
return false; // NEON only, since SLI/USHR are not available in SVE
|
||||
}
|
||||
break;
|
||||
case Op_VectorBitwiseBlend:
|
||||
// Use NEON BSL when UseSVE < 2; SVE1 has no BSL so larger vectors are
|
||||
// not supported on UseSVE == 1 machines.
|
||||
if (UseSVE < 2 && length_in_bytes > 16) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -7053,76 +7060,25 @@ instruct vblend_sve(vReg dst, vReg src1, vReg src2, pReg pg) %{
|
||||
|
||||
// ------------------------------ Vector bitwise blend -------------------------
|
||||
|
||||
instruct vbitwise_blend_neon_sve1(vReg dst_src1, vReg src2, vReg src3) %{
|
||||
instruct vbitwise_blend_neon_sve1(vReg src1, vReg src2, vReg dst_src3) %{
|
||||
predicate(UseSVE < 2 &&
|
||||
VM_Version::use_neon_for_vector(Matcher::vector_length_in_bytes(n)));
|
||||
match(Set dst_src1 (XorV src3 (AndV dst_src1 (XorV src2 src3))));
|
||||
// Second form: inner XorV may have operands (src3, src2) after Ideal/GVN.
|
||||
// adlc only auto-swaps commutative ops when at least one operand is a subtree,
|
||||
// not when both sides are leaves, so both shapes need explicit match rules.
|
||||
match(Set dst_src1 (XorV src3 (AndV dst_src1 (XorV src3 src2))));
|
||||
format %{ "vbitwise_blend_neon_sve1 $dst_src1, $src2, $src3" %}
|
||||
match(Set dst_src3 (VectorBitwiseBlend (Binary src1 src2) dst_src3));
|
||||
format %{ "vbitwise_blend_neon_sve1 $src1, $src2, $dst_src3" %}
|
||||
ins_encode %{
|
||||
uint length_in_bytes = Matcher::vector_length_in_bytes(this);
|
||||
Assembler::SIMD_Arrangement T = length_in_bytes == 16 ? __ T16B : __ T8B;
|
||||
__ bsl($dst_src1$$FloatRegister, T, $src2$$FloatRegister, $src3$$FloatRegister);
|
||||
__ bsl($dst_src3$$FloatRegister, T, $src2$$FloatRegister, $src1$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vbitwise_blend_sve2(vReg dst_src1, vReg src2, vReg src3) %{
|
||||
instruct vbitwise_blend_sve2(vReg src1, vReg dst_src2, vReg src3) %{
|
||||
predicate(UseSVE == 2);
|
||||
match(Set dst_src1 (XorV src2 (AndV src3 (XorV dst_src1 src2))));
|
||||
// Second form: inner XorV may have operands (src2, dst_src1) after Ideal/GVN.
|
||||
// adlc only auto-swaps commutative ops when at least one operand is a subtree,
|
||||
// not when both sides are leaves, so both shapes need explicit match rules.
|
||||
match(Set dst_src1 (XorV src2 (AndV src3 (XorV src2 dst_src1))));
|
||||
format %{ "vbitwise_blend_sve2 $dst_src1, $src2, $src3" %}
|
||||
match(Set dst_src2 (VectorBitwiseBlend (Binary src1 dst_src2) src3));
|
||||
format %{ "vbitwise_blend_sve2 $src1, $dst_src2, $src3" %}
|
||||
ins_encode %{
|
||||
__ sve_bsl($dst_src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vbitwise_blend_masked_sve1(vReg dst_src1, vReg src2, vReg src3, pReg pg) %{
|
||||
predicate(UseSVE == 1 &&
|
||||
Matcher::vector_length_in_bytes(n) <= 16);
|
||||
match(Set dst_src1 (XorV (Binary src3 (AndV dst_src1 (XorV src2 src3))) pg));
|
||||
// Second form: inner XorV may have operands (src3, src2) after Ideal/GVN.
|
||||
// adlc only auto-swaps commutative ops when at least one operand is a subtree,
|
||||
// not when both sides are leaves, so both shapes need explicit match rules.
|
||||
match(Set dst_src1 (XorV (Binary src3 (AndV dst_src1 (XorV src3 src2))) pg));
|
||||
format %{ "vbitwise_blend_masked_sve1 $dst_src1, $pg, $src2, $src3" %}
|
||||
ins_encode %{
|
||||
uint length_in_bytes = Matcher::vector_length_in_bytes(this);
|
||||
Assembler::SIMD_Arrangement T = length_in_bytes == 16 ? __ T16B : __ T8B;
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
__ bsl($dst_src1$$FloatRegister, T, $src2$$FloatRegister, $src3$$FloatRegister);
|
||||
// sve_sel reads src3 after bsl overwrites dst_src1.
|
||||
assert($dst_src1$$FloatRegister != $src3$$FloatRegister,
|
||||
"dst_src1 and src3 must not alias");
|
||||
__ sve_sel($dst_src1$$FloatRegister, __ elemType_to_regVariant(bt),
|
||||
$pg$$PRegister, $dst_src1$$FloatRegister, $src3$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vbitwise_blend_masked_sve2(vReg dst_src1, vReg src2, vReg src3, pReg pg) %{
|
||||
predicate(UseSVE == 2);
|
||||
match(Set dst_src1 (XorV (Binary src2 (AndV src3 (XorV dst_src1 src2))) pg));
|
||||
// Second form: inner XorV may have operands (src2, dst_src1) after Ideal/GVN.
|
||||
// adlc only auto-swaps commutative ops when at least one operand is a subtree,
|
||||
// not when both sides are leaves, so both shapes need explicit match rules.
|
||||
match(Set dst_src1 (XorV (Binary src2 (AndV src3 (XorV src2 dst_src1))) pg));
|
||||
format %{ "vbitwise_blend_masked_sve2 $dst_src1, $pg, $src2, $src3" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
__ sve_bsl($dst_src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
|
||||
// sve_sel reads src2 after sve_bsl overwrites dst_src1.
|
||||
assert($dst_src1$$FloatRegister != $src2$$FloatRegister,
|
||||
"dst_src1 and src2 must not alias");
|
||||
__ sve_sel($dst_src1$$FloatRegister, __ elemType_to_regVariant(bt),
|
||||
$pg$$PRegister, $dst_src1$$FloatRegister, $src2$$FloatRegister);
|
||||
__ sve_bsl($dst_src2$$FloatRegister, $src1$$FloatRegister, $src3$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
@ -307,6 +307,13 @@ source %{
|
||||
return false; // NEON only, since SLI/USHR are not available in SVE
|
||||
}
|
||||
break;
|
||||
case Op_VectorBitwiseBlend:
|
||||
// Use NEON BSL when UseSVE < 2; SVE1 has no BSL so larger vectors are
|
||||
// not supported on UseSVE == 1 machines.
|
||||
if (UseSVE < 2 && length_in_bytes > 16) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -4756,76 +4763,25 @@ instruct vblend_sve(vReg dst, vReg src1, vReg src2, pReg pg) %{
|
||||
|
||||
// ------------------------------ Vector bitwise blend -------------------------
|
||||
|
||||
instruct vbitwise_blend_neon_sve1(vReg dst_src1, vReg src2, vReg src3) %{
|
||||
instruct vbitwise_blend_neon_sve1(vReg src1, vReg src2, vReg dst_src3) %{
|
||||
predicate(UseSVE < 2 &&
|
||||
VM_Version::use_neon_for_vector(Matcher::vector_length_in_bytes(n)));
|
||||
match(Set dst_src1 (XorV src3 (AndV dst_src1 (XorV src2 src3))));
|
||||
// Second form: inner XorV may have operands (src3, src2) after Ideal/GVN.
|
||||
// adlc only auto-swaps commutative ops when at least one operand is a subtree,
|
||||
// not when both sides are leaves, so both shapes need explicit match rules.
|
||||
match(Set dst_src1 (XorV src3 (AndV dst_src1 (XorV src3 src2))));
|
||||
format %{ "vbitwise_blend_neon_sve1 $dst_src1, $src2, $src3" %}
|
||||
match(Set dst_src3 (VectorBitwiseBlend (Binary src1 src2) dst_src3));
|
||||
format %{ "vbitwise_blend_neon_sve1 $src1, $src2, $dst_src3" %}
|
||||
ins_encode %{
|
||||
uint length_in_bytes = Matcher::vector_length_in_bytes(this);
|
||||
Assembler::SIMD_Arrangement T = length_in_bytes == 16 ? __ T16B : __ T8B;
|
||||
__ bsl($dst_src1$$FloatRegister, T, $src2$$FloatRegister, $src3$$FloatRegister);
|
||||
__ bsl($dst_src3$$FloatRegister, T, $src2$$FloatRegister, $src1$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vbitwise_blend_sve2(vReg dst_src1, vReg src2, vReg src3) %{
|
||||
instruct vbitwise_blend_sve2(vReg src1, vReg dst_src2, vReg src3) %{
|
||||
predicate(UseSVE == 2);
|
||||
match(Set dst_src1 (XorV src2 (AndV src3 (XorV dst_src1 src2))));
|
||||
// Second form: inner XorV may have operands (src2, dst_src1) after Ideal/GVN.
|
||||
// adlc only auto-swaps commutative ops when at least one operand is a subtree,
|
||||
// not when both sides are leaves, so both shapes need explicit match rules.
|
||||
match(Set dst_src1 (XorV src2 (AndV src3 (XorV src2 dst_src1))));
|
||||
format %{ "vbitwise_blend_sve2 $dst_src1, $src2, $src3" %}
|
||||
match(Set dst_src2 (VectorBitwiseBlend (Binary src1 dst_src2) src3));
|
||||
format %{ "vbitwise_blend_sve2 $src1, $dst_src2, $src3" %}
|
||||
ins_encode %{
|
||||
__ sve_bsl($dst_src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vbitwise_blend_masked_sve1(vReg dst_src1, vReg src2, vReg src3, pReg pg) %{
|
||||
predicate(UseSVE == 1 &&
|
||||
Matcher::vector_length_in_bytes(n) <= 16);
|
||||
match(Set dst_src1 (XorV (Binary src3 (AndV dst_src1 (XorV src2 src3))) pg));
|
||||
// Second form: inner XorV may have operands (src3, src2) after Ideal/GVN.
|
||||
// adlc only auto-swaps commutative ops when at least one operand is a subtree,
|
||||
// not when both sides are leaves, so both shapes need explicit match rules.
|
||||
match(Set dst_src1 (XorV (Binary src3 (AndV dst_src1 (XorV src3 src2))) pg));
|
||||
format %{ "vbitwise_blend_masked_sve1 $dst_src1, $pg, $src2, $src3" %}
|
||||
ins_encode %{
|
||||
uint length_in_bytes = Matcher::vector_length_in_bytes(this);
|
||||
Assembler::SIMD_Arrangement T = length_in_bytes == 16 ? __ T16B : __ T8B;
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
__ bsl($dst_src1$$FloatRegister, T, $src2$$FloatRegister, $src3$$FloatRegister);
|
||||
// sve_sel reads src3 after bsl overwrites dst_src1.
|
||||
assert($dst_src1$$FloatRegister != $src3$$FloatRegister,
|
||||
"dst_src1 and src3 must not alias");
|
||||
__ sve_sel($dst_src1$$FloatRegister, __ elemType_to_regVariant(bt),
|
||||
$pg$$PRegister, $dst_src1$$FloatRegister, $src3$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vbitwise_blend_masked_sve2(vReg dst_src1, vReg src2, vReg src3, pReg pg) %{
|
||||
predicate(UseSVE == 2);
|
||||
match(Set dst_src1 (XorV (Binary src2 (AndV src3 (XorV dst_src1 src2))) pg));
|
||||
// Second form: inner XorV may have operands (src2, dst_src1) after Ideal/GVN.
|
||||
// adlc only auto-swaps commutative ops when at least one operand is a subtree,
|
||||
// not when both sides are leaves, so both shapes need explicit match rules.
|
||||
match(Set dst_src1 (XorV (Binary src2 (AndV src3 (XorV src2 dst_src1))) pg));
|
||||
format %{ "vbitwise_blend_masked_sve2 $dst_src1, $pg, $src2, $src3" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
__ sve_bsl($dst_src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
|
||||
// sve_sel reads src2 after sve_bsl overwrites dst_src1.
|
||||
assert($dst_src1$$FloatRegister != $src2$$FloatRegister,
|
||||
"dst_src1 and src2 must not alias");
|
||||
__ sve_sel($dst_src1$$FloatRegister, __ elemType_to_regVariant(bt),
|
||||
$pg$$PRegister, $dst_src1$$FloatRegister, $src2$$FloatRegister);
|
||||
__ sve_bsl($dst_src2$$FloatRegister, $src1$$FloatRegister, $src3$$FloatRegister);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
@ -512,6 +512,7 @@ macro(VectorMaskWrapper)
|
||||
macro(VectorMaskCmp)
|
||||
macro(VectorMaskCast)
|
||||
macro(VectorTest)
|
||||
macro(VectorBitwiseBlend)
|
||||
macro(VectorBlend)
|
||||
macro(VectorRearrange)
|
||||
macro(VectorLoadMask)
|
||||
|
||||
@ -2385,7 +2385,8 @@ void Matcher::find_shared_post_visit(Node* n, uint opcode) {
|
||||
break;
|
||||
}
|
||||
case Op_VectorBlend:
|
||||
case Op_VectorInsert: {
|
||||
case Op_VectorInsert:
|
||||
case Op_VectorBitwiseBlend: {
|
||||
Node* pair = new BinaryNode(n->in(1), n->in(2));
|
||||
n->set_req(1, pair);
|
||||
n->set_req(2, n->in(3));
|
||||
|
||||
@ -874,6 +874,7 @@ VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, Node* n3, const TypeV
|
||||
case Op_SignumVD: return new SignumVDNode(n1, n2, n3, vt);
|
||||
case Op_SignumVF: return new SignumVFNode(n1, n2, n3, vt);
|
||||
case Op_VectorBlend: return new VectorBlendNode(n1, n2, n3);
|
||||
case Op_VectorBitwiseBlend: return new VectorBitwiseBlendNode(n1, n2, n3, vt);
|
||||
default:
|
||||
fatal("Missed vector creation for '%s'", NodeClassNames[vopc]);
|
||||
return nullptr;
|
||||
@ -2768,6 +2769,73 @@ Node* XorVNode::Ideal_XorV_VectorMaskCmp(PhaseGVN* phase, bool can_reshape) {
|
||||
return res;
|
||||
}
|
||||
|
||||
// XorV(a, AndV(sel, XorV(a, b))) => VectorBitwiseBlend(a, b, sel)
|
||||
// XorV(a, AndV(sel, XorV(a, b)), mask) =>
|
||||
// VectorBlend(a, VectorBitwiseBlend(a, b, sel), mask)
|
||||
Node* XorVNode::Ideal_XorV_to_VectorBitwiseBlend(PhaseGVN* phase, bool can_reshape) {
|
||||
const TypeVect* vt = vect_type();
|
||||
BasicType bt = vt->element_basic_type();
|
||||
uint vlen = vt->length();
|
||||
if (!Matcher::match_rule_supported_vector(Op_VectorBitwiseBlend, vlen, bt)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool is_masked = is_predicated_vector();
|
||||
if (is_masked &&
|
||||
!Matcher::match_rule_supported_vector(Op_VectorBlend, vlen, bt)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// For the predicated case in(1) is fixed as the merge source. Otherwise the
|
||||
// outer XorV is commutative.
|
||||
Node* a = nullptr;
|
||||
Node* andv = nullptr;
|
||||
if (is_masked) {
|
||||
a = in(1);
|
||||
andv = in(2);
|
||||
} else if (in(2)->Opcode() == Op_AndV) {
|
||||
andv = in(2);
|
||||
a = in(1);
|
||||
} else {
|
||||
andv = in(1);
|
||||
a = in(2);
|
||||
}
|
||||
if (andv->Opcode() != Op_AndV || andv->is_predicated_vector()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Node* sel = nullptr;
|
||||
Node* inner_xor = nullptr;
|
||||
if (andv->in(2)->Opcode() == Op_XorV) {
|
||||
inner_xor = andv->in(2);
|
||||
sel = andv->in(1);
|
||||
} else if (andv->in(1)->Opcode() == Op_XorV) {
|
||||
inner_xor = andv->in(1);
|
||||
sel = andv->in(2);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
if (inner_xor->is_predicated_vector()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Node* b = nullptr;
|
||||
if (inner_xor->in(1) == a) {
|
||||
b = inner_xor->in(2);
|
||||
} else if (inner_xor->in(2) == a) {
|
||||
b = inner_xor->in(1);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Node* blend = new VectorBitwiseBlendNode(a, b, sel, vt);
|
||||
if (!is_masked) {
|
||||
return blend;
|
||||
}
|
||||
blend = phase->transform(blend);
|
||||
return new VectorBlendNode(a, blend, in(3));
|
||||
}
|
||||
|
||||
Node* XorVNode::Ideal(PhaseGVN* phase, bool can_reshape) {
|
||||
// (XorV src src) => (Replicate zero)
|
||||
// (XorVMask src src) => (MaskAll zero)
|
||||
@ -2786,6 +2854,11 @@ Node* XorVNode::Ideal(PhaseGVN* phase, bool can_reshape) {
|
||||
if (res != nullptr) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = Ideal_XorV_to_VectorBitwiseBlend(phase, can_reshape);
|
||||
if (res != nullptr) {
|
||||
return res;
|
||||
}
|
||||
return VectorNode::Ideal(phase, can_reshape);
|
||||
}
|
||||
|
||||
|
||||
@ -1075,6 +1075,7 @@ class XorVNode : public VectorNode {
|
||||
virtual int Opcode() const;
|
||||
virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
|
||||
Node* Ideal_XorV_VectorMaskCmp(PhaseGVN* phase, bool can_reshape);
|
||||
Node* Ideal_XorV_to_VectorBitwiseBlend(PhaseGVN* phase, bool can_reshape);
|
||||
};
|
||||
|
||||
// Vector xor byte, short, int, long as a reduction
|
||||
@ -1802,6 +1803,14 @@ class VectorBlendNode : public VectorNode {
|
||||
Node* vec_mask() const { return in(3); }
|
||||
};
|
||||
|
||||
// Vector bitwise blend (bit-select): (sel & vec_true) | (~sel & vec_false).
|
||||
class VectorBitwiseBlendNode : public VectorNode {
|
||||
public:
|
||||
VectorBitwiseBlendNode(Node* vec_false, Node* vec_true, Node* sel, const TypeVect* vt)
|
||||
: VectorNode(vec_false, vec_true, sel, vt) {}
|
||||
virtual int Opcode() const;
|
||||
};
|
||||
|
||||
// Rearrange lane elements from a source vector under the control of a shuffle
|
||||
// (indexes) vector. Each lane in the shuffle vector specifies which lane from
|
||||
// the source vector to select for the corresponding output lane. All indexes
|
||||
|
||||
@ -2392,26 +2392,6 @@ public class IRNode {
|
||||
machOnlyNameRegex(VAND_NOT_L_MASKED, "vand_notL_masked");
|
||||
}
|
||||
|
||||
public static final String VBITWISE_BLEND_NEON_SVE1 = PREFIX + "VBITWISE_BLEND_NEON_SVE1" + POSTFIX;
|
||||
static {
|
||||
machOnlyNameRegex(VBITWISE_BLEND_NEON_SVE1, "vbitwise_blend_neon_sve1");
|
||||
}
|
||||
|
||||
public static final String VBITWISE_BLEND_SVE2 = PREFIX + "VBITWISE_BLEND_SVE2" + POSTFIX;
|
||||
static {
|
||||
machOnlyNameRegex(VBITWISE_BLEND_SVE2, "vbitwise_blend_sve2");
|
||||
}
|
||||
|
||||
public static final String VBITWISE_BLEND_MASKED_SVE1 = PREFIX + "VBITWISE_BLEND_MASKED_SVE1" + POSTFIX;
|
||||
static {
|
||||
machOnlyNameRegex(VBITWISE_BLEND_MASKED_SVE1, "vbitwise_blend_masked_sve1");
|
||||
}
|
||||
|
||||
public static final String VBITWISE_BLEND_MASKED_SVE2 = PREFIX + "VBITWISE_BLEND_MASKED_SVE2" + POSTFIX;
|
||||
static {
|
||||
machOnlyNameRegex(VBITWISE_BLEND_MASKED_SVE2, "vbitwise_blend_masked_sve2");
|
||||
}
|
||||
|
||||
public static final String RISCV_VAND_NOTI_VX = PREFIX + "RISCV_VAND_NOTI_VX" + POSTFIX;
|
||||
static {
|
||||
machOnlyNameRegex(RISCV_VAND_NOTI_VX, "vand_notI_vx");
|
||||
@ -2462,6 +2442,12 @@ public class IRNode {
|
||||
vectorNode(VECTOR_BLEND_D, "VectorBlend", TYPE_DOUBLE);
|
||||
}
|
||||
|
||||
public static final String VECTOR_BITWISE_BLEND = PREFIX + "VECTOR_BITWISE_BLEND" + POSTFIX;
|
||||
static {
|
||||
String regex = START + "VectorBitwiseBlend" + MID + END;
|
||||
afterBarrierExpansionToBeforeMatching(VECTOR_BITWISE_BLEND, regex);
|
||||
}
|
||||
|
||||
public static final String VECTOR_MASK_CMP_I = VECTOR_PREFIX + "VECTOR_MASK_CMP_I" + POSTFIX;
|
||||
static {
|
||||
vectorNode(VECTOR_MASK_CMP_I, "VectorMaskCmp", TYPE_INT);
|
||||
|
||||
@ -93,10 +93,10 @@ public class VectorBitwiseBlendTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.VBITWISE_BLEND_NEON_SVE1, "= 1" },
|
||||
@IR(counts = { IRNode.VECTOR_BITWISE_BLEND, "= 1" },
|
||||
applyIfCPUFeatureAnd = { "asimd", "true", "sve2", "false" },
|
||||
applyIf = { "MaxVectorSize", "<= 16" })
|
||||
@IR(counts = { IRNode.VBITWISE_BLEND_SVE2, "= 1" },
|
||||
@IR(counts = { IRNode.VECTOR_BITWISE_BLEND, "= 1" },
|
||||
applyIfCPUFeature = { "sve2", "true" })
|
||||
public static void testUnmaskedBlendByte() {
|
||||
ByteVector va = ByteVector.fromArray(B_SPECIES, ba, 0);
|
||||
@ -106,10 +106,10 @@ public class VectorBitwiseBlendTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.VBITWISE_BLEND_NEON_SVE1, "= 1" },
|
||||
@IR(counts = { IRNode.VECTOR_BITWISE_BLEND, "= 1" },
|
||||
applyIfCPUFeatureAnd = { "asimd", "true", "sve2", "false" },
|
||||
applyIf = { "MaxVectorSize", "<= 16" })
|
||||
@IR(counts = { IRNode.VBITWISE_BLEND_SVE2, "= 1" },
|
||||
@IR(counts = { IRNode.VECTOR_BITWISE_BLEND, "= 1" },
|
||||
applyIfCPUFeature = { "sve2", "true" })
|
||||
public static void testUnmaskedBlendShort() {
|
||||
ShortVector va = ShortVector.fromArray(S_SPECIES, sa, 0);
|
||||
@ -119,10 +119,10 @@ public class VectorBitwiseBlendTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.VBITWISE_BLEND_NEON_SVE1, "= 1" },
|
||||
@IR(counts = { IRNode.VECTOR_BITWISE_BLEND, "= 1" },
|
||||
applyIfCPUFeatureAnd = { "asimd", "true", "sve2", "false" },
|
||||
applyIf = { "MaxVectorSize", "<= 16" })
|
||||
@IR(counts = { IRNode.VBITWISE_BLEND_SVE2, "= 1" },
|
||||
@IR(counts = { IRNode.VECTOR_BITWISE_BLEND, "= 1" },
|
||||
applyIfCPUFeature = { "sve2", "true" })
|
||||
public static void testUnmaskedBlendInt() {
|
||||
IntVector va = IntVector.fromArray(I_SPECIES, ia, 0);
|
||||
@ -132,10 +132,10 @@ public class VectorBitwiseBlendTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.VBITWISE_BLEND_NEON_SVE1, "= 1" },
|
||||
@IR(counts = { IRNode.VECTOR_BITWISE_BLEND, "= 1" },
|
||||
applyIfCPUFeatureAnd = { "asimd", "true", "sve2", "false" },
|
||||
applyIf = { "MaxVectorSize", "<= 16" })
|
||||
@IR(counts = { IRNode.VBITWISE_BLEND_SVE2, "= 1" },
|
||||
@IR(counts = { IRNode.VECTOR_BITWISE_BLEND, "= 1" },
|
||||
applyIfCPUFeature = { "sve2", "true" })
|
||||
public static void testUnmaskedBlendLong() {
|
||||
LongVector va = LongVector.fromArray(L_SPECIES, la, 0);
|
||||
@ -145,13 +145,12 @@ public class VectorBitwiseBlendTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.VBITWISE_BLEND_NEON_SVE1, "= 1" },
|
||||
applyIfCPUFeatureAnd = { "asimd", "true", "sve", "false" },
|
||||
@IR(counts = { IRNode.VECTOR_BLEND_B, "= 1",
|
||||
IRNode.VECTOR_BITWISE_BLEND, "= 1" },
|
||||
applyIfCPUFeatureAnd = { "asimd", "true", "sve2", "false" },
|
||||
applyIf = { "MaxVectorSize", "<= 16" })
|
||||
@IR(counts = { IRNode.VBITWISE_BLEND_MASKED_SVE1, "= 1" },
|
||||
applyIfCPUFeatureAnd = { "sve", "true", "sve2", "false" },
|
||||
applyIf = { "MaxVectorSize", "<= 16" })
|
||||
@IR(counts = { IRNode.VBITWISE_BLEND_MASKED_SVE2, "= 1" },
|
||||
@IR(counts = { IRNode.VECTOR_BLEND_B, "= 1",
|
||||
IRNode.VECTOR_BITWISE_BLEND, "= 1" },
|
||||
applyIfCPUFeature = { "sve2", "true" })
|
||||
public static void testMaskedBlendByte() {
|
||||
VectorMask<Byte> mask = VectorMask.fromArray(B_SPECIES, mask_arr, 0);
|
||||
@ -162,13 +161,12 @@ public class VectorBitwiseBlendTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.VBITWISE_BLEND_NEON_SVE1, "= 1" },
|
||||
applyIfCPUFeatureAnd = { "asimd", "true", "sve", "false" },
|
||||
@IR(counts = { IRNode.VECTOR_BLEND_S, "= 1",
|
||||
IRNode.VECTOR_BITWISE_BLEND, "= 1" },
|
||||
applyIfCPUFeatureAnd = { "asimd", "true", "sve2", "false" },
|
||||
applyIf = { "MaxVectorSize", "<= 16" })
|
||||
@IR(counts = { IRNode.VBITWISE_BLEND_MASKED_SVE1, "= 1" },
|
||||
applyIfCPUFeatureAnd = { "sve", "true", "sve2", "false" },
|
||||
applyIf = { "MaxVectorSize", "<= 16" })
|
||||
@IR(counts = { IRNode.VBITWISE_BLEND_MASKED_SVE2, "= 1" },
|
||||
@IR(counts = { IRNode.VECTOR_BLEND_S, "= 1",
|
||||
IRNode.VECTOR_BITWISE_BLEND, "= 1" },
|
||||
applyIfCPUFeature = { "sve2", "true" })
|
||||
public static void testMaskedBlendShort() {
|
||||
VectorMask<Short> mask = VectorMask.fromArray(S_SPECIES, mask_arr, 0);
|
||||
@ -179,13 +177,12 @@ public class VectorBitwiseBlendTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.VBITWISE_BLEND_NEON_SVE1, "= 1" },
|
||||
applyIfCPUFeatureAnd = { "asimd", "true", "sve", "false" },
|
||||
@IR(counts = { IRNode.VECTOR_BLEND_I, "= 1",
|
||||
IRNode.VECTOR_BITWISE_BLEND, "= 1" },
|
||||
applyIfCPUFeatureAnd = { "asimd", "true", "sve2", "false" },
|
||||
applyIf = { "MaxVectorSize", "<= 16" })
|
||||
@IR(counts = { IRNode.VBITWISE_BLEND_MASKED_SVE1, "= 1" },
|
||||
applyIfCPUFeatureAnd = { "sve", "true", "sve2", "false" },
|
||||
applyIf = { "MaxVectorSize", "<= 16" })
|
||||
@IR(counts = { IRNode.VBITWISE_BLEND_MASKED_SVE2, "= 1" },
|
||||
@IR(counts = { IRNode.VECTOR_BLEND_I, "= 1",
|
||||
IRNode.VECTOR_BITWISE_BLEND, "= 1" },
|
||||
applyIfCPUFeature = { "sve2", "true" })
|
||||
public static void testMaskedBlendInt() {
|
||||
VectorMask<Integer> mask = VectorMask.fromArray(I_SPECIES, mask_arr, 0);
|
||||
@ -196,13 +193,12 @@ public class VectorBitwiseBlendTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.VBITWISE_BLEND_NEON_SVE1, "= 1" },
|
||||
applyIfCPUFeatureAnd = { "asimd", "true", "sve", "false" },
|
||||
@IR(counts = { IRNode.VECTOR_BLEND_L, "= 1",
|
||||
IRNode.VECTOR_BITWISE_BLEND, "= 1" },
|
||||
applyIfCPUFeatureAnd = { "asimd", "true", "sve2", "false" },
|
||||
applyIf = { "MaxVectorSize", "<= 16" })
|
||||
@IR(counts = { IRNode.VBITWISE_BLEND_MASKED_SVE1, "= 1" },
|
||||
applyIfCPUFeatureAnd = { "sve", "true", "sve2", "false" },
|
||||
applyIf = { "MaxVectorSize", "<= 16" })
|
||||
@IR(counts = { IRNode.VBITWISE_BLEND_MASKED_SVE2, "= 1" },
|
||||
@IR(counts = { IRNode.VECTOR_BLEND_L, "= 1",
|
||||
IRNode.VECTOR_BITWISE_BLEND, "= 1" },
|
||||
applyIfCPUFeature = { "sve2", "true" })
|
||||
public static void testMaskedBlendLong() {
|
||||
VectorMask<Long> mask = VectorMask.fromArray(L_SPECIES, mask_arr, 0);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user