8329887: RISC-V: C2: Support Zvbb Vector And-Not instruction

Reviewed-by: fyang, fjiang
This commit is contained in:
Anjian-Wen 2025-04-17 02:16:24 +00:00 committed by Fei Yang
parent db2dffb6e5
commit 07aad68c17
3 changed files with 139 additions and 3 deletions

View File

@ -1117,6 +1117,74 @@ instruct vxor_regL_masked(vReg dst_src, iRegL src, vRegMask_V0 v0) %{
ins_pipe(pipe_slow);
%}
// ------------------------------ Vector and not -----------------------------------
// vector and not
instruct vand_notI(vReg dst, vReg src1, vReg src2, immI_M1 m1) %{
predicate(UseZvbb);
predicate(Matcher::vector_element_basic_type(n) == T_INT ||
Matcher::vector_element_basic_type(n) == T_BYTE ||
Matcher::vector_element_basic_type(n) == T_SHORT);
match(Set dst (AndV src1 (XorV src2 (Replicate m1))));
format %{ "vand_notI $dst, $src1, $src2" %}
ins_encode %{
BasicType bt = Matcher::vector_element_basic_type(this);
__ vsetvli_helper(bt, Matcher::vector_length(this));
__ vandn_vv(as_VectorRegister($dst$$reg),
as_VectorRegister($src1$$reg),
as_VectorRegister($src2$$reg));
%}
ins_pipe(pipe_slow);
%}
instruct vand_notL(vReg dst, vReg src1, vReg src2, immL_M1 m1) %{
predicate(UseZvbb);
predicate(Matcher::vector_element_basic_type(n) == T_LONG);
match(Set dst (AndV src1 (XorV src2 (Replicate m1))));
format %{ "vand_notL $dst, $src1, $src2" %}
ins_encode %{
__ vsetvli_helper(T_LONG, Matcher::vector_length(this));
__ vandn_vv(as_VectorRegister($dst$$reg),
as_VectorRegister($src1$$reg),
as_VectorRegister($src2$$reg));
%}
ins_pipe(pipe_slow);
%}
instruct vand_notI_masked(vReg dst_src1, vReg src2, immI_M1 m1, vRegMask_V0 v0) %{
predicate(UseZvbb);
predicate(Matcher::vector_element_basic_type(n) == T_INT ||
Matcher::vector_element_basic_type(n) == T_BYTE ||
Matcher::vector_element_basic_type(n) == T_SHORT);
match(Set dst_src1 (AndV (Binary dst_src1 (XorV src2 (Replicate m1))) v0));
format %{ "vand_notI_masked $dst_src1, $dst_src1, $src2, $v0" %}
ins_encode %{
BasicType bt = Matcher::vector_element_basic_type(this);
__ vsetvli_helper(bt, Matcher::vector_length(this));
__ vandn_vv(as_VectorRegister($dst_src1$$reg),
as_VectorRegister($dst_src1$$reg),
as_VectorRegister($src2$$reg),
Assembler::v0_t);
%}
ins_pipe(pipe_slow);
%}
instruct vand_notL_masked(vReg dst_src1, vReg src2, immL_M1 m1, vRegMask_V0 v0) %{
predicate(UseZvbb);
predicate(Matcher::vector_element_basic_type(n) == T_LONG);
match(Set dst_src1 (AndV (Binary dst_src1 (XorV src2 (Replicate m1))) v0));
format %{ "vand_notL_masked $dst_src1, $dst_src1, $src2, $v0" %}
ins_encode %{
__ vsetvli_helper(T_LONG, Matcher::vector_length(this));
__ vandn_vv(as_VectorRegister($dst_src1$$reg),
as_VectorRegister($dst_src1$$reg),
as_VectorRegister($src2$$reg),
Assembler::v0_t);
%}
ins_pipe(pipe_slow);
%}
// ------------------------------ Vector not -----------------------------------
// vector not

View File

