https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108922

--- Comment #11 from Uroš Bizjak <ubizjak at gmail dot com> ---
(In reply to Jan Kratochvil from comment #8)

> It is true replacing fmod() with fmodl() makes it 5x faster (but only 5x).
> There is still some infinity check and I haven't found any real
> justification in glibc sources for it:
> 28      if (__builtin_expect (isinf (x) || y == 0.0L, 0)
> 29          && _LIB_VERSION != _IEEE_ && !isnan (y) && !isnan (x))
> 30        /* fmod(+-Inf,y) or fmod(x,0) */
> 31        return __kernel_standard_l (x, y, 227);

Using the following test:

--cut here--
#include <math.h>
#include <stdio.h>

long double
__attribute__((noinline))
test (long double x, long double y)
{
  return fmodl (x, y);
}

int
main ()
{
  long double x = INFINITY, y = 1.0;

  printf ("%Lf\n", test (x, y));
  return 0;
}
--cut here--

execution ends in:

            case 227:
                /* fmod(x,0) */
                exc.type = DOMAIN;
                exc.name = CSTR ("fmod");
                if (_LIB_VERSION == _SVID_)
                    exc.retval = x;
                else
                    exc.retval = zero/zero;
                if (_LIB_VERSION == _POSIX_)
                  __set_errno (EDOM);
                else if (!matherr(&exc)) {
                  if (_LIB_VERSION == _SVID_) {
                    (void) WRITE2("fmod:  DOMAIN error\n", 20);
                  }
                  __set_errno (EDOM);
                }
                break;

So, it doesn't execute fprem, but returns early with NaN.

Reply via email to