b363472265
Reviewed-by: fyang
178 lines
7.5 KiB
Java
178 lines
7.5 KiB
Java
/*
|
|
* Copyright (c) 2023, 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.
|
|
*/
|
|
|
|
/*
|
|
* @test
|
|
* @bug 8302976
|
|
* @summary Verify conversion cons between float and the binary16 format
|
|
* @requires (vm.cpu.features ~= ".*avx512vl.*" | vm.cpu.features ~= ".*f16c.*") | os.arch=="aarch64"
|
|
* | (os.arch == "riscv64" & vm.cpu.features ~= ".*zfh,.*")
|
|
* @requires vm.compiler1.enabled & vm.compiler2.enabled
|
|
* @requires vm.compMode != "Xcomp"
|
|
* @comment default run:
|
|
* @run main TestConstFloat16ToFloat
|
|
* @comment C1 JIT compilation only:
|
|
* @run main/othervm -Xcomp -XX:CompileCommand=compileonly,TestConstFloat16ToFloat::test* -XX:TieredStopAtLevel=1 TestConstFloat16ToFloat
|
|
* @comment C2 JIT compilation only:
|
|
* @run main/othervm -Xcomp -XX:CompileCommand=compileonly,TestConstFloat16ToFloat::test* -XX:-TieredCompilation TestConstFloat16ToFloat
|
|
*/
|
|
|
|
public class TestConstFloat16ToFloat {
|
|
|
|
public static class Binary16 {
|
|
public static final short POSITIVE_INFINITY = (short)0x7c00;
|
|
public static final short MAX_VALUE = 0x7bff;
|
|
public static final short ONE = 0x3c00;
|
|
public static final short MIN_NORMAL = 0x0400;
|
|
public static final short MAX_SUBNORMAL = 0x03ff;
|
|
public static final short MIN_VALUE = 0x0001;
|
|
public static final short POSITIVE_ZERO = 0x0000;
|
|
}
|
|
|
|
static final short[] sCon = {
|
|
Short.MIN_VALUE,
|
|
Short.MIN_VALUE + 1,
|
|
-1,
|
|
0,
|
|
+1,
|
|
Short.MAX_VALUE - 1,
|
|
Short.MAX_VALUE,
|
|
Binary16.MIN_VALUE,
|
|
Binary16.MIN_NORMAL,
|
|
Binary16.POSITIVE_ZERO,
|
|
Binary16.ONE,
|
|
Binary16.MAX_VALUE,
|
|
Binary16.MAX_SUBNORMAL,
|
|
Binary16.POSITIVE_INFINITY
|
|
};
|
|
|
|
public final static class BinaryF16 {
|
|
public static final float POSITIVE_INFINITY = Float.POSITIVE_INFINITY;
|
|
public static final float MAX_VALUE = 65504.0f;
|
|
public static final float ONE = 1.0f;
|
|
public static final float MIN_NORMAL = 0x1.0p-14f;
|
|
public static final float MAX_SUBNORMAL = 0x1.ff8p-15f;
|
|
public static final float MIN_VALUE = 0x1.0p-24f;
|
|
public static final float POSITIVE_ZERO = +0x0f;
|
|
}
|
|
|
|
static float[] fCon = {
|
|
0.0f - BinaryF16.POSITIVE_INFINITY,
|
|
0.0f - BinaryF16.MAX_VALUE,
|
|
0.0f - BinaryF16.MAX_SUBNORMAL,
|
|
0.0f - BinaryF16.MIN_VALUE,
|
|
0.0f - BinaryF16.MIN_NORMAL,
|
|
-1.0f,
|
|
-0.0f,
|
|
BinaryF16.MIN_VALUE,
|
|
BinaryF16.MIN_NORMAL,
|
|
BinaryF16.POSITIVE_ZERO,
|
|
BinaryF16.ONE,
|
|
BinaryF16.MAX_VALUE,
|
|
BinaryF16.MAX_SUBNORMAL,
|
|
BinaryF16.POSITIVE_INFINITY
|
|
};
|
|
|
|
// Testing some constant values (optimized by C2).
|
|
public static void testFloat16Const(float[] fRes) {
|
|
fRes[ 0] = Float.float16ToFloat(Short.MIN_VALUE);
|
|
fRes[ 1] = Float.float16ToFloat((short)(Short.MIN_VALUE + 1));
|
|
fRes[ 2] = Float.float16ToFloat((short)-1);
|
|
fRes[ 3] = Float.float16ToFloat((short)0);
|
|
fRes[ 4] = Float.float16ToFloat((short)+1);
|
|
fRes[ 5] = Float.float16ToFloat((short)(Short.MAX_VALUE - 1));
|
|
fRes[ 6] = Float.float16ToFloat(Short.MAX_VALUE);
|
|
fRes[ 7] = Float.float16ToFloat(Binary16.MIN_VALUE);
|
|
fRes[ 8] = Float.float16ToFloat(Binary16.MIN_NORMAL);
|
|
fRes[ 9] = Float.float16ToFloat(Binary16.POSITIVE_ZERO);
|
|
fRes[10] = Float.float16ToFloat(Binary16.ONE);
|
|
fRes[11] = Float.float16ToFloat(Binary16.MAX_VALUE);
|
|
fRes[12] = Float.float16ToFloat(Binary16.MAX_SUBNORMAL);
|
|
fRes[13] = Float.float16ToFloat(Binary16.POSITIVE_INFINITY);
|
|
}
|
|
|
|
public static void testFloatConst(short[] sRes) {
|
|
sRes[ 0] = Float.floatToFloat16(0.0f - BinaryF16.POSITIVE_INFINITY);
|
|
sRes[ 1] = Float.floatToFloat16(0.0f - BinaryF16.MAX_VALUE);
|
|
sRes[ 2] = Float.floatToFloat16(0.0f - BinaryF16.MAX_SUBNORMAL);
|
|
sRes[ 3] = Float.floatToFloat16(0.0f - BinaryF16.MIN_VALUE);
|
|
sRes[ 4] = Float.floatToFloat16(0.0f - BinaryF16.MIN_NORMAL);
|
|
sRes[ 5] = Float.floatToFloat16(-1.0f);
|
|
sRes[ 6] = Float.floatToFloat16(-0.0f);
|
|
sRes[ 7] = Float.floatToFloat16(BinaryF16.MIN_VALUE);
|
|
sRes[ 8] = Float.floatToFloat16(BinaryF16.MIN_NORMAL);
|
|
sRes[ 9] = Float.floatToFloat16(BinaryF16.POSITIVE_ZERO);
|
|
sRes[10] = Float.floatToFloat16(BinaryF16.ONE);
|
|
sRes[11] = Float.floatToFloat16(BinaryF16.MAX_VALUE);
|
|
sRes[12] = Float.floatToFloat16(BinaryF16.MAX_SUBNORMAL);
|
|
sRes[13] = Float.floatToFloat16(BinaryF16.POSITIVE_INFINITY);
|
|
}
|
|
|
|
public static int run() {
|
|
int errors = 0;
|
|
short s = Float.floatToFloat16(0.0f); // Load Float class
|
|
// Testing constant float16 values.
|
|
float[] fRes = new float[sCon.length];
|
|
testFloat16Const(fRes);
|
|
for (int i = 0; i < sCon.length; i++) {
|
|
float fVal = Float.float16ToFloat(sCon[i]);
|
|
if (Float.floatToRawIntBits(fRes[i]) != Float.floatToRawIntBits(fVal)) {
|
|
errors++;
|
|
String cVal_hex = Integer.toHexString(sCon[i] & 0xffff);
|
|
String fRes_hex = Integer.toHexString(Float.floatToRawIntBits(fRes[i]));
|
|
String fVal_hex = Integer.toHexString(Float.floatToRawIntBits(fVal));
|
|
System.out.println("Inconsistent result for Float.float16ToFloat(" + cVal_hex + "): " +
|
|
fRes[i] + "/" + fRes_hex + " != " + fVal + "/" + fVal_hex);
|
|
}
|
|
}
|
|
|
|
// Testing constant float values.
|
|
short[] sRes = new short[fCon.length];
|
|
testFloatConst(sRes);
|
|
for (int i = 0; i < fCon.length; i++) {
|
|
short sVal = Float.floatToFloat16(fCon[i]);
|
|
if (sRes[i] != sVal) {
|
|
errors++;
|
|
String cVal_hex = Integer.toHexString(Float.floatToRawIntBits(fCon[i]));
|
|
String sRes_hex = Integer.toHexString(sRes[i] & 0xffff);
|
|
String sVal_hex = Integer.toHexString(sVal & 0xffff);
|
|
System.out.println("Inconsistent result for Float.floatToFloat16(" + fCon[i] + "/" + cVal_hex + "): " +
|
|
sRes_hex + "(" + sRes + ")" + " != " + sVal_hex + "(" + sVal + ")");
|
|
}
|
|
}
|
|
return errors;
|
|
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
int errors = 0;
|
|
// Run twice to trigger compilation
|
|
for (int i = 0; i < 2; i++) {
|
|
errors += run();
|
|
}
|
|
if (errors > 0) {
|
|
throw new RuntimeException(errors + " errors");
|
|
}
|
|
}
|
|
}
|