Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 11 commits into from
68 changes: 68 additions & 0 deletions src/hotspot/cpu/riscv/riscv_v.ad
Original file line number Diff line number Diff line change
Expand Up @@ -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 src2, vReg src1, 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 src2 (XorV src1 (Replicate m1))));
format %{ "vand_notI $dst, $src2, $src1" %}
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($src2$$reg),
as_VectorRegister($src1$$reg));
%}
ins_pipe(pipe_slow);
%}

instruct vand_notL(vReg dst, vReg src2, vReg src1, immL_M1 m1) %{
predicate(UseZvbb);
predicate(Matcher::vector_element_basic_type(n) == T_LONG);
match(Set dst (AndV src2 (XorV src1 (Replicate m1))));
format %{ "vand_notL $dst, $src2, $src1" %}
ins_encode %{
__ vsetvli_helper(T_LONG, Matcher::vector_length(this));
__ vandn_vv(as_VectorRegister($dst$$reg),
as_VectorRegister($src2$$reg),
as_VectorRegister($src1$$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
Expand Down
10 changes: 10 additions & 0 deletions test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -2076,6 +2076,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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
* @key randomness
* @library /test/lib /
* @requires vm.compiler2.enabled
* @requires vm.cpu.features ~= ".*asimd.*"
* @summary AArch64: [vector] Make all bits set vector sharable for match rules
* @requires (os.simpleArch == "aarch64" & vm.cpu.features ~= ".*asimd.*") | (os.simpleArch == "riscv64" & vm.cpu.features ~= ".*zvbb.*")
* @summary [vector] Make all bits set vector sharable for match rules
* @modules jdk.incubator.vector
*
* @run driver compiler.vectorapi.AllBitsSetVectorMatchRuleTest
Expand All @@ -63,6 +63,9 @@ public class AllBitsSetVectorMatchRuleTest {
private static boolean[] mb;
private static boolean[] mc;
private static boolean[] mr;
private static long[] la;
private static long[] lb;
private static long[] lr;

static {
ia = new int[LENGTH];
Expand All @@ -72,13 +75,18 @@ public class AllBitsSetVectorMatchRuleTest {
mb = new boolean[LENGTH];
mc = new boolean[LENGTH];
mr = new boolean[LENGTH];
la = new long[LENGTH];
lb = new long[LENGTH];
lr = new long[LENGTH];

for (int i = 0; i < LENGTH; i++) {
ia[i] = RD.nextInt(25);
ib[i] = RD.nextInt(25);
ma[i] = RD.nextBoolean();
mb[i] = RD.nextBoolean();
mc[i] = RD.nextBoolean();
la[i] = RD.nextLong(25);
lb[i] = RD.nextLong(25);
}
}

Expand All @@ -98,8 +106,8 @@ public static void testAllBitsSetVector() {

@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" }, 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);
Expand All @@ -112,6 +120,56 @@ public static void testAllBitsSetMask() {
}
}

@Test
@Warmup(10000)
@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]);
}
}
}

public static void main(String[] args) {
TestFramework.runWithFlags("--add-modules=jdk.incubator.vector");
}
Expand Down