Correct reference for fma for RTZ devices for half (#2269)

The reference was always being calculated using round to nearest even
for fma when testing half precision.

Fixes https://github.com/KhronosGroup/OpenCL-CTS/issues/2224
This commit is contained in:
Ahmed
2025-02-25 20:54:26 +00:00
committed by GitHub
parent c84b712366
commit 803e665683

View File

@@ -2734,6 +2734,34 @@ static double round_to_nearest_even_double(cl_ulong hi, cl_ulong lo,
return u.d; return u.d;
} }
static double round_toward_zero_double(cl_ulong hi, cl_ulong lo, int exponent)
{
union {
cl_ulong u;
cl_double d;
} u;
// edges
if (exponent > 1023) return CL_DBL_MAX;
if (exponent <= -1074) return 0.0;
// Figure out which bits go where
int shift = 11;
if (exponent < -1022)
{
shift -= 1022 + exponent; // subnormal: shift is not 52
exponent = -1023; // set exponent to 0
}
else
hi &= 0x7fffffffffffffffULL; // normal: leading bit is implicit. Remove
// it.
// Assemble the double (round toward zero)
u.u = (hi >> shift) | ((cl_ulong)(exponent + 1023) << 52);
return u.d;
}
// Shift right. Bits lost on the right will be OR'd together and OR'd with the // Shift right. Bits lost on the right will be OR'd together and OR'd with the
// LSB // LSB
static inline void shift_right_sticky_128(cl_ulong *hi, cl_ulong *lo, int shift) static inline void shift_right_sticky_128(cl_ulong *hi, cl_ulong *lo, int shift)
@@ -2966,7 +2994,14 @@ long double reference_fmal(long double x, long double y, long double z)
} }
// round // round
ua.d = round_to_nearest_even_double(hi, lo, exponent); if (gIsInRTZMode)
{
ua.d = round_toward_zero_double(hi, lo, exponent);
}
else
{
ua.d = round_to_nearest_even_double(hi, lo, exponent);
}
// Set the sign // Set the sign
ua.u |= sign; ua.u |= sign;