[PATCH] math: Add __issignaling inline

Wilco Dijkstra Wilco.Dijkstra@arm.com
Wed Dec 24 16:15:30 GMT 2025


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?

---

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