From eb21e8abd19b0d619cb3105b91e580fc13effb6e Mon Sep 17 00:00:00 2001 From: Aisha Tammy Date: Fri, 23 Oct 2020 15:36:23 +0000 Subject: [PATCH 1/8] don't alter toolchain vars if already provided --- Make.inc | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Make.inc b/Make.inc index adeb33d..f9b3397 100644 --- a/Make.inc +++ b/Make.inc @@ -10,41 +10,41 @@ VERSION = 0.7.0 SOMAJOR = 3 SOMINOR = 0 DESTDIR = -prefix = /usr/local -bindir = $(prefix)/bin -libdir = $(prefix)/lib -includedir = $(prefix)/include +prefix ?= /usr/local +bindir ?= $(prefix)/bin +libdir ?= $(prefix)/lib +includedir ?= $(prefix)/include ifeq ($(OS), FreeBSD) -pkgconfigdir = $(prefix)/libdata/pkgconfig +pkgconfigdir ?= $(prefix)/libdata/pkgconfig else -pkgconfigdir = $(libdir)/pkgconfig +pkgconfigdir ?= $(libdir)/pkgconfig endif -USEGCC = 1 -USECLANG = 0 +USEGCC ?= 1 +USECLANG ?= 0 ifneq (,$(findstring $(OS),Darwin FreeBSD OpenBSD)) -USEGCC = 0 -USECLANG = 1 +USEGCC ?= 0 +USECLANG ?= 1 endif -AR = $(TOOLPREFIX)ar +AR ?= $(TOOLPREFIX)ar ifeq ($(ARCH),wasm32) -CC = clang-8 -USEGCC = 0 +CC ?= clang-8 +USEGCC ?= 0 CFLAGS_add += -fno-builtin -fno-strict-aliasing endif ifeq ($(USECLANG),1) -USEGCC = 0 -CC = clang +USEGCC ?= 0 +CC ?= clang CFLAGS_add += -fno-builtin -fno-strict-aliasing endif ifeq ($(USEGCC),1) -CC = $(TOOLPREFIX)gcc +CC ?= $(TOOLPREFIX)gcc CFLAGS_add += -fno-gnu89-inline -fno-builtin endif From be31bff11d59e737566c6de81d645c2d0d207c5e Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Mon, 16 Nov 2020 09:09:18 +0100 Subject: [PATCH 2/8] Revert "Export `fenv` functions on all platforms (#213)" The implementation of `fesetenv` cannot be portable, as the value of `FE_DFL_ENV` differs between platforms. On FreeBSD, it is a actual environment. With glibc however, it's a sentinel -1 handled in the implementation of its floating point functions. With openlibm based on FreeBSD's libm, it assumes `FE_DFL_ENV` to be an actual environment. That assumption breaks using code that was compiled against glibc, e.g., `libcuda`: ``` Thread 1 "julia-debug" received signal SIGSEGV, Segmentation fault. 0x00007ffff7b855d0 in fesetenv () from /home/tim/Julia/julia/build/release/usr/bin/../lib/libopenlibm.so (gdb) bt ``` This reverts commit 5a27b4c0c0a5befc2b7622ff8517743963c1f1d2. Fixes https://github.com/JuliaLang/julia/issues/38427. --- amd64/fenv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/amd64/fenv.c b/amd64/fenv.c index 173d4ce..ddf7dba 100644 --- a/amd64/fenv.c +++ b/amd64/fenv.c @@ -29,7 +29,7 @@ #include "bsd_fpu.h" #include "math_private.h" -#ifndef OPENLIBM_USE_HOST_FENV_H +#ifdef _WIN32 #define __fenv_static OLM_DLLEXPORT #endif #include From 9152b0d1b031fc0a20f7d06596df9ff0adcd7160 Mon Sep 17 00:00:00 2001 From: JC Estibariz Date: Fri, 13 Nov 2020 23:14:33 -0500 Subject: [PATCH 3/8] Fix compilation errors on wasm32 --- Make.inc | 11 +++++------ include/openlibm_math.h | 1 + 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Make.inc b/Make.inc index f9b3397..8e443c8 100644 --- a/Make.inc +++ b/Make.inc @@ -29,17 +29,16 @@ USEGCC ?= 0 USECLANG ?= 1 endif -AR ?= $(TOOLPREFIX)ar - ifeq ($(ARCH),wasm32) -CC ?= clang-8 -USEGCC ?= 0 -CFLAGS_add += -fno-builtin -fno-strict-aliasing +USECLANG = 1 +TOOLPREFIX = llvm- endif +AR ?= $(TOOLPREFIX)ar + ifeq ($(USECLANG),1) USEGCC ?= 0 -CC ?= clang +CC = clang CFLAGS_add += -fno-builtin -fno-strict-aliasing endif diff --git a/include/openlibm_math.h b/include/openlibm_math.h index 272721d..3e510a9 100644 --- a/include/openlibm_math.h +++ b/include/openlibm_math.h @@ -304,6 +304,7 @@ OLM_DLLEXPORT double trunc(double); * BSD math library entry points */ #if __BSD_VISIBLE +OLM_DLLEXPORT int isinff(float) __pure2; OLM_DLLEXPORT int isnanf(float) __pure2; /* From 63aa8757f37f65a09c171be896ba3dab960507a4 Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Mon, 1 Feb 2021 13:48:31 +0100 Subject: [PATCH 4/8] Make fenv methods static on additional platforms. --- aarch64/fenv.c | 1 - powerpc/fenv.c | 1 - 2 files changed, 2 deletions(-) diff --git a/aarch64/fenv.c b/aarch64/fenv.c index c9abf14..8a1ca57 100644 --- a/aarch64/fenv.c +++ b/aarch64/fenv.c @@ -26,7 +26,6 @@ * $FreeBSD: src/lib/msun/arm/fenv.c,v 1.3 2011/10/16 05:37:56 das Exp $ */ -#define __fenv_static #include #ifdef __GNUC_GNU_INLINE__ diff --git a/powerpc/fenv.c b/powerpc/fenv.c index 78e6015..bf7d0cb 100644 --- a/powerpc/fenv.c +++ b/powerpc/fenv.c @@ -26,7 +26,6 @@ * $FreeBSD$ */ -#define __fenv_static #include #ifdef __GNUC_GNU_INLINE__ From 40dac9dd77e8d5429f14ce6f7cc7c44605542be6 Mon Sep 17 00:00:00 2001 From: "Viral B. Shah" Date: Sat, 6 Feb 2021 17:27:15 -0500 Subject: [PATCH 5/8] Restore STRICT_ASSIGN on FreeBSD as suggested in #215 Co-authored-by: @kargl --- src/math_private.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/math_private.h b/src/math_private.h index 17027d6..d26eb4e 100644 --- a/src/math_private.h +++ b/src/math_private.h @@ -203,10 +203,9 @@ do { \ } while (0) -//VBS +#ifndef __FreeBSD__ #define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval)) - -/* VBS +#else #ifdef FLT_EVAL_METHOD // Attempt to get strict C99 semantics for assignment with non-C99 compilers. #if FLT_EVAL_METHOD == 0 || __GNUC__ == 0 @@ -215,7 +214,7 @@ do { \ #define STRICT_ASSIGN(type, lval, rval) do { \ volatile type __lval; \ \ - if (sizeof(type) >= sizeof(double)) \ + if (sizeof(type) >= sizeof(long double)) \ (lval) = (rval); \ else { \ __lval = (rval); \ @@ -224,7 +223,7 @@ do { \ } while (0) #endif #endif -*/ +#endif /* * Common routine to process the arguments to nan(), nanf(), and nanl(). From 98f87135b05fab59223167478bdf52c2e4045a52 Mon Sep 17 00:00:00 2001 From: "Viral B. Shah" Date: Sat, 6 Feb 2021 17:59:39 -0500 Subject: [PATCH 6/8] Fix #211 Patched by importing latest msun version --- src/e_powf.c | 24 +++++++++++------------- src/math_private.h | 18 ++++++++++++++++++ test/test-211.c | 12 ++++++++++++ 3 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 test/test-211.c diff --git a/src/e_powf.c b/src/e_powf.c index 84b5692..fd78847 100644 --- a/src/e_powf.c +++ b/src/e_powf.c @@ -25,6 +25,9 @@ bp[] = {1.0, 1.5,}, dp_h[] = { 0.0, 5.84960938e-01,}, /* 0x3f15c000 */ dp_l[] = { 0.0, 1.56322085e-06,}, /* 0x35d1cfdc */ zero = 0.0, +half = 0.5, +qrtr = 0.25, +thrd = 3.33333343e-01, /* 0x3eaaaaab */ one = 1.0, two = 2.0, two24 = 16777216.0, /* 0x4b800000 */ @@ -74,7 +77,7 @@ __ieee754_powf(float x, float y) /* y!=zero: result is NaN if either arg is NaN */ if(ix > 0x7f800000 || iy > 0x7f800000) - return (x+0.0F)+(y+0.0F); + return nan_mix(x, y); /* determine if y is an odd int when x < 0 * yisint = 0 ... y is not an integer @@ -103,15 +106,10 @@ __ieee754_powf(float x, float y) if(iy==0x3f800000) { /* y is +-1 */ if(hy<0) return one/x; else return x; } - if(hy==0x40000000) return x*x; /* y is 2 */ - if(hy==0x40400000) return x*x*x; /* y is 3 */ - if(hy==0x40800000) { /* y is 4 */ - u = x*x; - return u*u; - } - if(hy==0x3f000000) { /* y is 0.5 */ + if(hy==0x40000000) return x*x; /* y is 2 */ + if(hy==0x3f000000) { /* y is 0.5 */ if(hx>=0) /* x >= +0 */ - return __ieee754_sqrtf(x); + return __ieee754_sqrtf(x); } ax = fabsf(x); @@ -144,7 +142,7 @@ __ieee754_powf(float x, float y) /* now |1-x| is tiny <= 2**-20, suffice to compute log(x) by x-x^2/2+x^3/3-x^4/4 */ t = ax-1; /* t has 20 trailing zeros */ - w = (t*t)*((float)0.5-t*((float)0.333333333333-t*(float)0.25)); + w = (t*t)*(half-t*(thrd-t*qrtr)); u = ivln2_h*t; /* ivln2_h has 16 sig. bits */ v = t*ivln2_l-w*ivln2; t1 = u+v; @@ -183,10 +181,10 @@ __ieee754_powf(float x, float y) r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6))))); r += s_l*(s_h+s); s2 = s_h*s_h; - t_h = (float)3.0+s2+r; + t_h = 3+s2+r; GET_FLOAT_WORD(is,t_h); SET_FLOAT_WORD(t_h,is&0xfffff000); - t_l = r-((t_h-(float)3.0)-s2); + t_l = r-((t_h-3)-s2); /* u+v = s*(1+...) */ u = s_h*t_h; v = s_l*t_h+t_l*s; @@ -198,7 +196,7 @@ __ieee754_powf(float x, float y) z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */ z_l = cp_l*p_h+p_l*cp+dp_l[k]; /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ - t = (float)n; + t = n; t1 = (((z_h+z_l)+dp_h[k])+t); GET_FLOAT_WORD(is,t1); SET_FLOAT_WORD(t1,is&0xfffff000); diff --git a/src/math_private.h b/src/math_private.h index d26eb4e..15a27b2 100644 --- a/src/math_private.h +++ b/src/math_private.h @@ -230,6 +230,24 @@ do { \ */ void __scan_nan(u_int32_t *__words, int __num_words, const char *__s); +/* + * Mix 1 or 2 NaNs. First add 0 to each arg. This normally just turns + * signaling NaNs into quiet NaNs by setting a quiet bit. We do this + * because we want to never return a signaling NaN, and also because we + * don't want the quiet bit to affect the result. Then mix the converted + * args using addition. The result is typically the arg whose mantissa + * bits (considered as in integer) are largest. + * + * Technical complications: the result in bits might depend on the precision + * and/or on compiler optimizations, especially when different register sets + * are used for different precisions. Try to make the result not depend on + * at least the precision by always doing the main mixing step in long double + * precision. Try to reduce dependencies on optimizations by adding the + * the 0's in different precisions (unless everything is in long double + * precision). + */ +#define nan_mix(x, y) (((x) + 0.0L) + ((y) + 0)) + #ifdef __GNUCLIKE_ASM /* Asm versions of some functions. */ diff --git a/test/test-211.c b/test/test-211.c new file mode 100644 index 0000000..8bec4e9 --- /dev/null +++ b/test/test-211.c @@ -0,0 +1,12 @@ +#include +#include +#include + +int +main() +{ + float x = 0xd.65874p-4f; + float y = 4.0f; + float z = powf (x, y); + assert(z==0x1.f74424p-2); +} From aeab19f47efb759ce5f91d5a5f352ab6d44e6b79 Mon Sep 17 00:00:00 2001 From: "Viral B. Shah" Date: Mon, 8 Feb 2021 09:39:30 -0500 Subject: [PATCH 7/8] Fix for #211 Co-authored by: @kargl --- src/e_powf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/e_powf.c b/src/e_powf.c index fd78847..7256ce4 100644 --- a/src/e_powf.c +++ b/src/e_powf.c @@ -137,7 +137,7 @@ __ieee754_powf(float x, float y) /* |y| is huge */ if(iy>0x4d000000) { /* if |y| > 2**27 */ /* over/underflow if x is not close to one */ - if(ix<0x3f7ffff8) return (hy<0)? sn*huge*huge:sn*tiny*tiny; + if(ix<0x3f7ffff7) return (hy<0)? sn*huge*huge:sn*tiny*tiny; if(ix>0x3f800007) return (hy>0)? sn*huge*huge:sn*tiny*tiny; /* now |1-x| is tiny <= 2**-20, suffice to compute log(x) by x-x^2/2+x^3/3-x^4/4 */ From 711654eeabc77df467d42224b6951d312bf6f725 Mon Sep 17 00:00:00 2001 From: "Steven G. Kargl" Date: Wed, 10 Feb 2021 12:44:19 -0800 Subject: [PATCH 8/8] Fix incorrect results in `hypotl` near underflow Fixes #224. --- src/e_hypotl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/e_hypotl.c b/src/e_hypotl.c index 047484d..2632774 100644 --- a/src/e_hypotl.c +++ b/src/e_hypotl.c @@ -82,7 +82,7 @@ hypotl(long double x, long double y) man_t manh, manl; GET_LDBL_MAN(manh,manl,b); if((manh|manl)==0) return a; - t1=0; + t1=1; SET_HIGH_WORD(t1,ESW(MAX_EXP-2)); /* t1=2^(MAX_EXP-2) */ b *= t1; a *= t1;