diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorShape.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorShape.java index d3a15fac54152..1ffbcef821afb 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorShape.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorShape.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, Oracle and/or its 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 @@ -60,7 +60,7 @@ public enum VectorShape { /** Shape of length 512 bits */ S_512_BIT(512), /** Shape of maximum length supported on the platform */ - S_Max_BIT(VectorSupport.getMaxLaneCount(byte.class) * Byte.SIZE); + S_Max_BIT(getMaxVectorBitSize(byte.class)); final int vectorBitSize; final int vectorBitSizeLog2; @@ -211,10 +211,7 @@ static VectorShape ofSwitchKey(int sk) { /*package-private*/ static VectorShape largestShapeFor(Class etype) { - int laneCount = VectorSupport.getMaxLaneCount(etype); - int elementSize = LaneType.of(etype).elementSize; - int vectorBitSize = laneCount * elementSize; - return VectorShape.forBitSize(vectorBitSize); + return VectorShape.forBitSize(getMaxVectorBitSize(etype)); } /** @@ -244,23 +241,32 @@ private static VectorShape computePreferredShape() { int prefBitSize = Integer.MAX_VALUE; for (LaneType type : LaneType.values()) { Class etype = type.elementType; - int maxLaneCount = VectorSupport.getMaxLaneCount(etype); - int maxSize = type.elementSize * maxLaneCount; - // FIXME: Consider removing, since unlikely to occur on modern hardware - if (maxSize < Double.SIZE) { - String msg = "shape unavailable for lane type: " + etype.getName(); - throw new UnsupportedOperationException(msg); - } - prefBitSize = Math.min(prefBitSize, maxSize); + prefBitSize = Math.min(prefBitSize, getMaxVectorBitSize(etype)); } // If these assertions fail, we must reconsider our API portability assumptions. assert(prefBitSize >= Double.SIZE && prefBitSize < Integer.MAX_VALUE / Long.SIZE); - assert(prefBitSize/Byte.SIZE == VectorSupport.getMaxLaneCount(byte.class)); + assert(prefBitSize == getMaxVectorBitSize(byte.class)); VectorShape shape = VectorShape.forBitSize(prefBitSize); PREFERRED_SHAPE = shape; return shape; } + /** + * Returns the maximum vector bit size for a given element type. + * + * @param etype the element type. + * @return the maximum vector bit. + */ + /*package-private*/ + static int getMaxVectorBitSize(Class etype) { + // VectorSupport.getMaxLaneCount may return -1 if C2 is not enabled, + // or a value smaller than the S_64_BIT.vectorBitSize / elementSizeInBits if MaxVectorSize < 16 + // If so default to S_64_BIT + int maxLaneCount = VectorSupport.getMaxLaneCount(etype); + int elementSizeInBits = LaneType.of(etype).elementSize; + return Math.max(maxLaneCount * elementSizeInBits, S_64_BIT.vectorBitSize); + } + private static @Stable VectorShape PREFERRED_SHAPE; // ==== JROSE NAME CHANGES ==== diff --git a/test/jdk/jdk/incubator/vector/PreferredSpeciesTest.java b/test/jdk/jdk/incubator/vector/PreferredSpeciesTest.java index 00796a9360763..f105df5756cf3 100644 --- a/test/jdk/jdk/incubator/vector/PreferredSpeciesTest.java +++ b/test/jdk/jdk/incubator/vector/PreferredSpeciesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, Oracle and/or its 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 @@ -33,6 +33,16 @@ * @run testng PreferredSpeciesTest */ +/** + * @test + * @bug 8262096 + * @requires vm.compiler2.enabled + * @summary Test the initialization of vector shapes + * @modules jdk.incubator.vector java.base/jdk.internal.vm.vector + * @run testng/othervm -XX:MaxVectorSize=8 PreferredSpeciesTest + * @run testng/othervm -XX:MaxVectorSize=4 PreferredSpeciesTest + */ + public class PreferredSpeciesTest { @DataProvider public static Object[][] classesProvider() { @@ -49,26 +59,35 @@ public static Object[][] classesProvider() { @Test(dataProvider = "classesProvider") void testVectorLength(Class c) { VectorSpecies species = null; + int elemSize = 0; if (c == byte.class) { species = ByteVector.SPECIES_PREFERRED; + elemSize = Byte.SIZE; } else if (c == short.class) { species = ShortVector.SPECIES_PREFERRED; + elemSize = Short.SIZE; } else if (c == int.class) { species = IntVector.SPECIES_PREFERRED; + elemSize = Integer.SIZE; } else if (c == long.class) { species = LongVector.SPECIES_PREFERRED; + elemSize = Long.SIZE; } else if (c == float.class) { species = FloatVector.SPECIES_PREFERRED; + elemSize = Float.SIZE; } else if (c == double.class) { species = DoubleVector.SPECIES_PREFERRED; + elemSize = Double.SIZE; } else { throw new IllegalArgumentException("Bad vector element type: " + c.getName()); } VectorShape shape = VectorShape.preferredShape(); - System.out.println("class = "+c+"; preferred shape"+shape+"; preferred species = "+species+"; maxSize="+VectorSupport.getMaxLaneCount(c)); + int maxLaneCount = Math.max(VectorSupport.getMaxLaneCount(c), 64 / elemSize); + + System.out.println("class = "+c+"; preferred shape"+shape+"; preferred species = "+species+"; maxSize="+maxLaneCount); Assert.assertEquals(species.vectorShape(), shape); - Assert.assertEquals(species.length(), Math.min(species.length(), VectorSupport.getMaxLaneCount(c))); + Assert.assertEquals(species.length(), Math.min(species.length(), maxLaneCount)); } @Test(dataProvider = "classesProvider") @@ -96,12 +115,15 @@ void testVectorShape(Class c) { } else { throw new IllegalArgumentException("Bad vector element type: " + c.getName()); } + + int maxLaneCount = Math.max(VectorSupport.getMaxLaneCount(c), 64 / elemSize); + VectorSpecies largestSpecies = VectorSpecies.ofLargestShape(c); - VectorShape largestShape = VectorShape.forBitSize(VectorSupport.getMaxLaneCount(c) * elemSize); + VectorShape largestShape = VectorShape.forBitSize(maxLaneCount * elemSize); - System.out.println("class = "+c+"; largest species = "+largestSpecies+"; maxSize="+VectorSupport.getMaxLaneCount(c)); + System.out.println("class = "+c+"; largest species = "+largestSpecies+"; maxSize="+maxLaneCount); Assert.assertEquals(largestSpecies.vectorShape(), largestShape); - Assert.assertEquals(largestSpecies.length(), VectorSupport.getMaxLaneCount(c)); - Assert.assertEquals(largestSpecies.length(), Math.max(species.length(), VectorSupport.getMaxLaneCount(c))); + Assert.assertEquals(largestSpecies.length(), maxLaneCount); + Assert.assertEquals(largestSpecies.length(), Math.max(species.length(), maxLaneCount)); } }