]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
math: Add __issignaling inline
authorWilco Dijkstra <Wilco.Dijkstra@arm.com>
Fri, 23 Jan 2026 13:02:14 +0000 (10:02 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Mon, 2 Feb 2026 17:34:18 +0000 (14:34 -0300)
Add __issignaling inline based on the issignaling_inline implementation.
Improve the __issignalingf inline.  Remove issignaling(f)_inline and its uses.

Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Co-authored-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
include/math.h
sysdeps/aarch64/fpu/finite_pow.h
sysdeps/aarch64/fpu/pow_sve.c
sysdeps/aarch64/fpu/powf_sve.c
sysdeps/ieee754/dbl-64/e_hypot.c
sysdeps/ieee754/dbl-64/e_pow.c
sysdeps/ieee754/dbl-64/math_config.h
sysdeps/ieee754/flt-32/math_config.h

index 2565a4723aed991d5f3eeb60a82d89316aaa6a13..b197333e9523eaa0f15a2911e1ac3b9661293fb1 100644 (file)
@@ -62,32 +62,21 @@ libm_hidden_proto (__expm1f128)
 #include <stdint.h>
 #include <nan-high-order-bit.h>
 
-/* A union which permits us to convert between a float and a 32 bit
-   int.  */
-
-typedef union
-{
-  float value;
-  uint32_t word;
-} ieee_float_shape_type;
-
 /* Get a 32 bit int from a float.  */
 #ifndef GET_FLOAT_WORD
-# define GET_FLOAT_WORD(i,d)                                   \
+# define GET_FLOAT_WORD(__i, __d)                              \
 do {                                                           \
-  ieee_float_shape_type gf_u;                                  \
-  gf_u.value = (d);                                            \
-  (i) = gf_u.word;                                             \
+  union { float f; uint32_t i; } u = { .f = (__d) };           \
+  (__i) = u.i;                                                 \
 } while (0)
 #endif
 
 /* Set a float from a 32 bit int.  */
 #ifndef SET_FLOAT_WORD
-# define SET_FLOAT_WORD(d,i)                                   \
+# define SET_FLOAT_WORD(__d, __i)                              \
 do {                                                           \
-  ieee_float_shape_type sf_u;                                  \
-  sf_u.word = (i);                                             \
-  (d) = sf_u.value;                                            \
+  union { float f; uint32_t i; } u = { .i = (__i) };           \
+  (__d) = u.f;                                                 \
 } while (0)
 #endif
 
@@ -96,20 +85,39 @@ __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)
+{
+  union { double f; uint64_t i; } u = { .f = x };
+  uint64_t xi = u.i;
+
+  /* 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
index 8a6a229cb47cb0560b94270fdf7c3d8c2e105dfc..44aaa1c4ad135a2ef9bbeb9bf05ac8f8d63abeab 100644 (file)
@@ -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;
index d1ceab5a1c158df8bdfe0b7c42d3290c3ccc28c0..19062b5375d8b18cee783db79dd4a50c6cfdb58d 100644 (file)
@@ -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))
index 25cd8cd15ecb48898ebec5e1fc4c8eae8032da23..46b006c845c6dd6635c8fb64c79bde6cae7f1273 100644 (file)
@@ -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)
index b901ee1ef1f36fd5a0096e623fa636779c62af31..c99f40310b8f597863d261fc695ea1de5750ca96 100644 (file)
@@ -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;
     }
index 3ff41922d8043859e9a7b28d57767332ac4b813e..56c393e917b3a1aea5ea442ca75293ad26c7877e 100644 (file)
@@ -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;
index 5158d4cdb75f9bb1c883672ad18fdc9f9e13fe1a..dd0a4494e321c8def55b2f9f88e6d456c440531a 100644 (file)
@@ -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
index 27eaf50191032b80debb11d9cfb4da04e776c7f0..1509c2ef6263b69ddc12842a74e2d9ec23f3c7c4 100644 (file)
@@ -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