From owner-svn-src-head@FreeBSD.ORG Fri Jan 20 08:04:14 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 65630106566C; Fri, 20 Jan 2012 08:04:14 +0000 (UTC) (envelope-from rdivacky@vlakno.cz) Received: from vlakno.cz (vlakno.cz [46.28.110.116]) by mx1.freebsd.org (Postfix) with ESMTP id 917B68FC19; Fri, 20 Jan 2012 08:04:13 +0000 (UTC) Received: by vlakno.cz (Postfix, from userid 1002) id C74FA7F387D; Fri, 20 Jan 2012 08:55:51 +0100 (CET) Date: Fri, 20 Jan 2012 08:55:51 +0100 From: Roman Divacky To: David Schultz Message-ID: <20120120075551.GA28975@freebsd.org> References: <201201200657.q0K6vMhf028463@svn.freebsd.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <201201200657.q0K6vMhf028463@svn.freebsd.org> User-Agent: Mutt/1.4.2.3i Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r230368 - head/tools/regression/usr.bin/cc X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Jan 2012 08:04:14 -0000 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 > + * 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 > +__FBSDID("$FreeBSD$"); > + > +#include > +#include > +#include > +#include > + > +#ifdef __i386__ > +#include > +#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