1 /*
2 * Copyright (c) 2022, 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 /**
25 * @test
26 * @bug 8294588
27 * @summary Auto-vectorize Float.floatToFloat16, Float.float16ToFloat APIs
28 * @requires vm.compiler2.enabled
29 * @library /test/lib /
30 * @run driver compiler.vectorization.TestFloatConversionsVector
31 */
32
33 package compiler.vectorization;
34
35 import java.util.Set;
36
37 import compiler.lib.ir_framework.*;
38 import jdk.test.lib.Asserts;
39
40 public class TestFloatConversionsVector {
41 private static final int ARRLEN = 1024;
42 private static final int ITERS = 11000;
43 private static float [] finp;
44 private static short [] sout;
45 private static short [] sinp;
46 private static float [] fout;
47
48 public static void main(String args[]) {
49 TestFramework framework = new TestFramework(TestFloatConversionsVector.class);
50 framework.addFlags("-XX:-TieredCompilation", "-XX:CompileThresholdScaling=0.3");
51 framework.addCrossProductScenarios(Set.of("-XX:-UseCompactObjectHeaders", "-XX:+UseCompactObjectHeaders"),
52 Set.of("-XX:-AlignVector", "-XX:+AlignVector"));
53 framework.start();
54 System.out.println("PASSED");
55 }
56
57 @Test
58 @IR(counts = {IRNode.VECTOR_CAST_F2HF, IRNode.VECTOR_SIZE + "min(max_float, max_short)", "> 0"},
59 applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"},
60 applyIfCPUFeatureOr = {"f16c", "true", "avx512f", "true", "zvfh", "true", "asimd", "true", "sve", "true"})
61 public void test_float_float16(short[] sout, float[] finp) {
62 for (int i = 0; i < finp.length; i++) {
63 sout[i] = Float.floatToFloat16(finp[i]);
64 }
65 }
66
67 @Test
68 public void test_float_float16_strided(short[] sout, float[] finp) {
69 for (int i = 0; i < finp.length/2; i++) {
70 sout[i*2] = Float.floatToFloat16(finp[i*2]);
71 }
72 }
73
74 @Test
75 @IR(counts = {IRNode.VECTOR_CAST_F2HF, IRNode.VECTOR_SIZE_2, "> 0"},
76 applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"},
77 applyIfCPUFeature = {"asimd", "true"})
78 public void test_float_float16_short_vector(short[] sout, float[] finp) {
79 for (int i = 0; i < finp.length; i += 4) {
80 sout[i] = Float.floatToFloat16(finp[i]);
81 sout[i + 1] = Float.floatToFloat16(finp[i + 1]);
82 }
83 }
84
85 @Run(test = {"test_float_float16", "test_float_float16_strided",
86 "test_float_float16_short_vector"}, mode = RunMode.STANDALONE)
87 public void kernel_test_float_float16() {
88 finp = new float[ARRLEN];
89 sout = new short[ARRLEN];
90
91 for (int i = 0; i < ARRLEN; i++) {
92 finp[i] = (float) i * 1.4f;
93 }
94
95 for (int i = 0; i < ITERS; i++) {
96 test_float_float16(sout, finp);
97 }
98
99 // Verifying the result
100 for (int i = 0; i < ARRLEN; i++) {
101 Asserts.assertEquals(Float.floatToFloat16(finp[i]), sout[i]);
102 }
103
104 for (int i = 0; i < ITERS; i++) {
105 test_float_float16_strided(sout, finp);
106 }
107
108 // Verifying the result
109 for (int i = 0; i < ARRLEN/2; i++) {
110 Asserts.assertEquals(Float.floatToFloat16(finp[i*2]), sout[i*2]);
111 }
112
113 for (int i = 0; i < ITERS; i++) {
114 test_float_float16_short_vector(sout, finp);
115 }
116
117 // Verifying the result
118 for (int i = 0; i < ARRLEN; i += 4) {
119 Asserts.assertEquals(Float.floatToFloat16(finp[i]), sout[i]);
120 Asserts.assertEquals(Float.floatToFloat16(finp[i + 1]), sout[i + 1]);
121 }
122 }
123
124 @Test
125 @IR(counts = {IRNode.VECTOR_CAST_HF2F, IRNode.VECTOR_SIZE + "min(max_float, max_short)", "> 0"},
126 applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"},
127 applyIfCPUFeatureOr = {"f16c", "true", "avx512f", "true", "zvfh", "true", "asimd", "true", "sve", "true"})
128 public void test_float16_float(float[] fout, short[] sinp) {
129 for (int i = 0; i < sinp.length; i++) {
130 fout[i] = Float.float16ToFloat(sinp[i]);
131 }
132 }
133
134 @Test
135 public void test_float16_float_strided(float[] fout, short[] sinp) {
136 for (int i = 0; i < sinp.length/2; i++) {
137 fout[i*2] = Float.float16ToFloat(sinp[i*2]);
138 }
139 }
140
141 @Test
142 @IR(counts = {IRNode.VECTOR_CAST_HF2F, IRNode.VECTOR_SIZE_2, "> 0"},
143 applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"},
144 applyIfCPUFeature = {"asimd", "true"})
145 public void test_float16_float_short_vector(float[] fout, short[] sinp) {
146 for (int i = 0; i < sinp.length; i += 4) {
147 fout[i] = Float.float16ToFloat(sinp[i]);
148 fout[i + 1] = Float.float16ToFloat(sinp[i + 1]);
149 }
150 }
151
152 @Run(test = {"test_float16_float", "test_float16_float_strided",
153 "test_float16_float_short_vector"}, mode = RunMode.STANDALONE)
154 public void kernel_test_float16_float() {
155 sinp = new short[ARRLEN];
156 fout = new float[ARRLEN];
157
158 for (int i = 0; i < ARRLEN; i++) {
159 sinp[i] = (short)i;
160 }
161
162 for (int i = 0; i < ITERS; i++) {
163 test_float16_float(fout, sinp);
164 }
165
166 // Verifying the result
167 for (int i = 0; i < ARRLEN; i++) {
168 Asserts.assertEquals(Float.float16ToFloat(sinp[i]), fout[i]);
169 }
170
171 for (int i = 0; i < ITERS; i++) {
172 test_float16_float_strided(fout, sinp);
173 }
174
175 // Verifying the result
176 for (int i = 0; i < ARRLEN/2; i++) {
177 Asserts.assertEquals(Float.float16ToFloat(sinp[i*2]), fout[i*2]);
178 }
179
180 for (int i = 0; i < ITERS; i++) {
181 test_float16_float_short_vector(fout, sinp);
182 }
183
184 // Verifying the result
185 for (int i = 0; i < ARRLEN; i += 4) {
186 Asserts.assertEquals(Float.float16ToFloat(sinp[i]), fout[i]);
187 Asserts.assertEquals(Float.float16ToFloat(sinp[i + 1]), fout[i + 1]);
188 }
189 }
190 }