http://llvm.org/bugs/show_bug.cgi?id=11406 says this has been
fixed, is this just problem with us having older clang in base?

On Fri, Jan 20, 2012 at 06:57:22AM +0000, David Schultz wrote:
> Author: das
> Date: Fri Jan 20 06:57:21 2012
> New Revision: 230368
> URL: http://svn.freebsd.org/changeset/base/230368
> 
> Log:
>   These tests check whether the compiler evaluates floating-point
>   expressions properly.  Some of the tests depend on the compiler
>   implementing C99's FENV_ACCESS pragma, and only commercial compilers
>   do; those tests are currently skipped.  If any of the enabled tests
>   fail, then odds are the libm regression tests will fail also.
>   This should make it easier to diagnose reported problems on platforms
>   I don't have.
>   
>   Currently, gcc passes all the tests that don't depend on FENV_ACCESS
>   on amd64 and sparc64.  Clang fails a few on amd64 (see clang bug
>   11406).  Both gcc and clang fare poorly on i386, which has well-known
>   issues.
> 
> Added:
>   head/tools/regression/usr.bin/cc/
>   head/tools/regression/usr.bin/cc/Makefile   (contents, props changed)
>   head/tools/regression/usr.bin/cc/float.c   (contents, props changed)
>   head/tools/regression/usr.bin/cc/float.t   (contents, props changed)
> 
> Added: head/tools/regression/usr.bin/cc/Makefile
> ==============================================================================
> --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> +++ head/tools/regression/usr.bin/cc/Makefile Fri Jan 20 06:57:21 2012        
> (r230368)
> @@ -0,0 +1,12 @@
> +# $FreeBSD$
> +
> +TESTS=       float
> +CFLAGS+=-lm
> +
> +.PHONY: tests
> +tests: ${TESTS}
> +     for p in ${TESTS}; do ${.OBJDIR}/$$p; done
> +
> +.PHONY: clean
> +clean:
> +     -rm -f ${TESTS}
> 
> Added: head/tools/regression/usr.bin/cc/float.c
> ==============================================================================
> --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> +++ head/tools/regression/usr.bin/cc/float.c  Fri Jan 20 06:57:21 2012        
> (r230368)
> @@ -0,0 +1,271 @@
> +/*-
> + * Copyright (c) 2012 David Schultz <d...@freebsd.org>
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + */
> +
> +/*
> + * Test that floating-point arithmetic works as specified by the C standard.
> + */
> +
> +#include <sys/cdefs.h>
> +__FBSDID("$FreeBSD$");
> +
> +#include <fenv.h>
> +#include <float.h>
> +#include <math.h>
> +#include <stdio.h>
> +
> +#ifdef  __i386__
> +#include <ieeefp.h>
> +#endif
> +
> +#define      ALL_STD_EXCEPT  (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
> +                      FE_OVERFLOW | FE_UNDERFLOW)
> +
> +#define      TWICE(x)                ((x) + (x))
> +#define      test(desc, pass)        test1((desc), (pass), 0)
> +#define      skiptest(desc, pass)    test1((desc), (pass), 1)
> +
> +#pragma STDC FENV_ACCESS ON
> +
> +static const float one_f = 1.0 + FLT_EPSILON / 2;
> +static const double one_d = 1.0 + DBL_EPSILON / 2;
> +static const long double one_ld = 1.0L + LDBL_EPSILON / 2;
> +
> +static int testnum, failures;
> +
> +static void
> +test1(const char *testdesc, int pass, int skip)
> +{
> +
> +     testnum++;
> +     printf("%sok %d - %s%s\n", pass || skip ? "" : "not ", testnum, 
> +         skip ? "(SKIPPED) " : "", testdesc);
> +     if (!pass && !skip)
> +             failures++;
> +}
> +
> +/*
> + * Compare d1 and d2 using special rules: NaN == NaN and +0 != -0.
> + */
> +static int
> +fpequal(long double d1, long double d2)
> +{
> +
> +     if (d1 != d2)
> +             return (isnan(d1) && isnan(d2));
> +     return (copysignl(1.0, d1) == copysignl(1.0, d2));
> +}
> +
> +void
> +run_zero_opt_test(double d1, double d2)
> +{
> +
> +     test("optimizations don't break the sign of 0",
> +          fpequal(d1 - d2, 0.0)
> +          && fpequal(-d1 + 0.0, 0.0)
> +          && fpequal(-d1 - d2, -0.0)
> +          && fpequal(-(d1 - d2), -0.0)
> +          && fpequal(-d1 - (-d2), 0.0));
> +}
> +
> +void
> +run_inf_opt_test(double d)
> +{
> +
> +     test("optimizations don't break infinities",
> +          fpequal(d / d, NAN) && fpequal(0.0 * d, NAN));
> +}
> +
> +static inline double
> +todouble(long double ld)
> +{
> +
> +     return (ld);
> +}
> +
> +static inline float
> +tofloat(double d)
> +{
> +
> +     return (d);
> +}
> +
> +void
> +run_tests(void)
> +{
> +     volatile long double vld;
> +     long double ld;
> +     volatile double vd;
> +     double d;
> +     volatile float vf;
> +     float f;
> +     int x;
> +
> +     test("sign bits", fpequal(-0.0, -0.0) && !fpequal(0.0, -0.0));
> +
> +     vd = NAN;
> +     test("NaN equality", fpequal(NAN, NAN) && NAN != NAN && vd != vd);
> +
> +     feclearexcept(ALL_STD_EXCEPT);
> +     test("NaN comparison returns false", !(vd <= vd));
> +     /*
> +      * XXX disabled; gcc/amd64 botches this IEEE 754 requirement by
> +      * emitting ucomisd instead of comisd.
> +      */
> +     skiptest("FENV_ACCESS: NaN comparison raises invalid exception",
> +         fetestexcept(ALL_STD_EXCEPT) == FE_INVALID);
> +
> +     vd = 0.0;
> +     run_zero_opt_test(vd, vd);
> +
> +     vd = INFINITY;
> +     run_inf_opt_test(vd);
> +
> +     feclearexcept(ALL_STD_EXCEPT);
> +     vd = INFINITY;
> +     x = (int)vd;
> +     /* XXX disabled (works with -O0); gcc doesn't support FENV_ACCESS */
> +     skiptest("FENV_ACCESS: Inf->int conversion raises invalid exception",
> +         fetestexcept(ALL_STD_EXCEPT) == FE_INVALID);
> +
> +     /* Raising an inexact exception here is an IEEE-854 requirement. */
> +     feclearexcept(ALL_STD_EXCEPT);
> +     vd = 0.75;
> +     x = (int)vd;
> +     test("0.75->int conversion rounds toward 0, raises inexact exception",
> +          x == 0 && fetestexcept(ALL_STD_EXCEPT) == FE_INEXACT);
> +
> +     feclearexcept(ALL_STD_EXCEPT);
> +     vd = -42.0;
> +     x = (int)vd;
> +     test("-42.0->int conversion is exact, raises no exception",
> +          x == -42 && fetestexcept(ALL_STD_EXCEPT) == 0);
> +
> +     feclearexcept(ALL_STD_EXCEPT);
> +     x = (int)INFINITY;
> +     /* XXX disabled; gcc doesn't support FENV_ACCESS */
> +     skiptest("FENV_ACCESS: const Inf->int conversion raises invalid",
> +         fetestexcept(ALL_STD_EXCEPT) == FE_INVALID);
> +
> +     feclearexcept(ALL_STD_EXCEPT);
> +     x = (int)0.5;
> +     /* XXX disabled; gcc doesn't support FENV_ACCESS */
> +     skiptest("FENV_ACCESS: const double->int conversion raises inexact",
> +          x == 0 && fetestexcept(ALL_STD_EXCEPT) == FE_INEXACT);
> +
> +     test("compile-time constants don't have too much precision",
> +          one_f == 1.0L && one_d == 1.0L && one_ld == 1.0L);
> +
> +     test("const minimum rounding precision",
> +          1.0F + FLT_EPSILON != 1.0F &&
> +          1.0 + DBL_EPSILON != 1.0 &&
> +          1.0L + LDBL_EPSILON != 1.0L);
> +
> +     /* It isn't the compiler's fault if this fails on FreeBSD/i386. */
> +     vf = FLT_EPSILON;
> +     vd = DBL_EPSILON;
> +     vld = LDBL_EPSILON;
> +     test("runtime minimum rounding precision",
> +          1.0F + vf != 1.0F && 1.0 + vd != 1.0 && 1.0L + vld != 1.0L);
> +
> +     test("explicit float to float conversion discards extra precision",
> +          (float)(1.0F + FLT_EPSILON * 0.5F) == 1.0F &&
> +          (float)(1.0F + vf * 0.5F) == 1.0F);
> +     test("explicit double to float conversion discards extra precision",
> +          (float)(1.0 + FLT_EPSILON * 0.5) == 1.0F &&
> +          (float)(1.0 + vf * 0.5) == 1.0F);
> +     test("explicit ldouble to float conversion discards extra precision",
> +          (float)(1.0L + FLT_EPSILON * 0.5L) == 1.0F &&
> +          (float)(1.0L + vf * 0.5L) == 1.0F);
> +
> +     test("explicit double to double conversion discards extra precision",
> +          (double)(1.0 + DBL_EPSILON * 0.5) == 1.0 &&
> +          (double)(1.0 + vd * 0.5) == 1.0);
> +     test("explicit ldouble to double conversion discards extra precision",
> +          (double)(1.0L + DBL_EPSILON * 0.5L) == 1.0 &&
> +          (double)(1.0L + vd * 0.5L) == 1.0);
> +
> +     /*
> +      * FLT_EVAL_METHOD > 1 implies that float expressions are always
> +      * evaluated in double precision or higher, but some compilers get
> +      * this wrong when registers spill to memory.  The following expression
> +      * forces a spill when there are at most 8 FP registers.
> +      */
> +     test("implicit promption to double or higher precision is consistent",
> +#if FLT_EVAL_METHOD == 1 || FLT_EVAL_METHOD == 2 || defined(__i386__)
> +            TWICE(TWICE(TWICE(TWICE(TWICE(
> +                TWICE(TWICE(TWICE(TWICE(1.0F + vf * 0.5F)))))))))
> +          == (1.0 + FLT_EPSILON * 0.5) * 512.0
> +#else
> +          1
> +#endif
> +         );
> +
> +     f = 1.0 + FLT_EPSILON * 0.5;
> +     d = 1.0L + DBL_EPSILON * 0.5L;
> +     test("const assignment discards extra precision", f == 1.0F && d == 
> 1.0);
> +
> +     f = 1.0 + vf * 0.5;
> +     d = 1.0L + vd * 0.5L;
> +     test("variable assignment discards explicit extra precision",
> +          f == 1.0F && d == 1.0);
> +     f = 1.0F + vf * 0.5F;
> +     d = 1.0 + vd * 0.5;
> +     test("variable assignment discards implicit extra precision",
> +          f == 1.0F && d == 1.0);
> +
> +     test("return discards extra precision",
> +          tofloat(1.0 + vf * 0.5) == 1.0F &&
> +          todouble(1.0L + vd * 0.5L) == 1.0);
> +
> +     fesetround(FE_UPWARD);
> +     /* XXX disabled (works with -frounding-math) */
> +     skiptest("FENV_ACCESS: constant arithmetic respects rounding mode",
> +         1.0F + FLT_MIN == 1.0F + FLT_EPSILON &&
> +         1.0 + DBL_MIN == 1.0 + DBL_EPSILON &&
> +         1.0L + LDBL_MIN == 1.0L + LDBL_EPSILON);
> +     fesetround(FE_TONEAREST);
> +
> +     ld = vld * 0.5;
> +     test("associativity is respected",
> +          1.0L + ld + (LDBL_EPSILON * 0.5) == 1.0L &&
> +          1.0L + (LDBL_EPSILON * 0.5) + ld == 1.0L &&
> +          ld + 1.0 + (LDBL_EPSILON * 0.5) == 1.0L &&
> +          ld + (LDBL_EPSILON * 0.5) + 1.0 == 1.0L + LDBL_EPSILON);
> +}
> +
> +int
> +main(int argc, char *argv[])
> +{
> +
> +     printf("1..26\n");
> +
> +#ifdef  __i386__
> +     fpsetprec(FP_PE);
> +#endif
> +     run_tests();
> +
> +     return (failures);
> +}
> 
> Added: head/tools/regression/usr.bin/cc/float.t
> ==============================================================================
> --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> +++ head/tools/regression/usr.bin/cc/float.t  Fri Jan 20 06:57:21 2012        
> (r230368)
> @@ -0,0 +1,10 @@
> +#!/bin/sh
> +# $FreeBSD$
> +
> +cd `dirname $0`
> +
> +executable=`basename $0 .t`
> +
> +make $executable 2>&1 > /dev/null
> +
> +exec ./$executable
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to