[PATCH v6 3/3] math: Remove the SVID error handling from tgammaf

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Wed Nov 5 10:38:25 GMT 2025



On 04/11/25 17:38, Wilco Dijkstra wrote:
> Hi Adhemerval,
> 
> +      if (x == 0.0f)
> +       return __math_oflowf_value (r);
> +      else if (isinf (r))
> +       return __math_oflowf (t >> 31);
>        return r;
> 
> Right so we end up with zero here (which also gives +-Inf). This is equivalent:
> 
> if (x == 0.0f)
>   return __math_divzerof (t >> 31);
> if (isinf (r))
>   return __math_oflowf (t >> 31);
> 
> We could write (instead of __math_oflowf_value):
> 
> if (isinf (r))
>   return __math_erangef (r);
> 
> I don't mind adding this interface, but the separate tests do allow more
> flexibility (eg. x == 0.0f test can be done at the start of the enclosing if).

Right, I am leaning more to using __math_erangef here since it does simplify
the code a bit.

> 
>    float fx = floorf (x);
>    if (__glibc_unlikely (x >= 0x1.18522p+5f))
> -    {
> -      /* Overflow case.  The original CORE-MATH code returns
> -        0x1p127f * 0x1p127f, but apparently some compilers replace this
> -        by +Inf.  */
> -      return math_narrow_eval (x * 0x1p127f);
> -    }
> +    return __math_oflowf (0);
> 
> OK
> 
>    /* compute k only after the overflow check, otherwise the case to integer
>       might overflow */
>    int k = fx;
>    if (__glibc_unlikely (fx == x))
>      { /* x is integer */
> -      if (x == 0.0f)
> -       return 1.0f / x;
> 
> OK, cannot ever happen since it's done above.
> 
>        if (x < 0.0f)
>          return __math_invalidf (0.0f);
> 
> OK
> 
>        double t0 = 1, x0 = 1;
> @@ -121,12 +110,10 @@ __ieee754_gammaf_r (float x, int *signgamp)
>        return t0;
>      }
>    if (__glibc_unlikely (x < -42.0f))
> -    { /* negative non-integer */
> -      /* For x < -42, x non-integer, |gamma(x)| < 2^-151.  */
> -      static const float sgn[2] = { 0x1p-127f, -0x1p-127f };
> -      /* Underflows always happens */
> -      return math_narrow_eval (0x1p-127f * sgn[k & 1]);
> -    }
> +    /* negative non-integer */
> +    /* For x < -42, x non-integer, |gamma(x)| < 2^-151.  */
> +    /* Underflows always happens */
> +    return __math_uflowf (k & 1);
> 
> OK
> 
> 
> @@ -164,13 +151,22 @@ __ieee754_gammaf_r (float x, int *signgamp)
>    f *= w;
>    uint64_t rt = asuint64 (f);
>    float r = f;
> +  if (__glibc_unlikely (r == 0))
> +    return __math_uflowf (rt >> 63);
> 
> OK
> 
>    /* Deal with exceptional cases.  */
>    if (__glibc_unlikely (((rt + 2) & 0xfffffff) < 8))
>      {
> -      for (unsigned j = 0; j < sizeof (tb) / sizeof (tb[0]); j++)
> +      for (unsigned j = 0; j < array_length (tb); j++)
>          if (t == tb[j].u)
>            return tb[j].f + tb[j].df;
>      }
>    return r;
>  }
> 
> OK



More information about the Libc-alpha mailing list