@ -2116,6 +2116,16 @@ public class IRNode {
machOnlyNameRegex(VAND_NOT_L, "vand_notL");
}
public static final String VAND_NOT_I_MASKED = PREFIX + "VAND_NOT_I_MASKED" + POSTFIX;
static {
machOnlyNameRegex(VAND_NOT_I_MASKED, "vand_notI_masked");
}
public static final String VAND_NOT_L_MASKED = PREFIX + "VAND_NOT_L_MASKED" + POSTFIX;
static {
machOnlyNameRegex(VAND_NOT_L_MASKED, "vand_notL_masked");
}
public static final String VECTOR_BLEND_B = VECTOR_PREFIX + "VECTOR_BLEND_B" + POSTFIX;
static {
vectorNode(VECTOR_BLEND_B, "VectorBlend", TYPE_BYTE);

View File

@ -42,7 +42,7 @@ import jdk.test.lib.Utils;
* @key randomness
* @library /test/lib /
* @requires vm.compiler2.enabled
* @requires vm.cpu.features ~= ".*asimd.*"
* @requires (os.simpleArch == "aarch64" & vm.cpu.features ~= ".*asimd.*") | (os.simpleArch == "riscv64" & vm.cpu.features ~= ".*zvbb.*")
* @summary AArch64: [vector] Make all bits set vector sharable for match rules
* @modules jdk.incubator.vector
*
@ -59,6 +59,9 @@ public class AllBitsSetVectorMatchRuleTest {
private static int[] ia;
private static int[] ib;
private static int[] ir;
private static long[] la;
private static long[] lb;
private static long[] lr;
private static boolean[] ma;
private static boolean[] mb;
private static boolean[] mc;
@ -68,6 +71,9 @@ public class AllBitsSetVectorMatchRuleTest {
ia = new int[LENGTH];
ib = new int[LENGTH];
ir = new int[LENGTH];
la = new long[LENGTH];
lb = new long[LENGTH];
lr = new long[LENGTH];
ma = new boolean[LENGTH];
mb = new boolean[LENGTH];
mc = new boolean[LENGTH];
@ -76,6 +82,8 @@ public class AllBitsSetVectorMatchRuleTest {
for (int i = 0; i < LENGTH; i++) {
ia[i] = RD.nextInt(25);
ib[i] = RD.nextInt(25);
la[i] = RD.nextLong(25);
lb[i] = RD.nextLong(25);
ma[i] = RD.nextBoolean();
mb[i] = RD.nextBoolean();
mc[i] = RD.nextBoolean();
@ -98,8 +106,58 @@ public class AllBitsSetVectorMatchRuleTest {
@Test
@Warmup(10000)
@IR(counts = { IRNode.VAND_NOT_L, " >= 1" }, applyIf = {"UseSVE", "0"})
@IR(counts = { IRNode.VMASK_AND_NOT_L, " >= 1" }, applyIf = {"UseSVE", "> 0"})
@IR(counts = { IRNode.VAND_NOT_L, " >= 1" })
public static void testVectorVAndNotL() {
LongVector av = LongVector.fromArray(L_SPECIES, la, 0);
LongVector bv = LongVector.fromArray(L_SPECIES, lb, 0);
av.not().lanewise(VectorOperators.AND_NOT, bv).intoArray(lr, 0);
// Verify results
for (int i = 0; i < L_SPECIES.length(); i++) {
Asserts.assertEquals((~la[i]) & (~lb[i]), lr[i]);
}
}
@Test
@Warmup(10000)
@IR(counts = { IRNode.VAND_NOT_I_MASKED, " >= 1" }, applyIfPlatform = {"aarch64", "true"}, applyIf = {"UseSVE", "> 0"})
@IR(counts = { IRNode.VAND_NOT_I_MASKED, " >= 1" }, applyIfPlatform = {"riscv64", "true"})
public static void testVectorVAndNotIMasked() {
VectorMask<Integer> avm = VectorMask.fromArray(I_SPECIES, ma, 0);
IntVector av = IntVector.fromArray(I_SPECIES, ia, 0);
IntVector bv = IntVector.fromArray(I_SPECIES, ib, 0);
av.not().lanewise(VectorOperators.AND_NOT, bv, avm).intoArray(ir, 0);
// Verify results
for (int i = 0; i < I_SPECIES.length(); i++) {
if (ma[i] == true) {
Asserts.assertEquals((~ia[i]) & (~ib[i]), ir[i]);
}
}
}
@Test
@Warmup(10000)
@IR(counts = { IRNode.VAND_NOT_L_MASKED, " >= 1" }, applyIfPlatform = {"aarch64", "true"}, applyIf = {"UseSVE", "> 0"})
@IR(counts = { IRNode.VAND_NOT_L_MASKED, " >= 1" }, applyIfPlatform = {"riscv64", "true"})
public static void testVectorVAndNotLMasked() {
VectorMask<Long> avm = VectorMask.fromArray(L_SPECIES, ma, 0);
LongVector av = LongVector.fromArray(L_SPECIES, la, 0);
LongVector bv = LongVector.fromArray(L_SPECIES, lb, 0);
av.not().lanewise(VectorOperators.AND_NOT, bv, avm).intoArray(lr, 0);
// Verify results
for (int i = 0; i < L_SPECIES.length(); i++) {
if (ma[i] == true) {
Asserts.assertEquals((~la[i]) & (~lb[i]), lr[i]);
}
}
}
@Test
@Warmup(10000)
@IR(counts = { IRNode.VAND_NOT_L, " >= 1" }, applyIfPlatform = {"aarch64", "true"}, applyIf = {"UseSVE", "0"})
@IR(counts = { IRNode.VMASK_AND_NOT_L, " >= 1" }, applyIfPlatform = {"aarch64", "true"}, applyIf = {"UseSVE", "> 0"})
public static void testAllBitsSetMask() {
VectorMask<Long> avm = VectorMask.fromArray(L_SPECIES, ma, 0);
VectorMask<Long> bvm = VectorMask.fromArray(L_SPECIES, mb, 0);