From 07aad68c17ba8d95aee914f3bd9705301477acf6 Mon Sep 17 00:00:00 2001 From: Anjian-Wen Date: Thu, 17 Apr 2025 02:16:24 +0000 Subject: [PATCH] 8329887: RISC-V: C2: Support Zvbb Vector And-Not instruction Reviewed-by: fyang, fjiang --- src/hotspot/cpu/riscv/riscv_v.ad | 68 +++++++++++++++++++ .../compiler/lib/ir_framework/IRNode.java | 10 +++ .../AllBitsSetVectorMatchRuleTest.java | 64 ++++++++++++++++- 3 files changed, 139 insertions(+), 3 deletions(-) diff --git a/src/hotspot/cpu/riscv/riscv_v.ad b/src/hotspot/cpu/riscv/riscv_v.ad index 1e99b2ece29..9b135215b3d 100644 --- a/src/hotspot/cpu/riscv/riscv_v.ad +++ b/src/hotspot/cpu/riscv/riscv_v.ad @@ -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 diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java index 57e4d413fea..6d58b35f53c 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java @@ -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); diff --git a/test/hotspot/jtreg/compiler/vectorapi/AllBitsSetVectorMatchRuleTest.java b/test/hotspot/jtreg/compiler/vectorapi/AllBitsSetVectorMatchRuleTest.java index e490174e380..f33dd24e726 100644 --- a/test/hotspot/jtreg/compiler/vectorapi/AllBitsSetVectorMatchRuleTest.java +++ b/test/hotspot/jtreg/compiler/vectorapi/AllBitsSetVectorMatchRuleTest.java @@ -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 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 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 avm = VectorMask.fromArray(L_SPECIES, ma, 0); VectorMask bvm = VectorMask.fromArray(L_SPECIES, mb, 0);