8295351: java/lang/Float/Binary16Conversion.java fails with "Unexpected result of converting"

Reviewed-by: sviswanathan, thartmann
This commit is contained in:
Smita Kamath 2022-11-28 19:24:25 +00:00 committed by Sandhya Viswanathan
parent a80552e1e1
commit 105d9d75e8
2 changed files with 19 additions and 8 deletions

View File

@ -450,7 +450,9 @@ JRT_END
// Reference implementation at src/java.base/share/classes/java/lang/Float.java:floatToFloat16
JRT_LEAF(jshort, SharedRuntime::f2hf(jfloat x))
jint doppel = SharedRuntime::f2i(x);
union {jfloat f; jint i;} bits;
bits.f = x;
jint doppel = bits.i;
jshort sign_bit = (jshort) ((doppel & 0x80000000) >> 16);
if (g_isnan(x))
return (jshort)(sign_bit | 0x7c00 | (doppel & 0x007fe000) >> 13 | (doppel & 0x00001ff0) >> 4 | (doppel & 0x0000000f));
@ -467,7 +469,7 @@ JRT_LEAF(jshort, SharedRuntime::f2hf(jfloat x))
return sign_bit; // Positive or negative zero
}
jint exp = 0x7f800000 & doppel;
jint exp = ((0x7f800000 & doppel) >> (24 - 1)) - 127;
// For binary16 subnormals, beside forcing exp to -15, retain
// the difference exp_delta = E_min - exp. This is the excess
@ -501,6 +503,7 @@ JRT_END
JRT_LEAF(jfloat, SharedRuntime::hf2f(jshort x))
// Halffloat format has 1 signbit, 5 exponent bits and
// 10 significand bits
union {jfloat f; jint i;} bits;
jint hf_arg = (jint)x;
jint hf_sign_bit = 0x8000 & hf_arg;
jint hf_exp_bits = 0x7c00 & hf_arg;
@ -516,16 +519,25 @@ JRT_LEAF(jfloat, SharedRuntime::hf2f(jshort x))
if (hf_exp == -15) {
// For subnormal values, return 2^-24 * significand bits
return (sign * (pow(2,-24)) * hf_significand_bits);
}else if (hf_exp == 16) {
return (hf_significand_bits == 0) ? sign * float_infinity : (SharedRuntime::i2f((hf_sign_bit << 16) | 0x7f800000 |
(hf_significand_bits << significand_shift)));
} else if (hf_exp == 16) {
if (hf_significand_bits == 0) {
bits.i = 0x7f800000;
return sign * bits.f;
} else {
bits.i = (hf_sign_bit << 16) | 0x7f800000 |
(hf_significand_bits << significand_shift);
return bits.f;
}
}
// Add the bias of float exponent and shift
int float_exp_bits = (hf_exp + 127) << (24 - 1);
jint float_exp_bits = (hf_exp + 127) << (24 - 1);
// Combine sign, exponent and significand bits
return SharedRuntime::i2f((hf_sign_bit << 16) | float_exp_bits | (hf_significand_bits << significand_shift));
bits.i = (hf_sign_bit << 16) | float_exp_bits |
(hf_significand_bits << significand_shift);
return bits.f;
JRT_END
// Exception handling across interpreter/compiler boundaries

View File

@ -30,4 +30,3 @@
java/lang/invoke/MethodHandles/CatchExceptionTest.java 8146623 generic-all
java/lang/ref/ReferenceEnqueue.java 8284236 generic-all
java/lang/Float/Binary16Conversion.java 8295351 generic-x64