mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 06:09:01 +00:00
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:
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user