Avoid some undefined behavior in test_bruteforce. (#2400)

* Ulp_Error*: ilogb(reference) - 1 may overflow if reference is zero.
* binary_i_double Test: DoubleFromUInt32's result is a cl_double and the
attempt is to store it as a cl_double, but p was defined as a pointer to
cl_ulong, resulting in an unintended implicit conversion that is not
valid for out-of-range doubles.
* exp2, tanpi: ensure early exit for NaN.
* shift_right_sticky_128: avoid out-of-range shift if shift value is
exactly 64.
* scalbn: e += n may overflow if n is large, move it after the check for
large n.
This commit is contained in:
Harald van Dijk
2025-07-08 17:59:08 +01:00
committed by GitHub
parent 5997a00b2f
commit 09f43ca916
4 changed files with 15 additions and 17 deletions

View File

@@ -721,9 +721,9 @@ double reference_tanpi(double x)
double z = reference_fabs(x);
// if big and even -- caution: only works if x only has single precision
if (z >= HEX_DBL(+, 1, 0, +, 24))
if (!(z < HEX_DBL(+, 1, 0, +, 24)))
{
if (z == INFINITY) return x - x; // nan
if (!isfinite(z)) return x - x; // nan
return reference_copysign(
0.0, x); // tanpi ( n ) is copysign( 0.0, n) for even integers n.
@@ -1223,6 +1223,8 @@ double reference_relaxed_exp2(double x) { return reference_exp2(x); }
double reference_exp2(double x)
{ // Note: only suitable for verifying single precision. Doesn't have range of a
// full double exp2 implementation.
if (isnan(x)) return x;
if (x == 0.0) return 1.0;
// separate x into fractional and integer parts
@@ -2781,7 +2783,7 @@ static inline void shift_right_sticky_128(cl_ulong *hi, cl_ulong *lo, int shift)
sticky |= (0 != l);
l = 0;
}
else
else if (shift > 0)
{
sticky |= (0 != (l << (64 - shift)));
l >>= shift;
@@ -3088,9 +3090,9 @@ long double reference_tanpil(long double x)
long double z = reference_fabsl(x);
// if big and even -- caution: only works if x only has single precision
if (z >= HEX_LDBL(+, 1, 0, +, 53))
if (!(z < HEX_LDBL(+, 1, 0, +, 53)))
{
if (z == INFINITY) return x - x; // nan
if (!isfinite(z)) return x - x; // nan
return reference_copysignl(
0.0L, x); // tanpi ( n ) is copysign( 0.0, n) for even integers n.
@@ -5027,8 +5029,9 @@ static double reference_scalbn(double x, int n)
u.d -= 1.0;
e = (int)((u.l & 0x7ff0000000000000LL) >> 52) - 1022;
}
if (n >= 2098) return reference_copysign(INFINITY, x);
e += n;
if (e >= 2047 || n >= 2098) return reference_copysign(INFINITY, x);
if (e >= 2047) return reference_copysign(INFINITY, x);
if (e < -51 || n < -2097) return reference_copysign(0.0, x);
if (e <= 0)
{