[llvm-commits] [llvm] r49458 - /llvm/trunk/lib/Transforms/IPO/SimplifyLibCalls.cpp

Duncan Sands baldrick at free.fr
Thu Apr 10 04:25:34 PDT 2008


> >> +      // x    pow(x, 0.5)  sqrt(x)
> >> +      // ---------------------------------------------
> >> +      // -0.0    +0.0       -0.0
> >> +      // -inf    +inf       NaN
> >
> > looks like pow is broken.  Is pow's behaviour documented
> > anywhere?  On my machine the man page says:
> >
> >       The pow() function can return the following error:
> >
> >       EDOM   The  argument x is negative and y is not an integral  
> > value.  This would result in a complex num‐
> >              ber.
> >
> > Are you sure errno is not being set by pow in these cases?
>
> This is what we have on Darwin:
>
> ...
>         pow(x, y) returns a NaN and raises the "invalid" floating-point  
> exception for finite x < 0 and finite non-integer y.
> ...
>
> The man page says nothing about errno. It claims to follow this  
> standard:
>
>         The pow() function conforms to ISO/IEC 9899:1999(E).

That standard says:

7.12.7.4 The pow functions
Synopsis
       #include <math.h>
       double pow(double x, double y);
       float powf(float x, float y);
       long double powl(long double x, long double y);
Description
The pow functions compute x raised to the power y. A domain error occurs if x is finite
and negative and y is finite and not an integer value. A domain error may occur if x is
zero and y is less than or equal to zero. A range error may occur.
Returns
The pow functions return x^y .

Elsewhere it says:

For all functions, a domain error occurs if an input argument is outside the domain over
which the mathematical function is defined. The description of each function lists any
required domain errors; an implementation may define additional domain errors, provided
that such errors are consistent with the mathematical definition of the function.194) On a
domain error, the function returns an implementation-defined value; if the integer
expression math_errhandling & MATH_ERRNO is nonzero, the integer expression
errno acquires the value EDOM; if the integer expression math_errhandling &
MATH_ERREXCEPT is nonzero, the ‘‘invalid’’ floating-point exception is raised.

This doesn't say anything about when x=-inf, and it is not clear to me if -0.0 is negative.
Anyway, at first glance it looks like the Darwin implementation conforms to the standard,
though the values it returns for x=-inf and x=-0.0 are surprising.

As for sqrt it says:

> 7.12.7.5 The sqrt functions
> Synopsis
>         #include <math.h>
>         double sqrt(double x);
>         float sqrtf(float x);
>         long double sqrtl(long double x);
> Description
> The sqrt functions compute the nonnegative square root of x. A domain error
> occurs if the argument is less than zero.

So it looks like Darwin is wrong not to raise a floating point exception for
sqrt(-inf), since -inf is less than zero.  I don't know if -0.0 is less than
zero.  Finally, returning -0.0 for sqrt(-0.0) is surprising, since
(-0.0)*(-0.0)=+0.0 not -0.0.

Mine says:

CONFORMING TO
       SVr4, 4.3BSD, C89.  The float and long double variants are C99 requirements.

Ciao,

Duncan.




More information about the llvm-commits mailing list