diff --git a/src/hotspot/share/opto/vectorIntrinsics.cpp b/src/hotspot/share/opto/vectorIntrinsics.cpp index 43ca51fca67c0..85d9790c0eb54 100644 --- a/src/hotspot/share/opto/vectorIntrinsics.cpp +++ b/src/hotspot/share/opto/vectorIntrinsics.cpp @@ -2502,7 +2502,7 @@ bool LibraryCallKit::inline_vector_extract() { if (vector_klass == nullptr || vector_klass->const_oop() == nullptr || elem_klass == nullptr || elem_klass->const_oop() == nullptr || vlen == nullptr || !vlen->is_con() || - idx == nullptr || !idx->is_con()) { + idx == nullptr) { log_if_needed(" ** missing constant: vclass=%s etype=%s vlen=%s", NodeClassNames[argument(0)->Opcode()], NodeClassNames[argument(1)->Opcode()], diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java index 16c6d99a64f33..52fc9a05f98c3 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java @@ -1417,6 +1417,11 @@ public class IRNode { beforeMatchingNameRegex(VECTOR_MASK_TO_LONG, "VectorMaskToLong"); } + public static final String VECTOR_MASK_LANE_IS_SET = PREFIX + "VECTOR_MASK_LANE_IS_SET" + POSTFIX; + static { + beforeMatchingNameRegex(VECTOR_MASK_LANE_IS_SET, "ExtractUB"); + } + // Can only be used if avx512_vnni is available. public static final String MUL_ADD_VS2VI_VNNI = PREFIX + "MUL_ADD_VS2VI_VNNI" + POSTFIX; static { diff --git a/test/hotspot/jtreg/compiler/vectorapi/VectorMaskLaneIsSetTest.java b/test/hotspot/jtreg/compiler/vectorapi/VectorMaskLaneIsSetTest.java new file mode 100644 index 0000000000000..b7f2103c56cd7 --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/VectorMaskLaneIsSetTest.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi; + +import compiler.lib.ir_framework.*; +import jdk.incubator.vector.*; +import jdk.test.lib.Asserts; + +/** + * @test + * @bug 8366588 + * @key randomness + * @library /test/lib / + * @summary VectorAPI: Re-intrinsify VectorMask.laneIsSet where the input index is a variable + * @modules jdk.incubator.vector + * + * @run driver compiler.vectorapi.VectorMaskLaneIsSetTest + */ + +public class VectorMaskLaneIsSetTest { + static final VectorSpecies B_SPECIES = ByteVector.SPECIES_MAX; + static final VectorSpecies S_SPECIES = ShortVector.SPECIES_MAX; + static final VectorSpecies I_SPECIES = IntVector.SPECIES_MAX; + static final VectorSpecies F_SPECIES = FloatVector.SPECIES_MAX; + static final VectorSpecies L_SPECIES = LongVector.SPECIES_MAX; + static final VectorSpecies D_SPECIES = DoubleVector.SPECIES_MAX; + static final int LENGTH = 512; + static boolean[] ma; + static VectorMask mask_b; + static VectorMask mask_s; + static VectorMask mask_i; + static VectorMask mask_l; + static VectorMask mask_f; + static VectorMask mask_d; + + static { + ma = new boolean[LENGTH]; + for (int i = 0; i < LENGTH; i++) { + ma[i] = i % 2 == 0; + } + mask_b = VectorMask.fromArray(B_SPECIES, ma, 0); + mask_s = VectorMask.fromArray(S_SPECIES, ma, 0); + mask_i = VectorMask.fromArray(I_SPECIES, ma, 0); + mask_l = VectorMask.fromArray(L_SPECIES, ma, 0); + mask_f = VectorMask.fromArray(F_SPECIES, ma, 0); + mask_d = VectorMask.fromArray(D_SPECIES, ma, 0); + } + + @Test + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 6" }, applyIfCPUFeature = { "asimd", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 6" }, applyIfCPUFeature = { "avx2", "true" }) + public static void testVectorMaskLaneIsSetByte_const() { + Asserts.assertEquals(ma[0], mask_b.laneIsSet(0)); + Asserts.assertEquals(ma[0], mask_s.laneIsSet(0)); + Asserts.assertEquals(ma[0], mask_i.laneIsSet(0)); + Asserts.assertEquals(ma[0], mask_l.laneIsSet(0)); + Asserts.assertEquals(ma[0], mask_f.laneIsSet(0)); + Asserts.assertEquals(ma[0], mask_d.laneIsSet(0)); + } + + @Test + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx", "true" }) + public static boolean testVectorMaskLaneIsSet_Byte_variable(int i) { + return mask_b.laneIsSet(i); + } + + @Run(test = "testVectorMaskLaneIsSet_Byte_variable") + public static void testVectorMaskLaneIsSet_Byte_variable_runner() { + Asserts.assertEquals(ma[0], testVectorMaskLaneIsSet_Byte_variable(0)); + } + + @Test + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx", "true" }) + public static boolean testVectorMaskLaneIsSet_Short_variable(int i) { + return mask_s.laneIsSet(i); + } + + @Run(test = "testVectorMaskLaneIsSet_Short_variable") + public static void testVectorMaskLaneIsSet_Short_variable_runner() { + Asserts.assertEquals(ma[0], testVectorMaskLaneIsSet_Short_variable(0)); + } + + @Test + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx", "true" }) + public static boolean testVectorMaskLaneIsSet_Int_variable(int i) { + return mask_i.laneIsSet(i); + } + + @Run(test = "testVectorMaskLaneIsSet_Int_variable") + public static void testVectorMaskLaneIsSet_Int_variable_runner() { + Asserts.assertEquals(ma[0], testVectorMaskLaneIsSet_Int_variable(0)); + } + + @Test + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx2", "true" }) + public static boolean testVectorMaskLaneIsSet_Long_variable(int i) { + return mask_l.laneIsSet(i); + } + + @Run(test = "testVectorMaskLaneIsSet_Long_variable") + public static void testVectorMaskLaneIsSet_Long_variable_runner() { + Asserts.assertEquals(ma[0], testVectorMaskLaneIsSet_Long_variable(0)); + } + + @Test + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx", "true" }) + public static boolean testVectorMaskLaneIsSet_Float_variable(int i) { + return mask_f.laneIsSet(i); + } + + @Run(test = "testVectorMaskLaneIsSet_Float_variable") + public static void testVectorMaskLaneIsSet_Float_variable_runner() { + Asserts.assertEquals(ma[0], testVectorMaskLaneIsSet_Float_variable(0)); + } + + @Test + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx2", "true" }) + public static boolean testVectorMaskLaneIsSet_Double_variable(int i) { + return mask_d.laneIsSet(i); + } + + @Run(test = "testVectorMaskLaneIsSet_Double_variable") + public static void testVectorMaskLaneIsSet_Double_variable_runner() { + Asserts.assertEquals(ma[0], testVectorMaskLaneIsSet_Double_variable(0)); + } + + public static void main(String[] args) { + TestFramework testFramework = new TestFramework(); + testFramework.setDefaultWarmup(10000) + .addFlags("--add-modules=jdk.incubator.vector") + .start(); + } +} diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorExtractBenchmark.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorExtractBenchmark.java index 6358cb0a5d493..84c9031739cf8 100644 --- a/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorExtractBenchmark.java +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorExtractBenchmark.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2023, Arm Limited. All rights reserved. + * Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +29,9 @@ @OutputTimeUnit(TimeUnit.MILLISECONDS) @State(Scope.Thread) -@Fork(jvmArgs = {"--add-modules=jdk.incubator.vector"}) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +@Fork(value = 1, jvmArgs = {"--add-modules=jdk.incubator.vector"}) public class VectorExtractBenchmark { private int idx = 0; private boolean[] res = new boolean[8];