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