Skip to content

Commit 89e7751

Browse files
committed
8370922: Template Framework Library: Float16 type and operations
Reviewed-by: galder, thartmann, bmaillard
1 parent a61394b commit 89e7751

File tree

9 files changed

+376
-28
lines changed

9 files changed

+376
-28
lines changed

test/hotspot/jtreg/compiler/igvn/ExpressionFuzzer.java

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@
2323

2424
/*
2525
* @test
26-
* @bug 8359412
26+
* @bug 8359412 8370922
2727
* @key randomness
2828
* @summary Use the template framework library to generate random expressions.
2929
* @modules java.base/jdk.internal.misc
30+
* @modules jdk.incubator.vector
3031
* @library /test/lib /
3132
* @compile ../lib/verify/Verify.java
3233
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:CompileTaskTimeout=10000 compiler.igvn.ExpressionFuzzer
@@ -55,6 +56,7 @@
5556
import compiler.lib.template_framework.library.PrimitiveType;
5657
import compiler.lib.template_framework.library.TestFrameworkClass;
5758
import static compiler.lib.template_framework.library.CodeGenerationDataNameType.PRIMITIVE_TYPES;
59+
import static compiler.lib.template_framework.library.CodeGenerationDataNameType.SCALAR_NUMERIC_TYPES;
5860

5961
// We generate random Expressions from primitive type operators.
6062
//
@@ -84,10 +86,14 @@ public static void main(String[] args) {
8486
comp.addJavaSourceCode("compiler.igvn.templated.ExpressionFuzzerInnerTest", generate(comp));
8587

8688
// Compile the source file.
87-
comp.compile();
89+
comp.compile("--add-modules=jdk.incubator.vector");
8890

8991
// compiler.igvn.templated.InnterTest.main(new String[] {});
90-
comp.invoke("compiler.igvn.templated.ExpressionFuzzerInnerTest", "main", new Object[] {new String[] {}});
92+
comp.invoke("compiler.igvn.templated.ExpressionFuzzerInnerTest", "main", new Object[] {new String[] {
93+
"--add-modules=jdk.incubator.vector",
94+
"--add-opens", "jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED",
95+
"--add-opens", "java.base/java.lang=ALL-UNNAMED"
96+
}});
9197
}
9298

9399
// Generate a Java source file as String
@@ -189,10 +195,10 @@ public static String generate(CompileFramework comp) {
189195
case "byte", "short", "char", "int", "long" ->
190196
List.of("val", Collections.nCopies(20, integralCmpTemplate.asToken(expression.returnType)));
191197
// Float/Double have no range, just return the value:
192-
case "float", "double" -> "val";
198+
case "float", "double", "Float16" -> "val";
193199
// Check if the boolean constant folded:
194200
case "boolean" -> "val, val == true, val == false";
195-
default -> throw new RuntimeException("should only be primitive types");
201+
default -> throw new RuntimeException("type not supported yet: " + expression.returnType.name());
196202
}
197203
, "};\n",
198204
"""
@@ -224,7 +230,7 @@ public static String generate(CompileFramework comp) {
224230
// Booleans do have an int-range, but restricting it would just make it constant, which
225231
// is not very useful: we would like to keep it variable here. We already mix in variable
226232
// arguments and constants in the testTemplate.
227-
case "boolean", "float", "double" -> "return v;\n";
233+
case "boolean", "float", "double", "Float16" -> "return v;\n";
228234
case "byte", "short", "char", "int", "long" -> List.of(
229235
// Sometimes constrain the signed range
230236
// v = min(max(v, CON1), CON2)
@@ -241,7 +247,7 @@ public static String generate(CompileFramework comp) {
241247
: List.of(),
242248
// FUTURE: we could also constrain the unsigned bounds.
243249
"return v;\n");
244-
default -> throw new RuntimeException("should only be primitive types");
250+
default -> throw new RuntimeException("type not supported yet: " + type.name());
245251
},
246252
"""
247253
}
@@ -325,6 +331,7 @@ public static String generate(CompileFramework comp) {
325331

326332
// Generate expressions with the primitive types.
327333
for (PrimitiveType type : PRIMITIVE_TYPES) {
334+
// Prmitive expressions are most important, so let's create many expressions per output type.
328335
for (int i = 0; i < 10; i++) {
329336
// The depth determines roughly how many operations are going to be used in the expression.
330337
int depth = RANDOM.nextInt(1, 20);
@@ -333,6 +340,21 @@ public static String generate(CompileFramework comp) {
333340
}
334341
}
335342

343+
// Generate expressions with any scalar numeric types.
344+
for (CodeGenerationDataNameType type : SCALAR_NUMERIC_TYPES) {
345+
// The extended set of scalar numeric expressions (incl. special types such as Float16) are relevant
346+
// but don't currently warrant the same number amount of testing time, so we only create 2 cases
347+
// per type. Note: this still produces a lot of expressions, given that we have a lot of output
348+
// types, and even if the output type is "float", we can still use other types in the expression,
349+
// such as "float -> Float16 -> float". We can consider adjusting this arbitrary count in the future.
350+
for (int i = 0; i < 2; i++) {
351+
// The depth determines roughly how many operations are going to be used in the expression.
352+
int depth = RANDOM.nextInt(1, 20);
353+
Expression expression = Expression.nestRandomly(type, Operations.SCALAR_NUMERIC_OPERATIONS, depth);
354+
tests.add(testTemplate.asToken(expression));
355+
}
356+
}
357+
336358
// Create the test class, which runs all tests.
337359
return TestFrameworkClass.render(
338360
// package and class name.
@@ -341,7 +363,8 @@ public static String generate(CompileFramework comp) {
341363
Set.of("compiler.lib.verify.*",
342364
"java.util.Random",
343365
"jdk.test.lib.Utils",
344-
"compiler.lib.generators.*"),
366+
"compiler.lib.generators.*",
367+
"jdk.incubator.vector.Float16"),
345368
// classpath, so the Test VM has access to the compiled class files.
346369
comp.getEscapedClassPathOfCompiledClasses(),
347370
// The list of tests.

test/hotspot/jtreg/compiler/lib/template_framework/library/CodeGenerationDataNameType.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,13 @@ public interface CodeGenerationDataNameType extends DataName.Type {
100100
*/
101101
static PrimitiveType booleans() { return PrimitiveType.BOOLEANS; }
102102

