[PATCH] math: Add __issignaling inline
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Tue Dec 30 18:11:00 GMT 2025
On 30/12/25 14:34, Andreas K. Huettel wrote:
> Am Mittwoch, 24. Dezember 2025, 17:15:30 Mitteleuropäische Normalzeit schrieb Wilco Dijkstra:
>> Add __issignaling inline based on the issignaling_inline implementation.
>> Improve the __issignalingf inline. Remove issignaling(f)_inline and its uses.
>>
>> Passes regress, OK for commit?
>
> So for the outside world issignaling(f)_inline disappears, and internally it's
> replaced by __issignaling inline?
>
> Have we advertised the ..._inline functions in any way, or was it an accident that
> they were public, which is corrected now?
>
> Anyway, OK from me
Both definitions are internal only, although for the _inline version it uses the
installed math.h _Generic selection through the __MATH_TG macro. The __MATH_TG
will select an __issignaling{suffix} implementation based its type.
For 'float' we already have a __issignalingf implementation in include/math.h, so
any *internal* call to issignaling (float) uses it. This patch replaces the
issignaling_inline (double) with a mechanism similar to the 'float' version.
>
>>
>> ---
>>
>> diff --git a/include/math.h b/include/math.h
>> index 2565a4723aed991d5f3eeb60a82d89316aaa6a13..45f4f9e5463aa422b8e2d4d7bf4897a6a0c9a1e7 100644
>> --- a/include/math.h
>> +++ b/include/math.h
>> @@ -69,6 +69,8 @@ typedef union
>> {
>> float value;
>> uint32_t word;
>> + double dvalue;
>> + uint64_t dword;
>> } ieee_float_shape_type;
>>
>> /* Get a 32 bit int from a float. */
>> @@ -96,20 +98,38 @@ __issignalingf (float x)
>> {
>> uint32_t xi;
>> GET_FLOAT_WORD (xi, x);
>> -#if HIGH_ORDER_BIT_IS_SET_FOR_SNAN
>> +
>> /* We only have to care about the high-order bit of x's significand, because
>> having it set (sNaN) already makes the significand different from that
>> used to designate infinity. */
>> - return (xi & 0x7fc00000) == 0x7fc00000;
>> -#else
>> - /* To keep the following comparison simple, toggle the quiet/signaling bit,
>> - so that it is set for sNaNs. This is inverse to IEEE 754-2008 (as well as
>> - common practice for IEEE 754-1985). */
>> - xi ^= 0x00400000;
>> - /* We have to compare for greater (instead of greater or equal), because x's
>> - significand being all-zero designates infinity not NaN. */
>> - return (xi & 0x7fffffff) > 0x7fc00000;
>> -#endif
>> + if (HIGH_ORDER_BIT_IS_SET_FOR_SNAN)
>> + return (xi & 0x7fc00000) == 0x7fc00000;
>> +
>> + /* IEEE 754-2008 is_quiet flag is zero for signaling NaN. To simplify the
>> + comparison logic, first toggle the flag, so that it is set for a sNaN.
>> + We shift out the sign bit and compare for greater than because xi's
>> + significand being all-zero means infinity, not sNaN. */
>> + return 2 * (xi ^ 0x00400000) > 2 * 0x7fc00000U;
>> +}
>> +
>> +extern inline int
>> +__issignaling (double x)
>> +{
>> + ieee_float_shape_type df = { .dvalue = x };
>> + uint64_t xi = df.dword;
>> + /* We only have to care about the high-order bit of x's significand, because
>> + having it set (sNaN) already makes the significand different from that
>> + used to designate infinity. */
>> + if (HIGH_ORDER_BIT_IS_SET_FOR_SNAN)
>> + return (xi & UINT64_C (0x7ff8000000000000))
>> + == UINT64_C (0x7ff8000000000000);
>> +
>> + /* IEEE 754-2008 is_quiet flag is zero for signaling NaN. To simplify the
>> + comparison logic, first toggle the flag, so that it is set for a sNaN.
>> + We shift out the sign bit and compare for greater than because xi's
>> + significand being all-zero means infinity, not sNaN. */
>> + return 2 * (xi ^ UINT64_C (0x0008000000000000))
>> + > UINT64_C (0xfff0000000000000);
>> }
>>
>> # if __HAVE_DISTINCT_FLOAT128
>> diff --git a/sysdeps/aarch64/fpu/finite_pow.h b/sysdeps/aarch64/fpu/finite_pow.h
>> index 9fd535e77d2b29cabe88970ace0f637c80f62434..ef4b87047c070d3b423dc4be2b71d86dcb518480 100644
>> --- a/sysdeps/aarch64/fpu/finite_pow.h
>> +++ b/sysdeps/aarch64/fpu/finite_pow.h
>> @@ -269,9 +269,9 @@ pow_scalar_special_case (double x, double y)
>> if (__glibc_unlikely (zeroinfnan (iy)))
>> {
>> if (2 * iy == 0)
>> - return issignaling_inline (x) ? x + y : 1.0;
>> + return issignaling (x) ? x + y : 1.0;
>> if (ix == asuint64 (1.0))
>> - return issignaling_inline (y) ? x + y : 1.0;
>> + return issignaling (y) ? x + y : 1.0;
>> if (2 * ix > 2 * asuint64 (INFINITY)
>> || 2 * iy > 2 * asuint64 (INFINITY))
>> return x + y;
>> diff --git a/sysdeps/aarch64/fpu/pow_sve.c b/sysdeps/aarch64/fpu/pow_sve.c
>> index e09a52f11558982d046082e490b8735cb3a94204..23dffed287299314596fa628bc7ebd72ca05596e 100644
>> --- a/sysdeps/aarch64/fpu/pow_sve.c
>> +++ b/sysdeps/aarch64/fpu/pow_sve.c
>> @@ -341,9 +341,9 @@ pow_specialcase (double x, double y)
>> if (__glibc_unlikely (zeroinfnan (iy)))
>> {
>> if (2 * iy == 0)
>> - return issignaling_inline (x) ? x + y : 1.0;
>> + return issignaling (x) ? x + y : 1.0;
>> if (ix == asuint64 (1.0))
>> - return issignaling_inline (y) ? x + y : 1.0;
>> + return issignaling (y) ? x + y : 1.0;
>> if (2 * ix > 2 * asuint64 (INFINITY) || 2 * iy > 2 * asuint64 (INFINITY))
>> return x + y;
>> if (2 * ix == 2 * asuint64 (1.0))
>> diff --git a/sysdeps/aarch64/fpu/powf_sve.c b/sysdeps/aarch64/fpu/powf_sve.c
>> index cbe20449261545c858a6ff6bd72587ecc65a9f84..5bbdb2421fec112cf4f3383d76e6a131140c6b27 100644
>> --- a/sysdeps/aarch64/fpu/powf_sve.c
>> +++ b/sysdeps/aarch64/fpu/powf_sve.c
>> @@ -123,9 +123,9 @@ powf_specialcase (float x, float y)
>> if (__glibc_unlikely (zeroinfnan (iy)))
>> {
>> if (2 * iy == 0)
>> - return issignalingf_inline (x) ? x + y : 1.0f;
>> + return issignaling (x) ? x + y : 1.0f;
>> if (ix == 0x3f800000)
>> - return issignalingf_inline (y) ? x + y : 1.0f;
>> + return issignaling (y) ? x + y : 1.0f;
>> if (2 * ix > 2u * 0x7f800000 || 2 * iy > 2u * 0x7f800000)
>> return x + y;
>> if (2 * ix == 2 * 0x3f800000)
>> diff --git a/sysdeps/ieee754/dbl-64/e_hypot.c b/sysdeps/ieee754/dbl-64/e_hypot.c
>> index 799ccbd08ea6d535e5d953b890fd0e2682bd60af..347a37320f57c5a304d2652ca4d7cf38272cff66 100644
>> --- a/sysdeps/ieee754/dbl-64/e_hypot.c
>> +++ b/sysdeps/ieee754/dbl-64/e_hypot.c
>> @@ -98,7 +98,7 @@ __hypot (double x, double y)
>> if (!isfinite(x) || !isfinite(y))
>> {
>> if ((isinf (x) || isinf (y))
>> - && !issignaling_inline (x) && !issignaling_inline (y))
>> + && !issignaling (x) && !issignaling (y))
>> return INFINITY;
>> return x + y;
>> }
>> diff --git a/sysdeps/ieee754/dbl-64/e_pow.c b/sysdeps/ieee754/dbl-64/e_pow.c
>> index 3252ac36aa64f2acb07584447474d635cdd757cc..c2cca8dc768929eef9dea2a172aaaa8b81422366 100644
>> --- a/sysdeps/ieee754/dbl-64/e_pow.c
>> +++ b/sysdeps/ieee754/dbl-64/e_pow.c
>> @@ -303,9 +303,9 @@ __pow (double x, double y)
>> if (__glibc_unlikely (zeroinfnan (iy)))
>> {
>> if (2 * iy == 0)
>> - return issignaling_inline (x) ? x + y : 1.0;
>> + return issignaling (x) ? x + y : 1.0;
>> if (ix == asuint64 (1.0))
>> - return issignaling_inline (y) ? x + y : 1.0;
>> + return issignaling (y) ? x + y : 1.0;
>> if (2 * ix > 2 * asuint64 (INFINITY)
>> || 2 * iy > 2 * asuint64 (INFINITY))
>> return x + y;
>> diff --git a/sysdeps/ieee754/dbl-64/math_config.h b/sysdeps/ieee754/dbl-64/math_config.h
>> index 6a7b98e1f0a69b3c038dc9041bda20e3e21376f0..b9f891fe2cdffef6de6de3363f345f4079ab46c9 100644
>> --- a/sysdeps/ieee754/dbl-64/math_config.h
>> +++ b/sysdeps/ieee754/dbl-64/math_config.h
>> @@ -125,15 +125,6 @@ asdouble (uint64_t i)
>> return u.f;
>> }
>>
>> -static inline int
>> -issignaling_inline (double x)
>> -{
>> - uint64_t ix = asuint64 (x);
>> - if (HIGH_ORDER_BIT_IS_SET_FOR_SNAN)
>> - return (ix & 0x7ff8000000000000) == 0x7ff8000000000000;
>> - return 2 * (ix ^ 0x0008000000000000) > 2 * 0x7ff8000000000000ULL;
>> -}
>> -
>> #define BIT_WIDTH 64
>> #define MANTISSA_WIDTH 52
>> #define EXPONENT_WIDTH 11
>> diff --git a/sysdeps/ieee754/flt-32/math_config.h b/sysdeps/ieee754/flt-32/math_config.h
>> index fb78ade9e2a91cc1bb8bc860666d08bb353a8917..47aaedfeadefe651d05c281f91026317b3a39256 100644
>> --- a/sysdeps/ieee754/flt-32/math_config.h
>> +++ b/sysdeps/ieee754/flt-32/math_config.h
>> @@ -154,15 +154,6 @@ asdouble (uint64_t i)
>> return u.f;
>> }
>>
>> -static inline int
>> -issignalingf_inline (float x)
>> -{
>> - uint32_t ix = asuint (x);
>> - if (HIGH_ORDER_BIT_IS_SET_FOR_SNAN)
>> - return (ix & 0x7fc00000) == 0x7fc00000;
>> - return 2 * (ix ^ 0x00400000) > 2 * 0x7fc00000UL;
>> -}
>> -
>> #define BIT_WIDTH 32
>> #define MANTISSA_WIDTH 23
>> #define EXPONENT_WIDTH 8
>>
>>
>>
>
>
More information about the Libc-alpha
mailing list