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
5556import compiler .lib .template_framework .library .PrimitiveType ;
5657import compiler .lib .template_framework .library .TestFrameworkClass ;
5758import 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.
0 commit comments