diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/library/CodeGenerationDataNameType.java b/test/hotspot/jtreg/compiler/lib/template_framework/library/CodeGenerationDataNameType.java
index 33eba66cd8c9a..2ad4b235f388d 100644
--- a/test/hotspot/jtreg/compiler/lib/template_framework/library/CodeGenerationDataNameType.java
+++ b/test/hotspot/jtreg/compiler/lib/template_framework/library/CodeGenerationDataNameType.java
@@ -33,6 +33,27 @@
* additional functionality for code generation. These types with their extended
* functionality can be used with many other code generation facilities in the
* library, such as generating random {@code Expression}s.
+ *
+ *
This module distinguishes scalar Java types and
+ * Vector API lane-element types:
+ *
+ *
Scalar {@code PRIMITIVE_TYPES}/{@code FLOATING_TYPES}/etc. enumerate
+ * only Java primitive types ({@code byte}, {@code short}, ...).
+ * These lists are typed as {@code List} and are consumed
+ * by scalar fuzzers / scalar code generation. {@link Float16Type} (the
+ * scalar {@code Float16} logical type) is included in
+ * {@link #SCALAR_NUMERIC_TYPES} only.
+ *
Vector-lane lists ({@code VECTOR_ELEMENT_TYPES},
+ * {@code FLOATING_VECTOR_ELEMENT_TYPES}, ...) enumerate the lane types
+ * valid for {@code VectorType.Vector}. These are typed as
+ * {@code List} and additionally include
+ * {@link Float16VectorType#FLOAT16} since {@code Float16Vector} is a real
+ * Vector API type whose lanes happen to have no Java primitive
+ * keyword.
+ *
+ * Vector generators (e.g. {@code Operations.VECTOR_OPERATIONS}) consume the
+ * vector-lane lists; scalar generators (e.g.
+ * {@code Operations.PRIMITIVE_OPERATIONS}) consume the scalar lists.
*/
public interface CodeGenerationDataNameType extends DataName.Type {
@@ -101,9 +122,19 @@ public interface CodeGenerationDataNameType extends DataName.Type {
static PrimitiveType booleans() { return PrimitiveType.BOOLEANS; }
/**
- * The Float16 type.
+ * The {@code Float16Vector} lane-element type. This is a
+ * {@link VectorElementType}, not a Java
+ * {@link PrimitiveType}; it appears in vector-lane lists but never in the
+ * scalar {@code PRIMITIVE_TYPES}/{@code FLOATING_TYPES} lists.
*
- * @return The Float16 type.
+ * @return The {@code Float16Vector} {@link VectorElementType}.
+ */
+ static Float16VectorType float16s() { return Float16VectorType.FLOAT16; }
+
+ /**
+ * The {@code Float16} scalar (logical) type.
+ *
+ * @return The scalar {@code Float16} type.
*/
static CodeGenerationDataNameType float16() { return Float16Type.FLOAT16; }
@@ -185,6 +216,75 @@ public interface CodeGenerationDataNameType extends DataName.Type {
float16()
);
+ // --------------------------------------------------------------------
+ // Vector API lane-element type lists.
+ //
+ // These are typed as List and may include
+ // Float16VectorType.FLOAT16 in addition to the Java primitive lane
+ // carriers. They are the source of truth for vector lane iteration in
+ // vector generators (e.g. Operations.VECTOR_OPS).
+ // --------------------------------------------------------------------
+
+ /**
+ * All Vector API lane-element types: every Java numeric primitive lane
+ * carrier plus {@link Float16VectorType#FLOAT16}.
+ */
+ List VECTOR_ELEMENT_TYPES = List.of(
+ bytes(),
+ shorts(),
+ float16s(),
+ ints(),
+ longs(),
+ floats(),
+ doubles()
+ );
+
+ /**
+ * Integral Vector API lane-element types (byte, short, int, long).
+ */
+ List INTEGRAL_VECTOR_ELEMENT_TYPES = List.of(
+ bytes(),
+ shorts(),
+ ints(),
+ longs()
+ );
+
+ /**
+ * Floating Vector API lane-element types (float16, float, double).
+ */
+ List FLOATING_VECTOR_ELEMENT_TYPES = List.of(
+ float16s(),
+ floats(),
+ doubles()
+ );
+
+ /**
+ * Integral-and-floating Vector API lane-element types: every lane type
+ * except booleans/chars (which have no Vector API counterparts).
+ */
+ List INTEGRAL_AND_FLOATING_VECTOR_ELEMENT_TYPES = List.of(
+ bytes(),
+ shorts(),
+ float16s(),
+ ints(),
+ longs(),
+ floats(),
+ doubles()
+ );
+
+ /**
+ * Vector API lane-element types whose lanes are 32/64 bits and integral
+ * (int, long).
+ */
+ List INT_LONG_VECTOR_ELEMENT_TYPES = List.of(
+ ints(),
+ longs()
+ );
+
+ // --------------------------------------------------------------------
+ // Concrete VectorType lists (typed as the concrete Vector subclasses).
+ // --------------------------------------------------------------------
+
List VECTOR_BYTE_VECTOR_TYPES = List.of(
VectorType.BYTE_64,
VectorType.BYTE_128,
@@ -199,6 +299,13 @@ public interface CodeGenerationDataNameType extends DataName.Type {
VectorType.SHORT_512
);
+ List VECTOR_FLOAT16_VECTOR_TYPES = List.of(
+ VectorType.FLOAT16_64,
+ VectorType.FLOAT16_128,
+ VectorType.FLOAT16_256,
+ VectorType.FLOAT16_512
+ );
+
List VECTOR_INT_VECTOR_TYPES = List.of(
VectorType.INT_64,
VectorType.INT_128,
@@ -230,6 +337,7 @@ public interface CodeGenerationDataNameType extends DataName.Type {
List VECTOR_VECTOR_TYPES = Utils.concat(
VECTOR_BYTE_VECTOR_TYPES,
VECTOR_SHORT_VECTOR_TYPES,
+ VECTOR_FLOAT16_VECTOR_TYPES,
VECTOR_INT_VECTOR_TYPES,
VECTOR_LONG_VECTOR_TYPES,
VECTOR_FLOAT_VECTOR_TYPES,
diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/library/Float16VectorType.java b/test/hotspot/jtreg/compiler/lib/template_framework/library/Float16VectorType.java
new file mode 100644
index 0000000000000..900f8432ebaee
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/lib/template_framework/library/Float16VectorType.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2026, 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
+ * 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.lib.template_framework.library;
+
+import compiler.lib.generators.Generators;
+import compiler.lib.generators.Generator;
+
+import compiler.lib.template_framework.DataName;
+
+/**
+ * The {@link Float16VectorType} is the {@link VectorElementType} that describes
+ * the lane type of a {@code Float16Vector}.
+ *
+ *
Float16 is not a Java primitive type and therefore does
+ * not appear in any of the scalar {@link PrimitiveType} lists. As a
+ * {@link VectorElementType} it appears in vector-lane-typed lists such as
+ * {@link CodeGenerationDataNameType#VECTOR_ELEMENT_TYPES} and
+ * {@link CodeGenerationDataNameType#FLOATING_VECTOR_ELEMENT_TYPES}, which are
+ * consumed by vector-only generators (e.g. {@code Operations.VECTOR_OPERATIONS}).
+ *
+ *
The carrier type for a {@code Float16Vector} lane is {@code short}; the
+ * element type token used in {@code VectorOperators.Conversion.of*} expressions
+ * and {@code Float16Vector.SPECIES_*} is {@code Float16}.
+ *
+ *
NaN handling note: there are multiple bit representations for NaN within
+ * {@code short}/{@code Float16}. Consumers comparing {@code short[]} carrier
+ * arrays should canonicalize via {@code Float.float16ToFloat} (which returns a
+ * canonical NaN) before structural comparison.
+ */
+public final class Float16VectorType implements VectorElementType {
+ private static final Generator GEN_FLOAT16 = Generators.G.float16s();
+
+ /** The singleton instance. */
+ public static final Float16VectorType FLOAT16 = new Float16VectorType();
+
+ private Float16VectorType() {}
+
+ @Override
+ public boolean isSubtypeOf(DataName.Type other) {
+ return other instanceof Float16VectorType;
+ }
+
+ @Override
+ public String name() {
+ return "Float16";
+ }
+
+ @Override
+ public String carrierTypeName() {
+ return "short";
+ }
+
+ @Override
+ public String boxedTypeName() {
+ return "Float16";
+ }
+
+ @Override
+ public int byteSize() {
+ return 2;
+ }
+
+ @Override
+ public boolean isFloating() {
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ // Used by Template `let(...)` hashtag substitution as a Java scalar
+ // type for a single lane. Float16 has no Java keyword, so we return
+ // the carrier ("short"), which is what Float16Vector.lane(int) returns
+ // and what Float16Vector.broadcast(SPECIES, ...) accepts.
+ return carrierTypeName();
+ }
+
+ @Override
+ public Object con() {
+ return "(short)" + GEN_FLOAT16.next();
+ }
+
+ @Override
+ public Object callLibraryRNG() {
+ return "LibraryRNG.nextFloat16()";
+ }
+}
diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/library/Operations.java b/test/hotspot/jtreg/compiler/lib/template_framework/library/Operations.java
index becda83a02975..29c0d98aacc83 100644
--- a/test/hotspot/jtreg/compiler/lib/template_framework/library/Operations.java
+++ b/test/hotspot/jtreg/compiler/lib/template_framework/library/Operations.java
@@ -40,6 +40,10 @@
import static compiler.lib.template_framework.library.CodeGenerationDataNameType.INTEGRAL_TYPES;
import static compiler.lib.template_framework.library.CodeGenerationDataNameType.FLOATING_TYPES;
import static compiler.lib.template_framework.library.CodeGenerationDataNameType.INT_LONG_TYPES;
+import static compiler.lib.template_framework.library.CodeGenerationDataNameType.VECTOR_ELEMENT_TYPES;
+import static compiler.lib.template_framework.library.CodeGenerationDataNameType.INTEGRAL_VECTOR_ELEMENT_TYPES;
+import static compiler.lib.template_framework.library.CodeGenerationDataNameType.FLOATING_VECTOR_ELEMENT_TYPES;
+import static compiler.lib.template_framework.library.CodeGenerationDataNameType.INT_LONG_VECTOR_ELEMENT_TYPES;
/**
* This class provides various lists of {@link Expression}s, that represent Java operators or library
@@ -322,8 +326,11 @@ private enum VOPType {
INTEGRAL_ASSOCIATIVE, // Binary - but only safe for integral reductions
TERNARY
}
- private record VOP(String name, VOPType type, List elementTypes, boolean isDeterministic) {
- VOP(String name, VOPType type, List elementTypes) {
+ // VOP element type pools are typed as VectorElementType so they can include
+ // Float16VectorType.FLOAT16 (the Float16Vector lane type) alongside the
+ // primitive lane types.
+ private record VOP(String name, VOPType type, List elementTypes, boolean isDeterministic) {
+ VOP(String name, VOPType type, List elementTypes) {
this(name, type, elementTypes, true);
}
}
@@ -333,81 +340,81 @@ private record VOP(String name, VOPType type, List elementTypes,
// But if a test is just interested in determinism, they are still
// non-deterministic.
private static final List VECTOR_OPS = List.of(
- new VOP("ABS", VOPType.UNARY, PRIMITIVE_TYPES),
- new VOP("ACOS", VOPType.UNARY, FLOATING_TYPES, false), // 1 ulp
- new VOP("ADD", VOPType.INTEGRAL_ASSOCIATIVE, PRIMITIVE_TYPES),
- new VOP("AND", VOPType.ASSOCIATIVE, INTEGRAL_TYPES),
- new VOP("AND_NOT", VOPType.BINARY, INTEGRAL_TYPES),
- new VOP("ASHR", VOPType.BINARY, INTEGRAL_TYPES),
- new VOP("ASIN", VOPType.UNARY, FLOATING_TYPES, false), // 1 ulp
- new VOP("ATAN", VOPType.UNARY, FLOATING_TYPES, false), // 1 ulp
- new VOP("ATAN2", VOPType.BINARY, FLOATING_TYPES, false), // 2 ulp
- new VOP("BIT_COUNT", VOPType.UNARY, INTEGRAL_TYPES),
- new VOP("BITWISE_BLEND", VOPType.TERNARY, INTEGRAL_TYPES),
- new VOP("CBRT", VOPType.UNARY, FLOATING_TYPES, false), // 1 ulp
- new VOP("COMPRESS_BITS", VOPType.BINARY, INT_LONG_TYPES),
- new VOP("COS", VOPType.UNARY, FLOATING_TYPES, false), // 1 ulp
- new VOP("COSH", VOPType.UNARY, FLOATING_TYPES, false), // 2.5 ulp
- new VOP("DIV", VOPType.BINARY, FLOATING_TYPES),
- new VOP("EXP", VOPType.UNARY, FLOATING_TYPES, false), // 1 ulp
- new VOP("EXPAND_BITS", VOPType.BINARY, INT_LONG_TYPES),
- new VOP("EXPM1", VOPType.UNARY, FLOATING_TYPES, false), // 1 ulp
- new VOP("FIRST_NONZERO", VOPType.ASSOCIATIVE, PRIMITIVE_TYPES),
- new VOP("FMA", VOPType.TERNARY, FLOATING_TYPES),
- new VOP("HYPOT", VOPType.BINARY, FLOATING_TYPES, false), // 1.5 ulp
- new VOP("LEADING_ZEROS_COUNT", VOPType.UNARY, INTEGRAL_TYPES),
- new VOP("LOG", VOPType.UNARY, FLOATING_TYPES, false), // 1 ulp
- new VOP("LOG10", VOPType.UNARY, FLOATING_TYPES, false), // 1 ulp
- new VOP("LOG1P", VOPType.UNARY, FLOATING_TYPES, false), // 1 ulp
- new VOP("LSHL", VOPType.BINARY, INTEGRAL_TYPES),
- new VOP("LSHR", VOPType.BINARY, INTEGRAL_TYPES),
- new VOP("MIN", VOPType.ASSOCIATIVE, PRIMITIVE_TYPES),
- new VOP("MAX", VOPType.ASSOCIATIVE, PRIMITIVE_TYPES),
- new VOP("MUL", VOPType.INTEGRAL_ASSOCIATIVE, PRIMITIVE_TYPES),
- new VOP("NEG", VOPType.UNARY, PRIMITIVE_TYPES),
- new VOP("NOT", VOPType.UNARY, INTEGRAL_TYPES),
- new VOP("OR", VOPType.ASSOCIATIVE, INTEGRAL_TYPES),
- new VOP("POW", VOPType.BINARY, FLOATING_TYPES, false), // 1 ulp
- new VOP("REVERSE", VOPType.UNARY, INTEGRAL_TYPES),
- new VOP("REVERSE_BYTES", VOPType.UNARY, INTEGRAL_TYPES),
- new VOP("ROL", VOPType.BINARY, INTEGRAL_TYPES),
- new VOP("ROR", VOPType.BINARY, INTEGRAL_TYPES),
- new VOP("SADD", VOPType.BINARY, INTEGRAL_TYPES),
- new VOP("SIN", VOPType.UNARY, FLOATING_TYPES, false), // 1 ulp
- new VOP("SINH", VOPType.UNARY, FLOATING_TYPES, false), // 2.5 ulp
- new VOP("SQRT", VOPType.UNARY, FLOATING_TYPES),
- new VOP("SSUB", VOPType.BINARY, INTEGRAL_TYPES),
- new VOP("SUADD", VOPType.BINARY, INTEGRAL_TYPES),
- new VOP("SUB", VOPType.BINARY, PRIMITIVE_TYPES),
- new VOP("SUSUB", VOPType.BINARY, INTEGRAL_TYPES),
- new VOP("TAN", VOPType.UNARY, FLOATING_TYPES, false), // 1.25 ulp
- new VOP("TANH", VOPType.UNARY, FLOATING_TYPES, false), // 2.5 ulp
- new VOP("TRAILING_ZEROS_COUNT", VOPType.UNARY, INTEGRAL_TYPES),
- new VOP("UMAX", VOPType.ASSOCIATIVE, INTEGRAL_TYPES),
- new VOP("UMIN", VOPType.ASSOCIATIVE, INTEGRAL_TYPES),
- new VOP("XOR", VOPType.ASSOCIATIVE, INTEGRAL_TYPES),
- new VOP("ZOMO", VOPType.UNARY, INTEGRAL_TYPES)
+ new VOP("ABS", VOPType.UNARY, VECTOR_ELEMENT_TYPES),
+ new VOP("ACOS", VOPType.UNARY, FLOATING_VECTOR_ELEMENT_TYPES, false), // 1 ulp
+ new VOP("ADD", VOPType.INTEGRAL_ASSOCIATIVE, VECTOR_ELEMENT_TYPES),
+ new VOP("AND", VOPType.ASSOCIATIVE, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("AND_NOT", VOPType.BINARY, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("ASHR", VOPType.BINARY, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("ASIN", VOPType.UNARY, FLOATING_VECTOR_ELEMENT_TYPES, false), // 1 ulp
+ new VOP("ATAN", VOPType.UNARY, FLOATING_VECTOR_ELEMENT_TYPES, false), // 1 ulp
+ new VOP("ATAN2", VOPType.BINARY, FLOATING_VECTOR_ELEMENT_TYPES, false), // 2 ulp
+ new VOP("BIT_COUNT", VOPType.UNARY, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("BITWISE_BLEND", VOPType.TERNARY, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("CBRT", VOPType.UNARY, FLOATING_VECTOR_ELEMENT_TYPES, false), // 1 ulp
+ new VOP("COMPRESS_BITS", VOPType.BINARY, INT_LONG_VECTOR_ELEMENT_TYPES),
+ new VOP("COS", VOPType.UNARY, FLOATING_VECTOR_ELEMENT_TYPES, false), // 1 ulp
+ new VOP("COSH", VOPType.UNARY, FLOATING_VECTOR_ELEMENT_TYPES, false), // 2.5 ulp
+ new VOP("DIV", VOPType.BINARY, FLOATING_VECTOR_ELEMENT_TYPES),
+ new VOP("EXP", VOPType.UNARY, FLOATING_VECTOR_ELEMENT_TYPES, false), // 1 ulp
+ new VOP("EXPAND_BITS", VOPType.BINARY, INT_LONG_VECTOR_ELEMENT_TYPES),
+ new VOP("EXPM1", VOPType.UNARY, FLOATING_VECTOR_ELEMENT_TYPES, false), // 1 ulp
+ new VOP("FIRST_NONZERO", VOPType.ASSOCIATIVE, VECTOR_ELEMENT_TYPES),
+ new VOP("FMA", VOPType.TERNARY, FLOATING_VECTOR_ELEMENT_TYPES),
+ new VOP("HYPOT", VOPType.BINARY, FLOATING_VECTOR_ELEMENT_TYPES, false), // 1.5 ulp
+ new VOP("LEADING_ZEROS_COUNT", VOPType.UNARY, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("LOG", VOPType.UNARY, FLOATING_VECTOR_ELEMENT_TYPES, false), // 1 ulp
+ new VOP("LOG10", VOPType.UNARY, FLOATING_VECTOR_ELEMENT_TYPES, false), // 1 ulp
+ new VOP("LOG1P", VOPType.UNARY, FLOATING_VECTOR_ELEMENT_TYPES, false), // 1 ulp
+ new VOP("LSHL", VOPType.BINARY, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("LSHR", VOPType.BINARY, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("MIN", VOPType.ASSOCIATIVE, VECTOR_ELEMENT_TYPES),
+ new VOP("MAX", VOPType.ASSOCIATIVE, VECTOR_ELEMENT_TYPES),
+ new VOP("MUL", VOPType.INTEGRAL_ASSOCIATIVE, VECTOR_ELEMENT_TYPES),
+ new VOP("NEG", VOPType.UNARY, VECTOR_ELEMENT_TYPES),
+ new VOP("NOT", VOPType.UNARY, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("OR", VOPType.ASSOCIATIVE, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("POW", VOPType.BINARY, FLOATING_VECTOR_ELEMENT_TYPES, false), // 1 ulp
+ new VOP("REVERSE", VOPType.UNARY, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("REVERSE_BYTES", VOPType.UNARY, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("ROL", VOPType.BINARY, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("ROR", VOPType.BINARY, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("SADD", VOPType.BINARY, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("SIN", VOPType.UNARY, FLOATING_VECTOR_ELEMENT_TYPES, false), // 1 ulp
+ new VOP("SINH", VOPType.UNARY, FLOATING_VECTOR_ELEMENT_TYPES, false), // 2.5 ulp
+ new VOP("SQRT", VOPType.UNARY, FLOATING_VECTOR_ELEMENT_TYPES),
+ new VOP("SSUB", VOPType.BINARY, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("SUADD", VOPType.BINARY, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("SUB", VOPType.BINARY, VECTOR_ELEMENT_TYPES),
+ new VOP("SUSUB", VOPType.BINARY, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("TAN", VOPType.UNARY, FLOATING_VECTOR_ELEMENT_TYPES, false), // 1.25 ulp
+ new VOP("TANH", VOPType.UNARY, FLOATING_VECTOR_ELEMENT_TYPES, false), // 2.5 ulp
+ new VOP("TRAILING_ZEROS_COUNT", VOPType.UNARY, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("UMAX", VOPType.ASSOCIATIVE, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("UMIN", VOPType.ASSOCIATIVE, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("XOR", VOPType.ASSOCIATIVE, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("ZOMO", VOPType.UNARY, INTEGRAL_VECTOR_ELEMENT_TYPES)
);
private static final List VECTOR_CMP = List.of(
- new VOP("EQ", VOPType.ASSOCIATIVE, PRIMITIVE_TYPES),
- new VOP("GE", VOPType.ASSOCIATIVE, PRIMITIVE_TYPES),
- new VOP("GT", VOPType.ASSOCIATIVE, PRIMITIVE_TYPES),
- new VOP("LE", VOPType.ASSOCIATIVE, PRIMITIVE_TYPES),
- new VOP("LT", VOPType.ASSOCIATIVE, PRIMITIVE_TYPES),
- new VOP("NE", VOPType.ASSOCIATIVE, PRIMITIVE_TYPES),
- new VOP("UGE", VOPType.ASSOCIATIVE, INTEGRAL_TYPES),
- new VOP("UGT", VOPType.ASSOCIATIVE, INTEGRAL_TYPES),
- new VOP("ULE", VOPType.ASSOCIATIVE, INTEGRAL_TYPES),
- new VOP("ULT", VOPType.ASSOCIATIVE, INTEGRAL_TYPES)
+ new VOP("EQ", VOPType.ASSOCIATIVE, VECTOR_ELEMENT_TYPES),
+ new VOP("GE", VOPType.ASSOCIATIVE, VECTOR_ELEMENT_TYPES),
+ new VOP("GT", VOPType.ASSOCIATIVE, VECTOR_ELEMENT_TYPES),
+ new VOP("LE", VOPType.ASSOCIATIVE, VECTOR_ELEMENT_TYPES),
+ new VOP("LT", VOPType.ASSOCIATIVE, VECTOR_ELEMENT_TYPES),
+ new VOP("NE", VOPType.ASSOCIATIVE, VECTOR_ELEMENT_TYPES),
+ new VOP("UGE", VOPType.ASSOCIATIVE, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("UGT", VOPType.ASSOCIATIVE, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("ULE", VOPType.ASSOCIATIVE, INTEGRAL_VECTOR_ELEMENT_TYPES),
+ new VOP("ULT", VOPType.ASSOCIATIVE, INTEGRAL_VECTOR_ELEMENT_TYPES)
);
private static final List VECTOR_TEST = List.of(
- new VOP("IS_DEFAULT", VOPType.UNARY, PRIMITIVE_TYPES),
- new VOP("IS_NEGATIVE", VOPType.UNARY, PRIMITIVE_TYPES),
- new VOP("IS_FINITE", VOPType.UNARY, FLOATING_TYPES),
- new VOP("IS_NAN", VOPType.UNARY, FLOATING_TYPES),
- new VOP("IS_INFINITE", VOPType.UNARY, FLOATING_TYPES)
+ new VOP("IS_DEFAULT", VOPType.UNARY, VECTOR_ELEMENT_TYPES),
+ new VOP("IS_NEGATIVE", VOPType.UNARY, VECTOR_ELEMENT_TYPES),
+ new VOP("IS_FINITE", VOPType.UNARY, FLOATING_VECTOR_ELEMENT_TYPES),
+ new VOP("IS_NAN", VOPType.UNARY, FLOATING_VECTOR_ELEMENT_TYPES),
+ new VOP("IS_INFINITE", VOPType.UNARY, FLOATING_VECTOR_ELEMENT_TYPES)
);
// TODO: Conversion VectorOperators -> convertShape
@@ -519,6 +526,9 @@ private static List generateVectorOperations() {
if (type.elementType == FLOATS) {
ops.add(Expression.make(type, "", type2, ".reinterpretAsFloats()", reinterpretInfo));
}
+ if (type.elementType instanceof Float16VectorType) {
+ ops.add(Expression.make(type, "", type2, ".reinterpretAsFloat16s()", reinterpretInfo));
+ }
if (type.elementType == DOUBLES) {
ops.add(Expression.make(type, "", type2, ".reinterpretAsDoubles()", reinterpretInfo));
}
@@ -834,8 +844,18 @@ private static List ternaryOps(Operations.VOP vop, VectorType.Vector
FLOAT16_OPERATIONS
);
+ /**
+ * Provides a list of Vector API operations. Iterates over all
+ * {@link CodeGenerationDataNameType#VECTOR_VECTOR_TYPES}, including
+ * {@code Float16Vector_*}, whose lanes are described by
+ * {@link Float16VectorType#FLOAT16}.
+ */
public static final List VECTOR_OPERATIONS = generateVectorOperations();
+ /**
+ * Provides a list of all operations: every scalar operation and every
+ * Vector API operation.
+ */
public static final List ALL_OPERATIONS = Utils.concat(
SCALAR_NUMERIC_OPERATIONS,
VECTOR_OPERATIONS
diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/library/PrimitiveType.java b/test/hotspot/jtreg/compiler/lib/template_framework/library/PrimitiveType.java
index cd796fd0d3144..ddce36ddfa04c 100644
--- a/test/hotspot/jtreg/compiler/lib/template_framework/library/PrimitiveType.java
+++ b/test/hotspot/jtreg/compiler/lib/template_framework/library/PrimitiveType.java
@@ -40,8 +40,19 @@
* The {@link PrimitiveType} models Java's primitive types, and provides a set
* of useful methods for code generation, such as the {@link #byteSize} and
* {@link #boxedTypeName}.
+ *
+ *
{@link PrimitiveType} is a Java scalar type and additionally
+ * doubles as a {@link VectorElementType} for those Vector API lane types whose
+ * lane carrier is itself a Java primitive (e.g. {@code IntVector}'s lane
+ * carrier is {@code int}). For these primitive lane types
+ * {@link #carrierTypeName} coincides with {@link #name}.
+ *
+ *
Non-primitive lane types, such as the {@code Float16Vector} lane, are
+ * modeled by separate {@link VectorElementType} implementations (see
+ * {@link Float16VectorType}). They do not appear in any of
+ * the scalar {@code PRIMITIVE_TYPES}/{@code FLOATING_TYPES} lists.
*/
-public final class PrimitiveType implements CodeGenerationDataNameType {
+public final class PrimitiveType implements VectorElementType {
private static final Random RANDOM = Utils.getRandomInstance();
private static final RestrictableGenerator GEN_BYTE = Generators.G.safeRestrict(Generators.G.ints(), Byte.MIN_VALUE, Byte.MAX_VALUE);
private static final RestrictableGenerator GEN_CHAR = Generators.G.safeRestrict(Generators.G.ints(), Character.MIN_VALUE, Character.MAX_VALUE);
@@ -107,6 +118,11 @@ public String name() {
};
}
+ @Override
+ public String carrierTypeName() {
+ return name();
+ }
+
@Override
public String toString() {
return name();
@@ -132,6 +148,7 @@ public Object con() {
* @return Size of the type in bytes.
* @throws UnsupportedOperationException for boolean which has no defined size.
*/
+ @Override
public int byteSize() {
return switch (kind) {
case BYTE -> 1;
@@ -147,6 +164,7 @@ public int byteSize() {
*
* @return the name of the boxed type.
*/
+ @Override
public String boxedTypeName() {
return switch (kind) {
case BYTE -> "Byte";
@@ -194,6 +212,7 @@ public String abbrev() {
*
* @return true iff the type is a floating point type.
*/
+ @Override
public boolean isFloating() {
return switch (kind) {
case BYTE, SHORT, CHAR, INT, LONG, BOOLEAN -> false;
@@ -213,6 +232,7 @@ public boolean isFloating() {
* @return the token representing the method call to obtain a
* random value for the given type at runtime.
*/
+ @Override
public Object callLibraryRNG() {
return switch (kind) {
case BYTE -> "LibraryRNG.nextByte()";
@@ -231,6 +251,12 @@ public Object callLibraryRNG() {
* random number generators available, wrapping {@link Generators}. This
* is supposed to be used in tandem with {@link #callLibraryRNG}.
*
+ *
In addition to the Java primitive generators, this also emits
+ * helpers for {@code Float16Vector}'s {@code short} carrier
+ * ({@code nextFloat16()} / {@code fill_float16(short[])}) so that
+ * {@link Float16VectorType#callLibraryRNG()} can be used with vector
+ * fuzzers without depending on this class importing Float16Vector itself.
+ *
* Note: you must ensure that all required imports are performed:
* {@code java.util.Random}
* {@code jdk.test.lib.Utils}
@@ -250,6 +276,7 @@ public static class LibraryRNG {
private static final RestrictableGenerator GEN_LONG = Generators.G.longs();
private static final Generator GEN_DOUBLE = Generators.G.doubles();
private static final Generator GEN_FLOAT = Generators.G.floats();
+ private static final Generator GEN_FLOAT16 = Generators.G.float16s();
public static byte nextByte() {
return GEN_BYTE.next().byteValue();
@@ -283,6 +310,17 @@ public static boolean nextBoolean() {
return RANDOM.nextBoolean();
}
+ // Float16Vector lane helpers. Float16 lanes are carried in short[].
+ public static short nextFloat16() {
+ return GEN_FLOAT16.next();
+ }
+
+ public static void fill_float16(short[] a) {
+ for (int i = 0; i < a.length; i++) {
+ a[i] = nextFloat16();
+ }
+ }
+
""",
CodeGenerationDataNameType.PRIMITIVE_TYPES.stream().map(type -> scope(
let("type", type),
diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/library/VectorElementType.java b/test/hotspot/jtreg/compiler/lib/template_framework/library/VectorElementType.java
new file mode 100644
index 0000000000000..289d68e5d1cc9
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/lib/template_framework/library/VectorElementType.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2026, 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
+ * 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.lib.template_framework.library;
+
+/**
+ * A {@link VectorElementType} describes a single lane-element of a Vector API
+ * vector ({@link VectorType.Vector}). It abstracts over:
+ *
+ *
{@link PrimitiveType} - the standard Java primitive lane types
+ * (byte, short, int, long, float, double, and char/boolean where
+ * applicable). For these {@link #name()} is the primitive keyword
+ * (e.g. {@code "int"}) and {@code name() + ".class"} yields the
+ * primitive {@code Class>} literal ({@code int.class}).
+ *
{@link Float16VectorType} - the {@code Float16Vector} lane type. Float16
+ * has no Java primitive keyword; its lanes are stored in a {@code short[]}
+ * carrier and {@link #name()} returns {@code "Float16"} so that
+ * {@code name() + ".class"} ({@code Float16.class}) is the token expected
+ * by {@code VectorOperators.Conversion.ofCast}/{@code ofReinterpret}.
+ *
+ *
+ *
This interface intentionally lives outside the scalar
+ * {@link PrimitiveType} type lists (e.g. {@code PRIMITIVE_TYPES},
+ * {@code FLOATING_TYPES}). Those lists model Java scalar types and are consumed
+ * by scalar fuzzers. Vector-lane lists (e.g. {@code VECTOR_ELEMENT_TYPES},
+ * {@code FLOATING_VECTOR_ELEMENT_TYPES}) are typed as {@code List}
+ * and may include {@link Float16VectorType#FLOAT16}.
+ */
+public interface VectorElementType extends CodeGenerationDataNameType {
+
+ /**
+ * @return The element type of the Java carrier array used to hold these
+ * lanes when calling {@code fromArray}/{@code intoArray}. For most
+ * lane types this is the same as {@link #name()}; for
+ * {@code Float16} it is {@code "short"}.
+ */
+ String carrierTypeName();
+
+ /**
+ * @return The boxed type name used to parameterize generic types such as
+ * {@code VectorMask} and {@code VectorShuffle}
+ * (e.g. {@code "Integer"}, {@code "Float16"}).
+ */
+ String boxedTypeName();
+
+ /**
+ * @return Size of the lane type in bytes.
+ */
+ int byteSize();
+
+ /**
+ * @return {@code true} iff the lane type is a floating point type.
+ */
+ boolean isFloating();
+
+ /**
+ * @return A token representing a call to the corresponding pseudo random
+ * number generator from {@link PrimitiveType#generateLibraryRNG()}.
+ */
+ Object callLibraryRNG();
+}
diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/library/VectorType.java b/test/hotspot/jtreg/compiler/lib/template_framework/library/VectorType.java
index 7eabd42a723f0..710186df8c5c9 100644
--- a/test/hotspot/jtreg/compiler/lib/template_framework/library/VectorType.java
+++ b/test/hotspot/jtreg/compiler/lib/template_framework/library/VectorType.java
@@ -39,6 +39,11 @@
/**
* The {@link VectorType} models the Vector API types.
+ *
+ *
A {@code VectorType.Vector} is parameterized by a {@link VectorElementType}
+ * (its lane element type) and a lane count. The lane element type may be a
+ * Java primitive lane ({@link PrimitiveType}) or {@link Float16VectorType} for
+ * {@code Float16Vector}.
*/
public abstract class VectorType implements CodeGenerationDataNameType {
private static final Random RANDOM = Utils.getRandomInstance();
@@ -73,6 +78,11 @@ public abstract class VectorType implements CodeGenerationDataNameType {
public static final VectorType.Vector DOUBLE_256 = new VectorType.Vector(DOUBLES, 4);
public static final VectorType.Vector DOUBLE_512 = new VectorType.Vector(DOUBLES, 8);
+ public static final VectorType.Vector FLOAT16_64 = new VectorType.Vector(Float16VectorType.FLOAT16, 4);
+ public static final VectorType.Vector FLOAT16_128 = new VectorType.Vector(Float16VectorType.FLOAT16, 8);
+ public static final VectorType.Vector FLOAT16_256 = new VectorType.Vector(Float16VectorType.FLOAT16, 16);
+ public static final VectorType.Vector FLOAT16_512 = new VectorType.Vector(Float16VectorType.FLOAT16, 32);
+
private final String vectorTypeName;
private VectorType(String vectorTypeName) {
@@ -95,7 +105,7 @@ public boolean isSubtypeOf(DataName.Type other) {
return this == other;
}
- private static final String vectorTypeName(PrimitiveType elementType) {
+ private static final String vectorTypeName(VectorElementType elementType) {
return switch(elementType.name()) {
case "byte" -> "ByteVector";
case "short" -> "ShortVector";
@@ -104,19 +114,20 @@ private static final String vectorTypeName(PrimitiveType elementType) {
case "long" -> "LongVector";
case "float" -> "FloatVector";
case "double" -> "DoubleVector";
+ case "Float16" -> "Float16Vector";
default -> throw new UnsupportedOperationException("Not supported: " + elementType.name());
};
}
public static final class Vector extends VectorType {
- public final PrimitiveType elementType;
+ public final VectorElementType elementType;
public final int length; // lane count
public final String speciesName;
public final Mask maskType;
public final Shuffle shuffleType;
- private Vector(PrimitiveType elementType, int length) {
+ private Vector(VectorElementType elementType, int length) {
super(vectorTypeName(elementType));
this.elementType = elementType;
this.length = length;
@@ -132,7 +143,7 @@ public final Object con() {
return List.of(name(), ".zero(", speciesName, ")");
} else if (r <= 8) {
return List.of(
- name(), ".fromArray(", speciesName, ", new ", elementType.name(), "[] {",
+ name(), ".fromArray(", speciesName, ", new ", elementType.carrierTypeName(), "[] {",
elementType.con(),
Stream.generate(() ->
List.of(", ", elementType.con())
diff --git a/test/hotspot/jtreg/compiler/vectorapi/VectorExpressionFuzzer.java b/test/hotspot/jtreg/compiler/vectorapi/VectorExpressionFuzzer.java
index cb5b95109f572..f34fef80209d9 100644
--- a/test/hotspot/jtreg/compiler/vectorapi/VectorExpressionFuzzer.java
+++ b/test/hotspot/jtreg/compiler/vectorapi/VectorExpressionFuzzer.java
@@ -66,6 +66,8 @@
import compiler.lib.template_framework.library.Operations;
import compiler.lib.template_framework.library.TestFrameworkClass;
import compiler.lib.template_framework.library.PrimitiveType;
+import compiler.lib.template_framework.library.Float16VectorType;
+import compiler.lib.template_framework.library.VectorElementType;
import compiler.lib.template_framework.library.VectorType;
/**
@@ -162,23 +164,38 @@ public static String generate(CompileFramework comp) {
// - We check correctness with a reference method that does the same but runs in the interpreter.
// - Input values are delivered via fields or array loads.
// - The final vector is written into an array, and that array is returned.
- var template2Body = Template.make("expression", "arguments", (Expression expression, List