diff --git a/test/hotspot/jtreg/compiler/vectorization/TestVectorAlgorithms.java b/test/hotspot/jtreg/compiler/vectorization/TestVectorAlgorithms.java index 57b91eb29c4..af86659c607 100644 --- a/test/hotspot/jtreg/compiler/vectorization/TestVectorAlgorithms.java +++ b/test/hotspot/jtreg/compiler/vectorization/TestVectorAlgorithms.java @@ -37,6 +37,7 @@ import java.util.Map; import java.util.HashMap; import jdk.test.lib.Utils; import java.util.Random; +import java.lang.foreign.*; import compiler.lib.ir_framework.*; import compiler.lib.generators.*; @@ -67,6 +68,9 @@ public class TestVectorAlgorithms { int[] rI4; int eI; + int[] oopsX4; + int[] memX4; + public static void main(String[] args) { TestFramework framework = new TestFramework(); // TODO: run with and without SuperWord, and also some intrinsics should be disabled in a run. @@ -129,6 +133,10 @@ public class TestVectorAlgorithms { testGroups.put("filterI", new HashMap()); testGroups.get("filterI").put("filterI_loop", () -> { return filterI_loop(aI, rI1, eI); }); testGroups.get("filterI").put("filterI_VectorAPI", () -> { return filterI_VectorAPI(aI, rI2, eI); }); + + testGroups.put("reduceAddIFieldsX4", new HashMap()); + testGroups.get("reduceAddIFieldsX4").put("reduceAddIFieldsX4_loop", () -> { return reduceAddIFieldsX4_loop(oopsX4, memX4); }); + testGroups.get("reduceAddIFieldsX4").put("reduceAddIFieldsX4_VectorAPI", () -> { return reduceAddIFieldsX4_VectorAPI(oopsX4, memX4); }); } @Warmup(100) @@ -156,7 +164,9 @@ public class TestVectorAlgorithms { "reverseI_loop", "reverseI_VectorAPI", "filterI_loop", - "filterI_VectorAPI"}) + "filterI_VectorAPI", + "reduceAddIFieldsX4_loop", + "reduceAddIFieldsX4_VectorAPI"}) public void runTests(RunInfo info) { // Repeat many times, so that we also have multiple iterations for post-warmup to potentially recompile int iters = info.isWarmUp() ? 1 : 20; @@ -173,6 +183,20 @@ public class TestVectorAlgorithms { rI3 = new int[size]; rI4 = new int[size]; + // X4 oop setup. + oopsX4 = new int[size]; + int numX4 = 10_000; + for (int i = 0; i < size; i++) { + // assign either a zero=null, or assign a random oop. + oopsX4[i] = (RANDOM.nextInt(10) == 0) ? 0 : RANDOM.nextInt(numX4) * 4; + } + // Just fill the whole array with random values. + // The relevant field is only at every "4 * i + 3" though. + memX4 = new int[4 * numX4]; + for (int i = 0; i < 4 * numX4; i++) { + memX4[i] = RANDOM.nextInt(); + } + // Run all tests for (Map.Entry> group_entry : testGroups.entrySet()) { String group_name = group_entry.getKey(); @@ -341,4 +365,14 @@ public class TestVectorAlgorithms { public Object filterI_VectorAPI(int[] a, int[] r, int threshold) { return VectorAlgorithmsImpl.filterI_VectorAPI(a, r, threshold); } + + @Test + public int reduceAddIFieldsX4_loop(int[] oops, int[] mem) { + return VectorAlgorithmsImpl.reduceAddIFieldsX4_loop(oops, mem); + } + + @Test + public int reduceAddIFieldsX4_VectorAPI(int[] oops, int[] mem) { + return VectorAlgorithmsImpl.reduceAddIFieldsX4_VectorAPI(oops, mem); + } } diff --git a/test/hotspot/jtreg/compiler/vectorization/VectorAlgorithmsImpl.java b/test/hotspot/jtreg/compiler/vectorization/VectorAlgorithmsImpl.java index 0b818ee69fa..ea9bc5afd63 100644 --- a/test/hotspot/jtreg/compiler/vectorization/VectorAlgorithmsImpl.java +++ b/test/hotspot/jtreg/compiler/vectorization/VectorAlgorithmsImpl.java @@ -373,4 +373,45 @@ public class VectorAlgorithmsImpl { r[r.length - 1] = j; return r; } + + // X4: ints simulate 4-byte oops. + // oops: if non-zero (= non-null), every entry simpulates a 4-byte oop, pointing into mem. + // mem: an int array that simulates the memory. + // + // Task: Find all non-null oops, and dereference them, get the relevant field. + // Objects have 16 bytes, and the relevant field is at bytes 12-16. + // Sum up all the field values. + public static int reduceAddIFieldsX4_loop(int[] oops, int[] mem) { + int sum = 0; + for (int i = 0; i < oops.length; i++) { + int oop = oops[i]; + if (oop != 0) { + int fieldValue = mem[oop + 3]; // oop+12 + sum += fieldValue; + } + } + return sum; + } + + public static int reduceAddIFieldsX4_VectorAPI(int[] oops, int[] mem) { + var nulls = IntVector.broadcast(SPECIES_I, 0); + var acc = IntVector.broadcast(SPECIES_I, 0); + int i = 0; + for (; i < SPECIES_I.loopBound(oops.length); i += SPECIES_I.length()) { + var oopv = IntVector.fromArray(SPECIES_I, oops, i); + var mask = oopv.compare(VectorOperators.NE, nulls); + // We are lucky today: we need to access mem[oop + 3] + var fieldValues = IntVector.fromArray(SPECIES_I, mem, 3, oops, i, mask); + acc = acc.add(fieldValues); + } + int sum = acc.reduceLanes(VectorOperators.ADD); + for (; i < oops.length; i++) { + int oop = oops[i]; + if (oop != 0) { + int fieldValue = mem[oop + 3]; // oop+12 + sum += fieldValue; + } + } + return sum; + } }