summaryrefslogtreecommitdiffstats
path: root/lib/msun
diff options
context:
space:
mode:
authordas <das@FreeBSD.org>2013-05-27 08:50:10 +0000
committerdas <das@FreeBSD.org>2013-05-27 08:50:10 +0000
commite7b0a63c190c7ecb475b09f41387a75952540f49 (patch)
treefe26b077920f74a021643eb895e508cd1a90d404 /lib/msun
parente97a0dc9656bc3f5214866731094513064e59725 (diff)
downloadFreeBSD-src-e7b0a63c190c7ecb475b09f41387a75952540f49.zip
FreeBSD-src-e7b0a63c190c7ecb475b09f41387a75952540f49.tar.gz
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.
Diffstat (limited to 'lib/msun')
-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 fdb5e2b..86881d2 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 31178e4..5afa37e 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 14dfc1d..fb5b50c 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 e432bc8..94c9769 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 a479076..b1fe2c5 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 204fb48..19f1ab9 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 104d257..a795129 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 c876594..9856df2 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 1fc44a5..010bc2c 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 7166346..1794484 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 c3be6ed..ec3985f 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 485b4e3..fde11c2 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 0a97bf6..9ac7c1f 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 5aa1917..5059d32 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 fb37494..c0a3934 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 dfbd13c..452bece 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 c2a6913..9271901 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 b062a8a..55d352c 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 01d3457..df04c67 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 12493d29..063f8d7 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); \
OpenPOWER on IntegriCloud