Use of C99 extra long double math functions after r236148
David Schultz
das at freebsd.org
Tue May 28 08:12:33 UTC 2013
On Tue, May 28, 2013, Bruce Evans wrote:
> @ diff -u2 catrigl.c~ catrigl.c
> @ --- catrigl.c~ 2012-09-22 21:14:24.000000000 +0000
> @ +++ catrigl.c 2013-05-26 08:46:10.423187000 +0000
> @ @@ -50,4 +50,6 @@
> @ #define signbit(x) (__builtin_signbitl(x))
> @
> @ +long double atanhl(long double);
> @ +
> @ static const long double
> @ A_crossover = 10,
>
> catrigl.c depends on atanhl(), logl() and log1pl() existing.
Yep, I'm ignoring the complex long double functions until the real
long double functions are done. I'm hoping that won't be too long!
> % Index: tools/regression/lib/msun/test-invctrig.c
> % ===================================================================
> % --- tools/regression/lib/msun/test-invctrig.c (revision 0)
> % +++ tools/regression/lib/msun/test-invctrig.c (working copy)
> % @@ -0,0 +1,467 @@
> % ....
> % +#pragma STDC FENV_ACCESS ON
> % +#pragma STDC CX_LIMITED_RANGE OFF
>
> Heheh, style rules for #pragma. I like the old rule which says that
> it should be indented 6 feet under. It is still almost useless, since
> we don't even have any C99 compilers than implement the fenv pragmas
> yet.
They are mostly just there to document the fact that this code is
expecting FENV_ACCESS to work. Clang, adding insult to injury,
generates a warning about these. I don't think they're going to
implement the missing C99 features soon. Many bugs have been filed
about the issue, but I haven't heard of any progress. When I asked
years ago, I was basically told that the LLVM IR can't support the
feature without substantial modifications.
> % + * XXX gcc implements complex multiplication incorrectly. In
> % + * particular, it implements it as if the CX_LIMITED_RANGE pragma
> % + * were ON. Consequently, we need this function to form numbers
> % + * such as x + INFINITY * I, since gcc evalutes INFINITY * I as
> % + * NaN + INFINITY * I.
> % + */
> % +static inline long double complex
> % +cpackl(long double x, long double y)
> % +{
> % + long double complex z;
> % +
> % + __real__ z = x;
> % + __imag__ z = y;
> % + return (z);
> % +}
>
> Why duplicate this? I guess it is because math_private,h is hard to
> include. I use complicated conditionals (mostly switches on
> $(uname -p) and $(hostname) in shell scripts to locate it when
> compiling from external directories.
I will change to CMPLXL, now that CMPLXL has been committed.
Thanks for reminding me. The ability to use complex numbers in
initializers is nice (ignore whitespace munging due to cut/paste):
static const struct {
complex long double z;
complex long double acos_z;
complex long double asin_z;
complex long double atan_z;
} tests[] = {
{ CMPLXL(0.75L, 0.25L),
CMPLXL(pi / 4, -0.34657359027997265470861606072908828L),
CMPLXL(pi / 4, 0.34657359027997265470861606072908828L),
CMPLXL(0.66290883183401623252961960521423782L,
0.15899719167999917436476103600701878L) },
};
int i;
for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
testall_tol(cacos, tests[i].z, tests[i].acos_z, 2);
testall_odd_tol(casin, tests[i].z, tests[i].asin_z, 2);
testall_odd_tol(catan, tests[i].z, tests[i].atan_z, 2);
}
A few more tests would be good (e.g., large inputs, parts of the
range that are close to an axis or discontinuity), but I ran out
of time.
> The tests seem to be compiled with -O0. That tests a different
> environment than the usual runtime one, and in particular misses seeing
> most precision bugs. I mostly test with -O (-O2 with gcc is slower
> and even harder to debug, while with clang it makes little difference),
> but switch to -O0 to debug. -g -O is now almost unusable because -O
> optimizes away dead variables and -g is broken in many cases (sometimes
> it can't even show live variables).
I want the tests to come as close as possible to testing the
behavior that real programs will see. Unfortunately, any test that
exercises different rounding modes or looks at floating-point
exceptions is pretty much doomed to fail with gcc and clang, so I
gave up. (Sometimes I wonder if there's any point in having a free
library that supports them if you need a commercial compiler to
take advantage.) However, the tests do sometimes uncover compiler
bugs that get fixed. They caught a few bugs in gcc builtins, and
an arithmetic bug in clang's constant-folding code, all of which
were fixed.
More information about the freebsd-numerics
mailing list