Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 27 May 2013 08:50:10 +0000 (UTC)
From:      David Schultz <das@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r251024 - in head: lib/msun lib/msun/ld128 lib/msun/ld80 lib/msun/src tools/regression/lib/msun
Message-ID:  <201305270850.r4R8oA6g008947@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: das
Date: Mon May 27 08:50:10 2013
New Revision: 251024
URL: http://svnweb.freebsd.org/changeset/base/251024

Log:
  Fix some regressions caused by the switch from gcc to clang. The fixes
  are workarounds for various symptoms of the problem described in clang
  bugs 3929, 8100, 8241, 10409, and 12958.
  
  The regression tests did their job: they failed, someone brought it
  up on the mailing lists, and then the issue got ignored for 6 months.
  Oops. There may still be some regressions for functions we don't have
  test coverage for yet.

Modified:
  head/lib/msun/Makefile
  head/lib/msun/ld128/s_exp2l.c
  head/lib/msun/ld80/s_exp2l.c
  head/lib/msun/src/e_exp.c
  head/lib/msun/src/e_expf.c
  head/lib/msun/src/e_log.c
  head/lib/msun/src/e_log10.c
  head/lib/msun/src/e_log10f.c
  head/lib/msun/src/e_log2.c
  head/lib/msun/src/e_log2f.c
  head/lib/msun/src/e_logf.c
  head/lib/msun/src/s_exp2.c
  head/lib/msun/src/s_exp2f.c
  head/lib/msun/src/s_expm1.c
  head/lib/msun/src/s_expm1f.c
  head/lib/msun/src/s_fma.c
  head/lib/msun/src/s_fmal.c
  head/lib/msun/src/s_log1p.c
  head/lib/msun/src/s_log1pf.c
  head/lib/msun/src/s_nearbyint.c
  head/tools/regression/lib/msun/test-fma.c

Modified: head/lib/msun/Makefile
==============================================================================
--- head/lib/msun/Makefile	Mon May 27 06:32:07 2013	(r251023)
+++ head/lib/msun/Makefile	Mon May 27 08:50:10 2013	(r251024)
@@ -121,12 +121,6 @@ COMMON_SRCS:=  ${COMMON_SRCS:N${i:R}.c}
 .endfor
 .endif
 
