[PATCH v2 3/4] math: Optimize dbl-64 remainder implementation

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Wed Oct 1 19:46:13 GMT 2025



On 29/09/25 15:26, Wilco Dijkstra wrote:
> Hi Adhemerval,
> 
> +  uint64_t hx = asuint64 (x);
> +  uint64_t hy = asuint64 (y);
> +  uint64_t sx = hx >> 63;
> +
> +  hx &= UINT64_C (0x7FFFFFFFFFFFFFFF);
> +  hy &= UINT64_C (0x7FFFFFFFFFFFFFFF);
> 
> hx &= ~SIGN_MASK?

Ack.

> 
> +  /* |x| not finite or |y| is NaN or 0 */
> +  if ((hx >= EXPONENT_MASK || (hy - 1) >= EXPONENT_MASK))
> +    return (x * y) / ( x * y);
> 
> We can move this into the else below and just check hx:
> 
> +  /* |y| < DBL_MAX / 2 ? */
> +  y = fabs (y);
> +  if (__glibc_likely (hy < UINT64_C (0x7fe0000000000000)))
> 
> We can add hx < EXPONENT_MASK here to skip the NaN checks above
> (the y == 0.0 case is handled correctly by fmod call).

Yeah, we can simplify the check for the likely case.  But we still need
the fully check on the else case to avoid FE_INVALID for qNaN inputs
(triggered by the FP operations).

> 
> +  /* Make sure x is not -0. This can occur only when x = p  and rounding
> +     direction is towards negative infinity.  */
> +  if (__glibc_unlikely (x == -0.0))
> +    x = 0.0;
> 
> This still seems to work out badly - I did some experiments, this moves the
> zero check to the case that requires it (after the first x - y):
> 
>           x -= y;
>           if (x + x >= y)
>             x -= y;
>           else if (x == 0.0)
>             x = 0.0;
> 
> This gives 5-15% improvements to throughput and latency for the
> denormal and close exponent cases.

We need on both, the lower case is required for the corner case

  remainder_downward (max_value, max_value)
  remainder_downward (max_value, -max_value)
  remainder_downward (-max_value, max_value)
  remainder_downward (-max_value, -max_value)

And it is still an improvement.

> 
> This is probably as good as it gets without merging fmod and remainder
> into a shared implementation.

Thanks, I will send an updated version.


More information about the Libc-alpha mailing list