[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