-# Some files need certain gcc built-in functions to be disabled, since gcc's
-# model of the functions bogusly assumes -fno-trapping-math.
-XRINT_CFLAGS=	-fno-builtin-rint -fno-builtin-rintf -fno-builtin-rintl
-CFLAGS+=	${XRINT_CFLAGS}
-XRINT_CFLAGS:=	${.IMPSRC:M*/s_nearbyint.c:C/^.+$/${XRINT_CFLAGS}/:C/^$//}
-
 SRCS=	${COMMON_SRCS} ${ARCH_SRCS}
 
 INCS+=	fenv.h math.h

Modified: head/lib/msun/ld128/s_exp2l.c
==============================================================================
--- head/lib/msun/ld128/s_exp2l.c	Mon May 27 06:32:07 2013	(r251023)
+++ head/lib/msun/ld128/s_exp2l.c	Mon May 27 08:50:10 2013	(r251024)
@@ -39,14 +39,11 @@ __FBSDID("$FreeBSD$");
 #define	BIAS	(LDBL_MAX_EXP - 1)
 #define	EXPMASK	(BIAS + LDBL_MAX_EXP)
 
-#if 0 /* XXX Prevent gcc from erroneously constant folding this. */
-static const long double twom10000 = 0x1p-10000L;
-#else
-static volatile long double twom10000 = 0x1p-10000L;
-#endif
+static volatile long double
+    huge      = 0x1p10000L,
+    twom10000 = 0x1p-10000L;
 
 static const long double
-    huge      = 0x1p10000L,
     P1        = 0x1.62e42fefa39ef35793c7673007e6p-1L,
     P2	      = 0x1.ebfbdff82c58ea86f16b06ec9736p-3L,
     P3        = 0x1.c6b08d704a0bf8b33a762bad3459p-5L,

Modified: head/lib/msun/ld80/s_exp2l.c
==============================================================================
--- head/lib/msun/ld80/s_exp2l.c	Mon May 27 06:32:07 2013	(r251023)
+++ head/lib/msun/ld80/s_exp2l.c	Mon May 27 08:50:10 2013	(r251024)
@@ -43,12 +43,9 @@ __FBSDID("$FreeBSD$");
 #define	BIAS	(LDBL_MAX_EXP - 1)
 #define	EXPMASK	(BIAS + LDBL_MAX_EXP)
 
-static const long double huge = 0x1p10000L;
-#if 0 /* XXX Prevent gcc from erroneously constant folding this. */
-static const long double twom10000 = 0x1p-10000L;
-#else
-static volatile long double twom10000 = 0x1p-10000L;
-#endif
+static volatile long double
+    huge = 0x1p10000L,
+    twom10000 = 0x1p-10000L;
 
 static const double
     redux     = 0x1.8p63 / TBLSIZE,

Modified: head/lib/msun/src/e_exp.c
==============================================================================
--- head/lib/msun/src/e_exp.c	Mon May 27 06:32:07 2013	(r251023)
+++ head/lib/msun/src/e_exp.c	Mon May 27 08:50:10 2013	(r251024)
@@ -84,7 +84,6 @@ __FBSDID("$FreeBSD$");
 static const double
 one	= 1.0,
 halF[2]	= {0.5,-0.5,},
-huge	= 1.0e+300,
 o_threshold=  7.09782712893383973096e+02,  /* 0x40862E42, 0xFEFA39EF */
 u_threshold= -7.45133219101941108420e+02,  /* 0xc0874910, 0xD52D3051 */
 ln2HI[2]   ={ 6.93147180369123816490e-01,  /* 0x3fe62e42, 0xfee00000 */
@@ -99,6 +98,7 @@ P4   = -1.65339022054652515390e-06, /* 0
 P5   =  4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */
 
 static volatile double
+huge	= 1.0e+300,
 twom1000= 9.33263618503218878990e-302;     /* 2**-1000=0x01700000,0*/
 
 double

Modified: head/lib/msun/src/e_expf.c
==============================================================================
--- head/lib/msun/src/e_expf.c	Mon May 27 06:32:07 2013	(r251023)
+++ head/lib/msun/src/e_expf.c	Mon May 27 08:50:10 2013	(r251024)
@@ -24,7 +24,6 @@ __FBSDID("$FreeBSD$");
 static const float
 one	= 1.0,
 halF[2]	= {0.5,-0.5,},
-huge	= 1.0e+30,
 o_threshold=  8.8721679688e+01,  /* 0x42b17180 */
 u_threshold= -1.0397208405e+02,  /* 0xc2cff1b5 */
 ln2HI[2]   ={ 6.9314575195e-01,		/* 0x3f317200 */
@@ -39,7 +38,9 @@ invln2 =  1.4426950216e+00, 		/* 0x3fb8a
 P1 =  1.6666625440e-1,		/*  0xaaaa8f.0p-26 */
 P2 = -2.7667332906e-3;		/* -0xb55215.0p-32 */
 
-static volatile float twom100 = 7.8886090522e-31;      /* 2**-100=0x0d800000 */
+static volatile float
+huge	= 1.0e+30,
+twom100 = 7.8886090522e-31;      /* 2**-100=0x0d800000 */
 
 float
 __ieee754_expf(float x)

Modified: head/lib/msun/src/e_log.c
==============================================================================
--- head/lib/msun/src/e_log.c	Mon May 27 06:32:07 2013	(r251023)
+++ head/lib/msun/src/e_log.c	Mon May 27 08:50:10 2013	(r251024)
@@ -81,6 +81,7 @@ Lg6 = 1.531383769920937332e-01,  /* 3FC3
 Lg7 = 1.479819860511658591e-01;  /* 3FC2F112 DF3E5244 */
 
 static const double zero   =  0.0;
+static volatile double vzero = 0.0;
 
 double
 __ieee754_log(double x)
@@ -94,7 +95,7 @@ __ieee754_log(double x)
 	k=0;
 	if (hx < 0x00100000) {			/* x < 2**-1022  */
 	    if (((hx&0x7fffffff)|lx)==0) 
-		return -two54/zero;		/* log(+-0)=-inf */
+		return -two54/vzero;		/* log(+-0)=-inf */
 	    if (hx<0) return (x-x)/zero;	/* log(-#) = NaN */
 	    k -= 54; x *= two54; /* subnormal number, scale up x */
 	    GET_HIGH_WORD(hx,x);

Modified: head/lib/msun/src/e_log10.c
==============================================================================
--- head/lib/msun/src/e_log10.c	Mon May 27 06:32:07 2013	(r251023)
+++ head/lib/msun/src/e_log10.c	Mon May 27 08:50:10 2013	(r251024)
@@ -34,6 +34,7 @@ log10_2hi  =  3.01029995663611771306e-01
 log10_2lo  =  3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */
 
 static const double zero   =  0.0;
+static volatile double vzero = 0.0;
 
 double
 __ieee754_log10(double x)
@@ -47,7 +48,7 @@ __ieee754_log10(double x)
 	k=0;
 	if (hx < 0x00100000) {			/* x < 2**-1022  */
 	    if (((hx&0x7fffffff)|lx)==0)
-		return -two54/zero;		/* log(+-0)=-inf */
+		return -two54/vzero;		/* log(+-0)=-inf */
 	    if (hx<0) return (x-x)/zero;	/* log(-#) = NaN */
 	    k -= 54; x *= two54; /* subnormal number, scale up x */
 	    GET_HIGH_WORD(hx,x);

Modified: head/lib/msun/src/e_log10f.c
==============================================================================
--- head/lib/msun/src/e_log10f.c	Mon May 27 06:32:07 2013	(r251023)
+++ head/lib/msun/src/e_log10f.c	Mon May 27 08:50:10 2013	(r251024)
@@ -28,6 +28,7 @@ log10_2hi  =  3.0102920532e-01, /* 0x3e9
 log10_2lo  =  7.9034151668e-07; /* 0x355427db */
 
 static const float zero   =  0.0;
+static volatile float vzero = 0.0;
 
 float
 __ieee754_log10f(float x)
@@ -40,7 +41,7 @@ __ieee754_log10f(float x)
 	k=0;
 	if (hx < 0x00800000) {			/* x < 2**-126  */
 	    if ((hx&0x7fffffff)==0)
-		return -two25/zero;		/* log(+-0)=-inf */
+		return -two25/vzero;		/* log(+-0)=-inf */
 	    if (hx<0) return (x-x)/zero;	/* log(-#) = NaN */
 	    k -= 25; x *= two25; /* subnormal number, scale up x */
 	    GET_FLOAT_WORD(hx,x);

Modified: head/lib/msun/src/e_log2.c
==============================================================================
--- head/lib/msun/src/e_log2.c	Mon May 27 06:32:07 2013	(r251023)
+++ head/lib/msun/src/e_log2.c	Mon May 27 08:50:10 2013	(r251024)
@@ -34,6 +34,7 @@ ivln2hi    =  1.44269504072144627571e+00
 ivln2lo    =  1.67517131648865118353e-10; /* 0x3de705fc, 0x2eefa200 */
 
 static const double zero   =  0.0;
+static volatile double vzero = 0.0;
 
 double
 __ieee754_log2(double x)
@@ -47,7 +48,7 @@ __ieee754_log2(double x)
 	k=0;
 	if (hx < 0x00100000) {			/* x < 2**-1022  */
 	    if (((hx&0x7fffffff)|lx)==0)
-		return -two54/zero;		/* log(+-0)=-inf */
+		return -two54/vzero;		/* log(+-0)=-inf */
 	    if (hx<0) return (x-x)/zero;	/* log(-#) = NaN */
 	    k -= 54; x *= two54; /* subnormal number, scale up x */
 	    GET_HIGH_WORD(hx,x);

Modified: head/lib/msun/src/e_log2f.c
==============================================================================
--- head/lib/msun/src/e_log2f.c	Mon May 27 06:32:07 2013	(r251023)
+++ head/lib/msun/src/e_log2f.c	Mon May 27 08:50:10 2013	(r251024)
@@ -26,6 +26,7 @@ ivln2hi    =  1.4428710938e+00, /* 0x3fb
 ivln2lo    = -1.7605285393e-04; /* 0xb9389ad4 */
 
 static const float zero   =  0.0;
+static volatile float vzero = 0.0;
 
 float
 __ieee754_log2f(float x)
@@ -38,7 +39,7 @@ __ieee754_log2f(float x)
 	k=0;
 	if (hx < 0x00800000) {			/* x < 2**-126  */
 	    if ((hx&0x7fffffff)==0)
-		return -two25/zero;		/* log(+-0)=-inf */
+		return -two25/vzero;		/* log(+-0)=-inf */
 	    if (hx<0) return (x-x)/zero;	/* log(-#) = NaN */
 	    k -= 25; x *= two25; /* subnormal number, scale up x */
 	    GET_FLOAT_WORD(hx,x);

Modified: head/lib/msun/src/e_logf.c
==============================================================================
--- head/lib/msun/src/e_logf.c	Mon May 27 06:32:07 2013	(r251023)
+++ head/lib/msun/src/e_logf.c	Mon May 27 08:50:10 2013	(r251024)
@@ -30,6 +30,7 @@ Lg3 =      0x91e9ee.0p-25,	/* 0.28498786
 Lg4 =      0xf89e26.0p-26;	/* 0.24279078841 */
 
 static const float zero   =  0.0;
+static volatile float vzero = 0.0;
 
 float
 __ieee754_logf(float x)
@@ -42,7 +43,7 @@ __ieee754_logf(float x)
 	k=0;
 	if (ix < 0x00800000) {			/* x < 2**-126  */
 	    if ((ix&0x7fffffff)==0)
-		return -two25/zero;		/* log(+-0)=-inf */
+		return -two25/vzero;		/* log(+-0)=-inf */
 	    if (ix<0) return (x-x)/zero;	/* log(-#) = NaN */
 	    k -= 25; x *= two25; /* subnormal number, scale up x */
 	    GET_FLOAT_WORD(ix,x);

Modified: head/lib/msun/src/s_exp2.c
==============================================================================
--- head/lib/msun/src/s_exp2.c	Mon May 27 06:32:07 2013	(r251023)
+++ head/lib/msun/src/s_exp2.c	Mon May 27 08:50:10 2013	(r251024)
@@ -36,7 +36,6 @@ __FBSDID("$FreeBSD$");
 #define	TBLSIZE	(1 << TBLBITS)
 
 static const double
-    huge     = 0x1p1000,
     redux    = 0x1.8p52 / TBLSIZE,
     P1	     = 0x1.62e42fefa39efp-1,
     P2	     = 0x1.ebfbdff82c575p-3,
@@ -44,7 +43,9 @@ static const double
     P4	     = 0x1.3b2ab88f70400p-7,
     P5	     = 0x1.5d88003875c74p-10;
 
-static volatile double twom1000 = 0x1p-1000;
+static volatile double
+    huge     = 0x1p1000,
+    twom1000 = 0x1p-1000;
 
 static const double tbl[TBLSIZE * 2] = {
 /*	exp2(z + eps)		eps	*/

Modified: head/lib/msun/src/s_exp2f.c
==============================================================================
--- head/lib/msun/src/s_exp2f.c	Mon May 27 06:32:07 2013	(r251023)
+++ head/lib/msun/src/s_exp2f.c	Mon May 27 08:50:10 2013	(r251024)
@@ -36,14 +36,15 @@ __FBSDID("$FreeBSD$");
 #define	TBLSIZE	(1 << TBLBITS)
 
 static const float
-    huge    = 0x1p100f,
     redux   = 0x1.8p23f / TBLSIZE,
     P1	    = 0x1.62e430p-1f,
     P2	    = 0x1.ebfbe0p-3f,
     P3	    = 0x1.c6b348p-5f,
     P4	    = 0x1.3b2c9cp-7f;
 
-static volatile float twom100 = 0x1p-100f;
+static volatile float
+    huge    = 0x1p100f,
+    twom100 = 0x1p-100f;
 
 static const double exp2ft[TBLSIZE] = {
 	0x1.6a09e667f3bcdp-1,

Modified: head/lib/msun/src/s_expm1.c
==============================================================================
--- head/lib/msun/src/s_expm1.c	Mon May 27 06:32:07 2013	(r251023)
+++ head/lib/msun/src/s_expm1.c	Mon May 27 08:50:10 2013	(r251024)
@@ -115,7 +115,6 @@ __FBSDID("$FreeBSD$");
 
 static const double
 one		= 1.0,
-huge		= 1.0e+300,
 tiny		= 1.0e-300,
 o_threshold	= 7.09782712893383973096e+02,/* 0x40862E42, 0xFEFA39EF */
 ln2_hi		= 6.93147180369123816490e-01,/* 0x3fe62e42, 0xfee00000 */
@@ -128,6 +127,8 @@ Q3  =  -7.93650757867487942473e-05, /* B
 Q4  =   4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */
 Q5  =  -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */
 
+static volatile double huge = 1.0e+300;
+
 double
 expm1(double x)
 {

Modified: head/lib/msun/src/s_expm1f.c
==============================================================================
--- head/lib/msun/src/s_expm1f.c	Mon May 27 06:32:07 2013	(r251023)
+++ head/lib/msun/src/s_expm1f.c	Mon May 27 08:50:10 2013	(r251024)
@@ -23,7 +23,6 @@ __FBSDID("$FreeBSD$");
 
 static const float
 one		= 1.0,
-huge		= 1.0e+30,
 tiny		= 1.0e-30,
 o_threshold	= 8.8721679688e+01,/* 0x42b17180 */
 ln2_hi		= 6.9313812256e-01,/* 0x3f317180 */
@@ -37,6 +36,8 @@ invln2		= 1.4426950216e+00,/* 0x3fb8aa3b
 Q1 = -3.3333212137e-2,		/* -0x888868.0p-28 */
 Q2 =  1.5807170421e-3;		/*  0xcf3010.0p-33 */
 
+static volatile float huge = 1.0e+30;
+
 float
 expm1f(float x)
 {

Modified: head/lib/msun/src/s_fma.c
==============================================================================
--- head/lib/msun/src/s_fma.c	Mon May 27 06:32:07 2013	(r251023)
+++ head/lib/msun/src/s_fma.c	Mon May 27 08:50:10 2013	(r251024)
@@ -238,6 +238,8 @@ fma(double x, double y, double z)
 		zs = copysign(DBL_MIN, zs);
 
 	fesetround(FE_TONEAREST);
+	/* work around clang bug 8100 */
+	volatile double vxs = xs;
 
 	/*
 	 * Basic approach for round-to-nearest:
@@ -247,7 +249,7 @@ fma(double x, double y, double z)
 	 *     adj = xy.lo + r.lo		(inexact; low bit is sticky)
 	 *     result = r.hi + adj		(correctly rounded)
 	 */
-	xy = dd_mul(xs, ys);
+	xy = dd_mul(vxs, ys);
 	r = dd_add(xy.hi, zs);
 
 	spread = ex + ey;
@@ -268,7 +270,9 @@ fma(double x, double y, double z)
 		 * rounding modes.
 		 */
 		fesetround(oround);
-		adj = r.lo + xy.lo;
+		/* work around clang bug 8100 */
+		volatile double vrlo = r.lo;
+		adj = vrlo + xy.lo;
 		return (ldexp(r.hi + adj, spread));
 	}
 

Modified: head/lib/msun/src/s_fmal.c
==============================================================================
--- head/lib/msun/src/s_fmal.c	Mon May 27 06:32:07 2013	(r251023)
+++ head/lib/msun/src/s_fmal.c	Mon May 27 08:50:10 2013	(r251024)
@@ -226,6 +226,8 @@ fmal(long double x, long double y, long 
 		zs = copysignl(LDBL_MIN, zs);
 
 	fesetround(FE_TONEAREST);
+	/* work around clang bug 8100 */
+	volatile long double vxs = xs;
 
 	/*
 	 * Basic approach for round-to-nearest:
@@ -235,7 +237,7 @@ fmal(long double x, long double y, long 
 	 *     adj = xy.lo + r.lo		(inexact; low bit is sticky)
 	 *     result = r.hi + adj		(correctly rounded)
 	 */
-	xy = dd_mul(xs, ys);
+	xy = dd_mul(vxs, ys);
 	r = dd_add(xy.hi, zs);
 
 	spread = ex + ey;
@@ -256,7 +258,9 @@ fmal(long double x, long double y, long 
 		 * rounding modes.
 		 */
 		fesetround(oround);
-		adj = r.lo + xy.lo;
+		/* work around clang bug 8100 */
+		volatile long double vrlo = r.lo;
+		adj = vrlo + xy.lo;
 		return (ldexpl(r.hi + adj, spread));
 	}
 

Modified: head/lib/msun/src/s_log1p.c
==============================================================================
--- head/lib/msun/src/s_log1p.c	Mon May 27 06:32:07 2013	(r251023)
+++ head/lib/msun/src/s_log1p.c	Mon May 27 08:50:10 2013	(r251024)
@@ -96,6 +96,7 @@ Lp6 = 1.531383769920937332e-01,  /* 3FC3
 Lp7 = 1.479819860511658591e-01;  /* 3FC2F112 DF3E5244 */
 
 static const double zero = 0.0;
+static volatile double vzero = 0.0;
 
 double
 log1p(double x)
@@ -109,7 +110,7 @@ log1p(double x)
 	k = 1;
 	if (hx < 0x3FDA827A) {			/* 1+x < sqrt(2)+ */
 	    if(ax>=0x3ff00000) {		/* x <= -1.0 */
-		if(x==-1.0) return -two54/zero; /* log1p(-1)=+inf */
+		if(x==-1.0) return -two54/vzero; /* log1p(-1)=+inf */
 		else return (x-x)/(x-x);	/* log1p(x<-1)=NaN */
 	    }
 	    if(ax<0x3e200000) {			/* |x| < 2**-29 */

Modified: head/lib/msun/src/s_log1pf.c
==============================================================================
--- head/lib/msun/src/s_log1pf.c	Mon May 27 06:32:07 2013	(r251023)
+++ head/lib/msun/src/s_log1pf.c	Mon May 27 08:50:10 2013	(r251024)
@@ -34,6 +34,7 @@ Lp6 = 1.5313838422e-01, /* 3E1CD04F */
 Lp7 = 1.4798198640e-01; /* 3E178897 */
 
 static const float zero = 0.0;
+static volatile float vzero = 0.0;
 
 float
 log1pf(float x)
@@ -47,7 +48,7 @@ log1pf(float x)
 	k = 1;
 	if (hx < 0x3ed413d0) {			/* 1+x < sqrt(2)+  */
 	    if(ax>=0x3f800000) {		/* x <= -1.0 */
-		if(x==(float)-1.0) return -two25/zero; /* log1p(-1)=+inf */
+		if(x==(float)-1.0) return -two25/vzero; /* log1p(-1)=+inf */
 		else return (x-x)/(x-x);	/* log1p(x<-1)=NaN */
 	    }
 	    if(ax<0x38000000) {			/* |x| < 2**-15 */

Modified: head/lib/msun/src/s_nearbyint.c
==============================================================================
--- head/lib/msun/src/s_nearbyint.c	Mon May 27 06:32:07 2013	(r251023)
+++ head/lib/msun/src/s_nearbyint.c	Mon May 27 08:50:10 2013	(r251024)
@@ -36,12 +36,16 @@ __FBSDID("$FreeBSD$");
  * instead of feclearexcept()/feupdateenv() to restore the environment
  * because the only exception defined for rint() is overflow, and
  * rounding can't overflow as long as emax >= p.
+ *
+ * The volatile keyword is needed below because clang incorrectly assumes
+ * that rint won't raise any floating-point exceptions. Declaring ret volatile
+ * is sufficient to trick the compiler into doing the right thing.
  */
 #define	DECL(type, fn, rint)	\
 type				\
 fn(type x)			\
 {				\
-	type ret;		\
+	volatile type ret;	\
 	fenv_t env;		\
 				\
 	fegetenv(&env);		\

Modified: head/tools/regression/lib/msun/test-fma.c
==============================================================================
--- head/tools/regression/lib/msun/test-fma.c	Mon May 27 06:32:07 2013	(r251023)
+++ head/tools/regression/lib/msun/test-fma.c	Mon May 27 08:50:10 2013	(r251024)
@@ -77,6 +77,12 @@ __FBSDID("$FreeBSD$");
 } while (0)
 
 /*
+ * This is needed because clang constant-folds fma in ways that are incorrect
+ * in rounding modes other than FE_TONEAREST.
+ */
+volatile double one = 1.0;
+
+/*
  * Determine whether x and y are equal, with two special rules:
  *	+0.0 != -0.0
  *	 NaN == NaN
@@ -108,9 +114,9 @@ test_zeroes(void)
 	testall(-0.0, 0.0, -0.0, -0.0, ALL_STD_EXCEPT, 0);
 	testall(0.0, -0.0, -0.0, -0.0, ALL_STD_EXCEPT, 0);
 
-	testall(-1.0, 1.0, 1.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0);
-	testall(1.0, -1.0, 1.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0);
-	testall(-1.0, -1.0, -1.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0);
+	testall(-one, one, one, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0);
+	testall(one, -one, one, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0);
+	testall(-one, -one, -one, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0);
 
 	switch (fegetround()) {
 	case FE_TONEAREST:
@@ -190,53 +196,53 @@ test_small_z(void)
 
 	/* x*y positive, z positive */
 	if (fegetround() == FE_UPWARD) {
-		test(fmaf, 1.0, 1.0, 0x1.0p-100, 1.0 + FLT_EPSILON,
+		test(fmaf, one, one, 0x1.0p-100, 1.0 + FLT_EPSILON,
 		     ALL_STD_EXCEPT, FE_INEXACT);
-		test(fma, 1.0, 1.0, 0x1.0p-200, 1.0 + DBL_EPSILON,
+		test(fma, one, one, 0x1.0p-200, 1.0 + DBL_EPSILON,
 		     ALL_STD_EXCEPT, FE_INEXACT);
-		test(fmal, 1.0, 1.0, 0x1.0p-200, 1.0 + LDBL_EPSILON,
+		test(fmal, one, one, 0x1.0p-200, 1.0 + LDBL_EPSILON,
 		     ALL_STD_EXCEPT, FE_INEXACT);
 	} else {
-		testall(0x1.0p100, 1.0, 0x1.0p-100, 0x1.0p100,
+		testall(0x1.0p100, one, 0x1.0p-100, 0x1.0p100,
 			ALL_STD_EXCEPT, FE_INEXACT);
 	}
 
 	/* x*y negative, z negative */
 	if (fegetround() == FE_DOWNWARD) {
-		test(fmaf, -1.0, 1.0, -0x1.0p-100, -(1.0 + FLT_EPSILON),
+		test(fmaf, -one, one, -0x1.0p-100, -(1.0 + FLT_EPSILON),
 		     ALL_STD_EXCEPT, FE_INEXACT);
-		test(fma, -1.0, 1.0, -0x1.0p-200, -(1.0 + DBL_EPSILON),
+		test(fma, -one, one, -0x1.0p-200, -(1.0 + DBL_EPSILON),
 		     ALL_STD_EXCEPT, FE_INEXACT);
-		test(fmal, -1.0, 1.0, -0x1.0p-200, -(1.0 + LDBL_EPSILON),
+		test(fmal, -one, one, -0x1.0p-200, -(1.0 + LDBL_EPSILON),
 		     ALL_STD_EXCEPT, FE_INEXACT);
 	} else {
-		testall(0x1.0p100, -1.0, -0x1.0p-100, -0x1.0p100,
+		testall(0x1.0p100, -one, -0x1.0p-100, -0x1.0p100,
 			ALL_STD_EXCEPT, FE_INEXACT);
 	}
 
 	/* x*y positive, z negative */
 	if (fegetround() == FE_DOWNWARD || fegetround() == FE_TOWARDZERO) {
-		test(fmaf, 1.0, 1.0, -0x1.0p-100, 1.0 - FLT_EPSILON / 2,
+		test(fmaf, one, one, -0x1.0p-100, 1.0 - FLT_EPSILON / 2,
 		     ALL_STD_EXCEPT, FE_INEXACT);
-		test(fma, 1.0, 1.0, -0x1.0p-200, 1.0 - DBL_EPSILON / 2,
+		test(fma, one, one, -0x1.0p-200, 1.0 - DBL_EPSILON / 2,
 		     ALL_STD_EXCEPT, FE_INEXACT);
-		test(fmal, 1.0, 1.0, -0x1.0p-200, 1.0 - LDBL_EPSILON / 2,
+		test(fmal, one, one, -0x1.0p-200, 1.0 - LDBL_EPSILON / 2,
 		     ALL_STD_EXCEPT, FE_INEXACT);
 	} else {
-		testall(0x1.0p100, 1.0, -0x1.0p-100, 0x1.0p100,
+		testall(0x1.0p100, one, -0x1.0p-100, 0x1.0p100,
 			ALL_STD_EXCEPT, FE_INEXACT);
 	}
 
 	/* x*y negative, z positive */
 	if (fegetround() == FE_UPWARD || fegetround() == FE_TOWARDZERO) {
-		test(fmaf, -1.0, 1.0, 0x1.0p-100, -1.0 + FLT_EPSILON / 2,
+		test(fmaf, -one, one, 0x1.0p-100, -1.0 + FLT_EPSILON / 2,
 		     ALL_STD_EXCEPT, FE_INEXACT);
-		test(fma, -1.0, 1.0, 0x1.0p-200, -1.0 + DBL_EPSILON / 2,
+		test(fma, -one, one, 0x1.0p-200, -1.0 + DBL_EPSILON / 2,
 		     ALL_STD_EXCEPT, FE_INEXACT);
-		test(fmal, -1.0, 1.0, 0x1.0p-200, -1.0 + LDBL_EPSILON / 2,
+		test(fmal, -one, one, 0x1.0p-200, -1.0 + LDBL_EPSILON / 2,
 		     ALL_STD_EXCEPT, FE_INEXACT);
 	} else {
-		testall(-0x1.0p100, 1.0, 0x1.0p-100, -0x1.0p100,
+		testall(-0x1.0p100, one, 0x1.0p-100, -0x1.0p100,
 			ALL_STD_EXCEPT, FE_INEXACT);
 	}
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201305270850.r4R8oA6g008947>