8308817: RISC-V: Support VectorTest node for Vector API

Co-authored-by: Dingli Zhang <dingli@iscas.ac.cn>
Reviewed-by: fjiang, fyang
This commit is contained in:
Gui Cao 2023-05-30 00:39:53 +00:00 committed by Fei Yang
parent 7508d9f9e0
commit 457e1cb827
2 changed files with 108 additions and 1 deletions

View File

@ -168,7 +168,7 @@
// BoolTest mask for vector test intrinsics
static constexpr BoolTest::mask vectortest_mask(bool is_alltrue, bool is_predicate, int vlen) {
return BoolTest::illegal;
return is_alltrue ? BoolTest::eq : BoolTest::ne;
}
// Returns pre-selection estimated size of a vector operation.

View File

@ -4281,4 +4281,111 @@ instruct vmask_fromlong(vRegMask dst, iRegL src) %{
__ vmv_s_x(as_VectorRegister($dst$$reg), $src$$Register);
%}
ins_pipe(pipe_slow);
%}
// ------------------------------ VectorTest -----------------------------------
// anytrue
// Not matched. Condition is negated and value zero is moved to the right side in CMoveINode::Ideal.
// instruct cmovI_vtest_anytrue(iRegINoSp dst, cmpOp cop, vRegMask op1, vRegMask op2, immI0 zero, immI_1 one) %{
// predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne &&
// static_cast<const VectorTestNode*>(n->in(1)->in(2))->get_predicate() == BoolTest::ne);
// match(Set dst (CMoveI (Binary cop (VectorTest op1 op2)) (Binary zero one)));
// format %{ "CMove $dst, (vectortest $cop $op1 $op2), zero, one\t#@cmovI_vtest_anytrue" %}
// ins_encode %{
// BasicType bt = Matcher::vector_element_basic_type(this, $op1);
// uint vector_length = Matcher::vector_length(this, $op1);
// __ vsetvli_helper(bt, vector_length);
// __ vcpop_m($dst$$Register, as_VectorRegister($op1$$reg));
// __ snez($dst$$Register, $dst$$Register);
// %}
// ins_pipe(pipe_slow);
// %}
instruct cmovI_vtest_anytrue_negate(iRegINoSp dst, cmpOp cop, vRegMask op1, vRegMask op2, immI0 zero, immI_1 one) %{
predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq &&
static_cast<const VectorTestNode*>(n->in(1)->in(2))->get_predicate() == BoolTest::ne);
match(Set dst (CMoveI (Binary cop (VectorTest op1 op2)) (Binary one zero)));
format %{ "CMove $dst, (vectortest $cop $op1 $op2), zero, one\t#@cmovI_vtest_anytrue_negate" %}
ins_encode %{
BasicType bt = Matcher::vector_element_basic_type(this, $op1);
uint vector_length = Matcher::vector_length(this, $op1);
__ vsetvli_helper(bt, vector_length);
__ vcpop_m($dst$$Register, as_VectorRegister($op1$$reg));
__ snez($dst$$Register, $dst$$Register);
%}
ins_pipe(pipe_slow);
%}
// alltrue
// Not matched. Condition is negated and value zero is moved to the right side in CMoveINode::Ideal.
// instruct cmovI_vtest_alltrue(iRegINoSp dst, cmpOp cop, vRegMask op1, vRegMask op2, immI0 zero, immI_1 one) %{
// predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq &&
// static_cast<const VectorTestNode*>(n->in(1)->in(2))->get_predicate() == BoolTest::overflow);
// match(Set dst (CMoveI (Binary cop (VectorTest op1 op2)) (Binary zero one)));
// format %{ "CMove $dst, (vectortest $cop $op1 $op2), zero, one\t#@cmovI_vtest_alltrue" %}
// ins_encode %{
// BasicType bt = Matcher::vector_element_basic_type(this, $op1);
// uint vector_length = Matcher::vector_length(this, $op1);
// __ vsetvli_helper(bt, vector_length);
// __ vcpop_m($dst$$Register, as_VectorRegister($op1$$reg));
// __ sub($dst$$Register, $dst$$Register, vector_length);
// __ seqz($dst$$Register, $dst$$Register);
// %}
// ins_pipe(pipe_slow);
// %}
instruct cmovI_vtest_alltrue_negate(iRegINoSp dst, cmpOp cop, vRegMask op1, vRegMask op2, immI0 zero, immI_1 one) %{
predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne &&
static_cast<const VectorTestNode*>(n->in(1)->in(2))->get_predicate() == BoolTest::overflow);
match(Set dst (CMoveI (Binary cop (VectorTest op1 op2)) (Binary one zero)));
format %{ "CMove $dst, (vectortest $cop $op1 $op2), zero, one\t#@cmovI_vtest_alltrue_negate" %}
ins_encode %{
BasicType bt = Matcher::vector_element_basic_type(this, $op1);
uint vector_length = Matcher::vector_length(this, $op1);
__ vsetvli_helper(bt, vector_length);
__ vcpop_m($dst$$Register, as_VectorRegister($op1$$reg));
__ sub($dst$$Register, $dst$$Register, vector_length);
__ seqz($dst$$Register, $dst$$Register);
%}
ins_pipe(pipe_slow);
%}
// anytrue
instruct vtest_anytrue_branch(cmpOpEqNe cop, vRegMask op1, vRegMask op2, label lbl) %{
predicate(static_cast<const VectorTestNode*>(n->in(2))->get_predicate() == BoolTest::ne);
match(If cop (VectorTest op1 op2));
effect(USE lbl);
format %{ "b$cop (vectortest ne $op1, $op2) $lbl\t#@vtest_anytrue_branch" %}
ins_encode %{
uint vector_length = Matcher::vector_length(this, $op1);
BasicType bt = Matcher::vector_element_basic_type(this, $op1);
__ vsetvli_helper(bt, vector_length);
__ vcpop_m(t0, as_VectorRegister($op1$$reg));
__ enc_cmpEqNe_imm0_branch($cop$$cmpcode, t0, *($lbl$$label), /* is_far */ true);
%}
ins_pipe(pipe_slow);
%}
// alltrue
instruct vtest_alltrue_branch(cmpOpEqNe cop, vRegMask op1, vRegMask op2, label lbl) %{
predicate(static_cast<const VectorTestNode*>(n->in(2))->get_predicate() == BoolTest::overflow);
match(If cop (VectorTest op1 op2));
effect(USE lbl);
format %{ "b$cop (vectortest overflow $op1, $op2) $lbl\t#@vtest_alltrue_branch" %}
ins_encode %{
uint vector_length = Matcher::vector_length(this, $op1);
BasicType bt = Matcher::vector_element_basic_type(this, $op1);
__ vsetvli_helper(bt, vector_length);
__ vcpop_m(t0, as_VectorRegister($op1$$reg));
__ sub(t0, t0, vector_length);
__ enc_cmpEqNe_imm0_branch($cop$$cmpcode, t0, *($lbl$$label), /* is_far */ true);
%}
ins_pipe(pipe_slow);
%}