aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDavid Schultz <das@FreeBSD.org>2013-05-27 08:50:10 +0000
committerDavid Schultz <das@FreeBSD.org>2013-05-27 08:50:10 +0000
commit7dbbb6dde39391c17de03d7901dad76de99a14ff (patch)
treefe26b077920f74a021643eb895e508cd1a90d404 /lib
parent6e7bc5b60d748c1a2a2247854e1714812a0dac4a (diff)
downloadsrc-7dbbb6dde39391c17de03d7901dad76de99a14ff.tar.gz
src-7dbbb6dde39391c17de03d7901dad76de99a14ff.zip
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.
Notes
Notes: svn path=/head/; revision=251024
Diffstat (limited to 'lib')
-rw-r--r--lib/msun/Makefile6
-rw-r--r--lib/msun/ld128/s_exp2l.c9
-rw-r--r--lib/msun/ld80/s_exp2l.c9
-rw-r--r--lib/msun/src/e_exp.c2
-rw-r--r--lib/msun/src/e_expf.c5
-rw-r--r--lib/msun/src/e_log.c3
-rw-r--r--lib/msun/src/e_log10.c3
-rw-r--r--lib/msun/src/e_log10f.c3
-rw-r--r--lib/msun/src/e_log2.c3
-rw-r--r--lib/msun/src/e_log2f.c3
-rw-r--r--lib/msun/src/e_logf.c3
-rw-r--r--lib/msun/src/s_exp2.c5
-rw-r--r--lib/msun/src/s_exp2f.c5
-rw-r--r--lib/msun/src/s_expm1.c3
-rw-r--r--lib/msun/src/s_expm1f.c3
-rw-r--r--lib/msun/src/s_fma.c8
-rw-r--r--lib/msun/src/s_fmal.c8
-rw-r--r--lib/msun/src/s_log1p.c3
-rw-r--r--lib/msun/src/s_log1pf.c3
-rw-r--r--lib/msun/src/s_nearbyint.c6
20 files changed, 53 insertions, 40 deletions
diff --git a/lib/msun/Makefile b/lib/msun/Makefile
index fdb5e2bb1b60..86881d2e16fe 100644
--- a/lib/msun/Makefile
+++ b/lib/msun/Makefile
@@ -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
diff --git a/lib/msun/ld128/s_exp2l.c b/lib/msun/ld128/s_exp2l.c
index 31178e40624d..5afa37e58222 100644
--- a/lib/msun/ld128/s_exp2l.c
+++ b/lib/msun/ld128/s_exp2l.c
@@ -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,
diff --git a/lib/msun/ld80/s_exp2l.c b/lib/msun/ld80/s_exp2l.c
index 14dfc1d87f21..fb5b50c4e411 100644
--- a/lib/msun/ld80/s_exp2l.c
+++ b/lib/msun/ld80/s_exp2l.c
@@ -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,
diff --git a/lib/msun/src/e_exp.c b/lib/msun/src/e_exp.c
index e432bc83c1be..94c9769da38d 100644
--- a/lib/msun/src/e_exp.c
+++ b/lib/msun/src/e_exp.c
@@ -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, /* 0xBEBBBD41, 0xC5D26BF1 */
P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */
static volatile double
+huge = 1.0e+300,
twom1000= 9.33263618503218878990e-302; /* 2**-1000=0x01700000,0*/
double
diff --git a/lib/msun/src/e_expf.c b/lib/msun/src/e_expf.c
index a4790765bcb5..b1fe2c5371ac 100644
--- a/lib/msun/src/e_expf.c
+++ b/lib/msun/src/e_expf.c
@@ -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, /* 0x3fb8aa3b */
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)
diff --git a/lib/msun/src/e_log.c b/lib/msun/src/e_log.c
index 204fb48e4605..19f1ab9e92a0 100644
--- a/lib/msun/src/e_log.c
+++ b/lib/msun/src/e_log.c
@@ -81,6 +81,7 @@ Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
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);
diff --git a/lib/msun/src/e_log10.c b/lib/msun/src/e_log10.c
index 104d2574c659..a795129a25d3 100644
--- a/lib/msun/src/e_log10.c
+++ b/lib/msun/src/e_log10.c
@@ -34,6 +34,7 @@ log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */
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);
diff --git a/lib/msun/src/e_log10f.c b/lib/msun/src/e_log10f.c
index c8765941c6d0..9856df2e7b6a 100644
--- a/lib/msun/src/e_log10f.c
+++ b/lib/msun/src/e_log10f.c
@@ -28,6 +28,7 @@ log10_2hi = 3.0102920532e-01, /* 0x3e9a2080 */
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);
diff --git a/lib/msun/src/e_log2.c b/lib/msun/src/e_log2.c
index 1fc44a5fedec..010bc2c5fcbd 100644
--- a/lib/msun/src/e_log2.c
+++ b/lib/msun/src/e_log2.c
@@ -34,6 +34,7 @@ ivln2hi = 1.44269504072144627571e+00, /* 0x3ff71547, 0x65200000 */
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);
diff --git a/lib/msun/src/e_log2f.c b/lib/msun/src/e_log2f.c
index 716634664a42..1794484e64ec 100644
--- a/lib/msun/src/e_log2f.c
+++ b/lib/msun/src/e_log2f.c
@@ -26,6 +26,7 @@ ivln2hi = 1.4428710938e+00, /* 0x3fb8b000 */
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);
diff --git a/lib/msun/src/e_logf.c b/lib/msun/src/e_logf.c
index c3be6eda5694..ec3985fcbeda 100644
--- a/lib/msun/src/e_logf.c
+++ b/lib/msun/src/e_logf.c
@@ -30,6 +30,7 @@ Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */
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);
diff --git a/lib/msun/src/s_exp2.c b/lib/msun/src/s_exp2.c
index 485b4e3c3e7f..fde11c27d63e 100644
--- a/lib/msun/src/s_exp2.c
+++ b/lib/msun/src/s_exp2.c
@@ -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 */
diff --git a/lib/msun/src/s_exp2f.c b/lib/msun/src/s_exp2f.c
index 0a97bf64d7a8..9ac7c1f6cac2 100644
--- a/lib/msun/src/s_exp2f.c
+++ b/lib/msun/src/s_exp2f.c
@@ -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,
diff --git a/lib/msun/src/s_expm1.c b/lib/msun/src/s_expm1.c
index 5aa1917b5a4c..5059d32d31f7 100644
--- a/lib/msun/src/s_expm1.c
+++ b/lib/msun/src/s_expm1.c
@@ -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, /* BF14CE19 9EAADBB7 */
Q4 = 4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */
Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */
+static volatile double huge = 1.0e+300;
+
double
expm1(double x)
{
diff --git a/lib/msun/src/s_expm1f.c b/lib/msun/src/s_expm1f.c
index fb374943000e..c0a39340fc04 100644
--- a/lib/msun/src/s_expm1f.c
+++ b/lib/msun/src/s_expm1f.c
@@ -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)
{
diff --git a/lib/msun/src/s_fma.c b/lib/msun/src/s_fma.c
index dfbd13c46815..452bece37974 100644
--- a/lib/msun/src/s_fma.c
+++ b/lib/msun/src/s_fma.c
@@ -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));
}
diff --git a/lib/msun/src/s_fmal.c b/lib/msun/src/s_fmal.c
index c2a691350999..92719010edd1 100644
--- a/lib/msun/src/s_fmal.c
+++ b/lib/msun/src/s_fmal.c
@@ -226,6 +226,8 @@ fmal(long double x, long double y, long double z)
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 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;
@@ -256,7 +258,9 @@ fmal(long double x, long double y, long double z)
* 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));
}
diff --git a/lib/msun/src/s_log1p.c b/lib/msun/src/s_log1p.c
index b062a8ad9290..55d352c6dd30 100644
--- a/lib/msun/src/s_log1p.c
+++ b/lib/msun/src/s_log1p.c
@@ -96,6 +96,7 @@ Lp6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
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 */
diff --git a/lib/msun/src/s_log1pf.c b/lib/msun/src/s_log1pf.c
index 01d3457d306f..df04c6756e8d 100644
--- a/lib/msun/src/s_log1pf.c
+++ b/lib/msun/src/s_log1pf.c
@@ -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 */
diff --git a/lib/msun/src/s_nearbyint.c b/lib/msun/src/s_nearbyint.c
index 12493d292809..063f8d7365f9 100644
--- a/lib/msun/src/s_nearbyint.c
+++ b/lib/msun/src/s_nearbyint.c
@@ -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); \