103+
/**
104+
* The Float16 type.
105+
*
106+
* @return The Float16 type.
107+
*/
108+
static CodeGenerationDataNameType float16() { return Float16Type.FLOAT16; }
109+
103110
/**
104111
* List of all {@link PrimitiveType}s.
105112
*/
@@ -154,4 +161,19 @@ public interface CodeGenerationDataNameType extends DataName.Type {
154161
floats(),
155162
doubles()
156163
);
164+
165+
/**
166+
* List of all scalar numeric types.
167+
*/
168+
List<CodeGenerationDataNameType> SCALAR_NUMERIC_TYPES = List.of(
169+
bytes(),
170+
chars(),
171+
shorts(),
172+
ints(),
173+
longs(),
174+
floats(),
175+
doubles(),
176+
booleans(),
177+
float16()
178+
);
157179
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
package compiler.lib.template_framework.library;
25+
26+
import compiler.lib.generators.Generators;
27+
import compiler.lib.generators.Generator;
28+
29+
import compiler.lib.template_framework.DataName;
30+
31+
/**
32+
* The {@link Float16Type} models Java's {@link Float16} type.
33+
*/
34+
final class Float16Type implements CodeGenerationDataNameType {
35+
private static final Generator<Short> GEN_FLOAT16 = Generators.G.float16s();
36+
37+
// We only need one static instance of the class.
38+
static final Float16Type FLOAT16 = new Float16Type();
39+
40+
// Private constructor so nobody can create duplicate instances.
41+
private Float16Type() {}
42+
43+
@Override
44+
public boolean isSubtypeOf(DataName.Type other) {
45+
return other instanceof Float16Type;
46+
}
47+
48+
@Override
49+
public String name() {
50+
return "Float16";
51+
}
52+
53+
@Override
54+
public String toString() {
55+
return name();
56+
}
57+
58+
@Override
59+
public Object con() {
60+
return "Float16.shortBitsToFloat16((short)" + GEN_FLOAT16.next() + ")";
61+
}
62+
}

0 commit comments

Comments
 (0)