* [PATCH 0/3] libm: Clean up gamma functions
@ 2020-08-26 17:03 Keith Packard
2020-08-26 17:03 ` [PATCH 1/3] libm: Fix sign value returned from __ieee754_lgamma*_r(-0) Keith Packard
` (3 more replies)
0 siblings, 4 replies; 34+ messages in thread
From: Keith Packard @ 2020-08-26 17:03 UTC (permalink / raw)
To: newlib
This series cleans up some API oddities and inaccuracies in
errno/exception reporting from the various gamma related functions.
With this series applied, newlib now matches the POSIX spec (and glibc)
for tgamma/lgamma functions. I've left the 'gamma' functions BSD
compatible (tgamma instead of lgamma) to avoid changing the API.
[PATCH 1/3] libm: Fix sign value returned from __ieee754_lgamma*_r(-0)
Following the C spec, gamma(-0) should be -INFINITY rather than
+INFINITY, so the *signgamp value in lgamma should be -1
rather than +1 for this case.
[PATCH 2/3] libm: Remove __ieee754_gamma_r variants
Back in 2002, a patch changed the various gamma functions so
that the returned abs(gamma) instead of the ln of gamma. This
left the _r variants in place, with their extra parameter to
return the sign of the resulting value. This doesn't make any
sense to me and looks like it was just a mistake. I've changed
the __ieee754_gamma functions to apply the sign value locally
and eliminated the gamma_r versions as those are no longer useful.
[PATCH 3/3] libm: Adjust errno/exception values for gamma/lgamma
There's a pretty detailed discussion in the commit message
here, the short version is that tgamma and lgamma are
specified with different errno/exception behaviour for
one class of inputs (negative integers).
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 1/3] libm: Fix sign value returned from __ieee754_lgamma*_r(-0)
2020-08-26 17:03 [PATCH 0/3] libm: Clean up gamma functions Keith Packard
@ 2020-08-26 17:03 ` Keith Packard
2020-08-26 17:03 ` [PATCH 2/3] libm: Remove __ieee754_gamma_r variants Keith Packard
` (2 subsequent siblings)
3 siblings, 0 replies; 34+ messages in thread
From: Keith Packard @ 2020-08-26 17:03 UTC (permalink / raw)
To: newlib
The sign of the INFINITY returned from these cases needs to match the
sign of the zero.
Signed-off-by: Keith Packard <keithp@keithp.com>
---
newlib/libm/math/er_lgamma.c | 6 +++++-
newlib/libm/math/erf_lgamma.c | 6 +++++-
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/newlib/libm/math/er_lgamma.c b/newlib/libm/math/er_lgamma.c
index 386a8a73b..36408382f 100644
--- a/newlib/libm/math/er_lgamma.c
+++ b/newlib/libm/math/er_lgamma.c
@@ -225,7 +225,11 @@ static double zero= 0.00000000000000000000e+00;
*signgamp = 1;
ix = hx&0x7fffffff;
if(ix>=0x7ff00000) return x*x;
- if((ix|lx)==0) return one/zero;
+ if((ix|lx)==0) {
+ if(hx<0)
+ *signgamp = -1;
+ return one/zero;
+ }
if(ix<0x3b900000) { /* |x|<2**-70, return -log(|x|) */
if(hx<0) {
*signgamp = -1;
diff --git a/newlib/libm/math/erf_lgamma.c b/newlib/libm/math/erf_lgamma.c
index 3c6ba02af..a45423949 100644
--- a/newlib/libm/math/erf_lgamma.c
+++ b/newlib/libm/math/erf_lgamma.c
@@ -160,7 +160,11 @@ static float zero= 0.0000000000e+00;
*signgamp = 1;
ix = hx&0x7fffffff;
if(ix>=0x7f800000) return x*x;
- if(ix==0) return one/zero;
+ if(ix==0) {
+ if(hx<0)
+ *signgamp = -1;
+ return one/zero;
+ }
if(ix<0x1c800000) { /* |x|<2**-70, return -log(|x|) */
if(hx<0) {
*signgamp = -1;
--
2.28.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
2020-08-26 17:03 [PATCH 0/3] libm: Clean up gamma functions Keith Packard
2020-08-26 17:03 ` [PATCH 1/3] libm: Fix sign value returned from __ieee754_lgamma*_r(-0) Keith Packard
@ 2020-08-26 17:03 ` Keith Packard
2020-08-26 18:20 ` Corinna Vinschen
2020-08-26 17:03 ` [PATCH 3/3] libm: Adjust errno/exception values for gamma/lgamma Keith Packard
[not found] ` <SN5P110MB0383186ECD9B028A4B0E2ECC9A550@SN5P110MB0383.NAMP110.PROD.OUTLOOK.COM>
3 siblings, 1 reply; 34+ messages in thread
From: Keith Packard @ 2020-08-26 17:03 UTC (permalink / raw)
To: newlib
Gamma should consume the sign reported by lgamma internally instead of
providing it back to the application. This removes the need to have _r
variants as there is no longer any re-entrancy issues with the API.
Signed-off-by: Keith Packard <keithp@keithp.com>
---
newlib/libc/include/math.h | 2 -
newlib/libc/sys/linux/cmath/math_private.h | 2 -
newlib/libm/common/fdlibm.h | 4 +-
newlib/libm/math/Makefile.am | 4 +-
newlib/libm/math/Makefile.in | 24 +++--------
newlib/libm/math/er_gamma.c | 12 ++++--
newlib/libm/math/erf_gamma.c | 12 ++++--
newlib/libm/math/w_gamma.c | 15 +------
newlib/libm/math/w_tgamma.c | 4 +-
newlib/libm/math/wf_gamma.c | 15 +------
newlib/libm/math/wf_tgamma.c | 4 +-
newlib/libm/math/wr_gamma.c | 49 ----------------------
newlib/libm/math/wrf_gamma.c | 48 ---------------------
13 files changed, 32 insertions(+), 163 deletions(-)
delete mode 100644 newlib/libm/math/wr_gamma.c
delete mode 100644 newlib/libm/math/wrf_gamma.c
diff --git a/newlib/libc/include/math.h b/newlib/libc/include/math.h
index 3399d3649..28d4df10f 100644
--- a/newlib/libc/include/math.h
+++ b/newlib/libc/include/math.h
@@ -515,9 +515,7 @@ extern float dremf (float, float);
#ifdef __CYGWIN__
extern float dreml (long double, long double);
#endif /* __CYGWIN__ */
-extern double gamma_r (double, int *);
extern double lgamma_r (double, int *);
-extern float gammaf_r (float, int *);
extern float lgammaf_r (float, int *);
#endif
diff --git a/newlib/libc/sys/linux/cmath/math_private.h b/newlib/libc/sys/linux/cmath/math_private.h
index 3e32b29ba..f5792f7fa 100644
--- a/newlib/libc/sys/linux/cmath/math_private.h
+++ b/newlib/libc/sys/linux/cmath/math_private.h
@@ -178,7 +178,6 @@ extern double __ieee754_cosh (double);
extern double __ieee754_fmod (double,double);
extern double __ieee754_pow (double,double);
extern double __ieee754_lgamma_r (double,int *);
-extern double __ieee754_gamma_r (double,int *);
extern double __ieee754_lgamma (double);
extern double __ieee754_gamma (double);
extern double __ieee754_log10 (double);
@@ -241,7 +240,6 @@ extern float __ieee754_coshf (float);
extern float __ieee754_fmodf (float,float);
extern float __ieee754_powf (float,float);
extern float __ieee754_lgammaf_r (float,int *);
-extern float __ieee754_gammaf_r (float,int *);
extern float __ieee754_lgammaf (float);
extern float __ieee754_gammaf (float);
extern float __ieee754_log10f (float);
diff --git a/newlib/libm/common/fdlibm.h b/newlib/libm/common/fdlibm.h
index 8dffc832d..5226c2e13 100644
--- a/newlib/libm/common/fdlibm.h
+++ b/newlib/libm/common/fdlibm.h
@@ -159,7 +159,7 @@ extern double __ieee754_cosh __P((double));
extern double __ieee754_fmod __P((double,double));
extern double __ieee754_pow __P((double,double));
extern double __ieee754_lgamma_r __P((double,int *));
-extern double __ieee754_gamma_r __P((double,int *));
+extern double __ieee754_gamma __P((double));
extern double __ieee754_log10 __P((double));
extern double __ieee754_sinh __P((double));
extern double __ieee754_hypot __P((double,double));
@@ -205,7 +205,7 @@ extern float __ieee754_coshf __P((float));
extern float __ieee754_fmodf __P((float,float));
extern float __ieee754_powf __P((float,float));
extern float __ieee754_lgammaf_r __P((float,int *));
-extern float __ieee754_gammaf_r __P((float,int *));
+extern float __ieee754_gammaf __P((float));
extern float __ieee754_log10f __P((float));
extern float __ieee754_sinhf __P((float));
extern float __ieee754_hypotf __P((float,float));
diff --git a/newlib/libm/math/Makefile.am b/newlib/libm/math/Makefile.am
index e745159ae..87e47dbd5 100644
--- a/newlib/libm/math/Makefile.am
+++ b/newlib/libm/math/Makefile.am
@@ -14,7 +14,7 @@ src = k_standard.c k_rem_pio2.c \
e_scalb.c e_sinh.c e_sqrt.c \
w_acos.c w_acosh.c w_asin.c w_atan2.c \
w_atanh.c w_cosh.c w_exp.c w_fmod.c \
- w_gamma.c wr_gamma.c w_hypot.c w_j0.c \
+ w_gamma.c w_hypot.c w_j0.c \
w_j1.c w_jn.c w_lgamma.c wr_lgamma.c \
w_log.c w_log10.c w_pow.c w_remainder.c \
w_scalb.c w_sinh.c w_sqrt.c \
@@ -37,7 +37,7 @@ fsrc = kf_rem_pio2.c \
ef_scalb.c ef_sinh.c ef_sqrt.c \
wf_acos.c wf_acosh.c wf_asin.c wf_atan2.c \
wf_atanh.c wf_cosh.c wf_exp.c wf_fmod.c \
- wf_gamma.c wrf_gamma.c wf_hypot.c wf_j0.c \
+ wf_gamma.c wf_hypot.c wf_j0.c \
wf_j1.c wf_jn.c wf_lgamma.c wrf_lgamma.c \
wf_log.c wf_log10.c wf_pow.c wf_remainder.c \
wf_scalb.c wf_sinh.c wf_sqrt.c \
diff --git a/newlib/libm/math/Makefile.in b/newlib/libm/math/Makefile.in
index 0ac2b1668..9ba1be8ca 100644
--- a/newlib/libm/math/Makefile.in
+++ b/newlib/libm/math/Makefile.in
@@ -90,7 +90,7 @@ am__objects_1 = lib_a-k_standard.$(OBJEXT) lib_a-k_rem_pio2.$(OBJEXT) \
lib_a-w_atan2.$(OBJEXT) lib_a-w_atanh.$(OBJEXT) \
lib_a-w_cosh.$(OBJEXT) lib_a-w_exp.$(OBJEXT) \
lib_a-w_fmod.$(OBJEXT) lib_a-w_gamma.$(OBJEXT) \
- lib_a-wr_gamma.$(OBJEXT) lib_a-w_hypot.$(OBJEXT) \
+ lib_a-w_hypot.$(OBJEXT) \
lib_a-w_j0.$(OBJEXT) lib_a-w_j1.$(OBJEXT) lib_a-w_jn.$(OBJEXT) \
lib_a-w_lgamma.$(OBJEXT) lib_a-wr_lgamma.$(OBJEXT) \
lib_a-w_log.$(OBJEXT) lib_a-w_log10.$(OBJEXT) \
@@ -122,7 +122,7 @@ am__objects_2 = lib_a-kf_rem_pio2.$(OBJEXT) lib_a-kf_cos.$(OBJEXT) \
lib_a-wf_asin.$(OBJEXT) lib_a-wf_atan2.$(OBJEXT) \
lib_a-wf_atanh.$(OBJEXT) lib_a-wf_cosh.$(OBJEXT) \
lib_a-wf_exp.$(OBJEXT) lib_a-wf_fmod.$(OBJEXT) \
- lib_a-wf_gamma.$(OBJEXT) lib_a-wrf_gamma.$(OBJEXT) \
+ lib_a-wf_gamma.$(OBJEXT) \
lib_a-wf_hypot.$(OBJEXT) lib_a-wf_j0.$(OBJEXT) \
lib_a-wf_j1.$(OBJEXT) lib_a-wf_jn.$(OBJEXT) \
lib_a-wf_lgamma.$(OBJEXT) lib_a-wrf_lgamma.$(OBJEXT) \
@@ -151,7 +151,7 @@ am__objects_4 = k_standard.lo k_rem_pio2.lo k_cos.lo k_sin.lo k_tan.lo \
e_jn.lo er_lgamma.lo e_log.lo e_log10.lo e_pow.lo \
e_rem_pio2.lo e_remainder.lo e_scalb.lo e_sinh.lo e_sqrt.lo \
w_acos.lo w_acosh.lo w_asin.lo w_atan2.lo w_atanh.lo w_cosh.lo \
- w_exp.lo w_fmod.lo w_gamma.lo wr_gamma.lo w_hypot.lo w_j0.lo \
+ w_exp.lo w_fmod.lo w_gamma.lo w_hypot.lo w_j0.lo \
w_j1.lo w_jn.lo w_lgamma.lo wr_lgamma.lo w_log.lo w_log10.lo \
w_pow.lo w_remainder.lo w_scalb.lo w_sinh.lo w_sqrt.lo \
w_sincos.lo w_drem.lo s_asinh.lo s_atan.lo s_ceil.lo s_cos.lo \
@@ -164,7 +164,7 @@ am__objects_5 = kf_rem_pio2.lo kf_cos.lo kf_sin.lo kf_tan.lo \
ef_pow.lo ef_rem_pio2.lo ef_remainder.lo ef_scalb.lo \
ef_sinh.lo ef_sqrt.lo wf_acos.lo wf_acosh.lo wf_asin.lo \
wf_atan2.lo wf_atanh.lo wf_cosh.lo wf_exp.lo wf_fmod.lo \
- wf_gamma.lo wrf_gamma.lo wf_hypot.lo wf_j0.lo wf_j1.lo \
+ wf_gamma.lo wf_hypot.lo wf_j0.lo wf_j1.lo \
wf_jn.lo wf_lgamma.lo wrf_lgamma.lo wf_log.lo wf_log10.lo \
wf_pow.lo wf_remainder.lo wf_scalb.lo wf_sinh.lo wf_sqrt.lo \
wf_sincos.lo wf_drem.lo sf_asinh.lo sf_atan.lo sf_ceil.lo \
@@ -339,7 +339,7 @@ src = k_standard.c k_rem_pio2.c \
e_scalb.c e_sinh.c e_sqrt.c \
w_acos.c w_acosh.c w_asin.c w_atan2.c \
w_atanh.c w_cosh.c w_exp.c w_fmod.c \
- w_gamma.c wr_gamma.c w_hypot.c w_j0.c \
+ w_gamma.c w_hypot.c w_j0.c \
w_j1.c w_jn.c w_lgamma.c wr_lgamma.c \
w_log.c w_log10.c w_pow.c w_remainder.c \
w_scalb.c w_sinh.c w_sqrt.c \
@@ -362,7 +362,7 @@ fsrc = kf_rem_pio2.c \
ef_scalb.c ef_sinh.c ef_sqrt.c \
wf_acos.c wf_acosh.c wf_asin.c wf_atan2.c \
wf_atanh.c wf_cosh.c wf_exp.c wf_fmod.c \
- wf_gamma.c wrf_gamma.c wf_hypot.c wf_j0.c \
+ wf_gamma.c wf_hypot.c wf_j0.c \
wf_j1.c wf_jn.c wf_lgamma.c wrf_lgamma.c \
wf_log.c wf_log10.c wf_pow.c wf_remainder.c \
wf_scalb.c wf_sinh.c wf_sqrt.c \
@@ -690,12 +690,6 @@ lib_a-w_gamma.o: w_gamma.c
lib_a-w_gamma.obj: w_gamma.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-w_gamma.obj `if test -f 'w_gamma.c'; then $(CYGPATH_W) 'w_gamma.c'; else $(CYGPATH_W) '$(srcdir)/w_gamma.c'; fi`
-lib_a-wr_gamma.o: wr_gamma.c
- $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wr_gamma.o `test -f 'wr_gamma.c' || echo '$(srcdir)/'`wr_gamma.c
-
-lib_a-wr_gamma.obj: wr_gamma.c
- $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wr_gamma.obj `if test -f 'wr_gamma.c'; then $(CYGPATH_W) 'wr_gamma.c'; else $(CYGPATH_W) '$(srcdir)/wr_gamma.c'; fi`
-
lib_a-w_hypot.o: w_hypot.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-w_hypot.o `test -f 'w_hypot.c' || echo '$(srcdir)/'`w_hypot.c
@@ -1086,12 +1080,6 @@ lib_a-wf_gamma.o: wf_gamma.c
lib_a-wf_gamma.obj: wf_gamma.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wf_gamma.obj `if test -f 'wf_gamma.c'; then $(CYGPATH_W) 'wf_gamma.c'; else $(CYGPATH_W) '$(srcdir)/wf_gamma.c'; fi`
-lib_a-wrf_gamma.o: wrf_gamma.c
- $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wrf_gamma.o `test -f 'wrf_gamma.c' || echo '$(srcdir)/'`wrf_gamma.c
-
-lib_a-wrf_gamma.obj: wrf_gamma.c
- $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wrf_gamma.obj `if test -f 'wrf_gamma.c'; then $(CYGPATH_W) 'wrf_gamma.c'; else $(CYGPATH_W) '$(srcdir)/wrf_gamma.c'; fi`
-
lib_a-wf_hypot.o: wf_hypot.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wf_hypot.o `test -f 'wf_hypot.c' || echo '$(srcdir)/'`wf_hypot.c
diff --git a/newlib/libm/math/er_gamma.c b/newlib/libm/math/er_gamma.c
index 3c0e241e5..9252e2d04 100644
--- a/newlib/libm/math/er_gamma.c
+++ b/newlib/libm/math/er_gamma.c
@@ -22,11 +22,15 @@
#include "fdlibm.h"
#ifdef __STDC__
- double __ieee754_gamma_r(double x, int *signgamp)
+ double __ieee754_gamma(double x)
#else
- double __ieee754_gamma_r(x,signgamp)
- double x; int *signgamp;
+ double __ieee754_gamma(x)
+ double x;
#endif
{
- return __ieee754_exp (__ieee754_lgamma_r(x,signgamp));
+ int local_signgam = 1;
+ double y = __ieee754_exp (__ieee754_lgamma_r(x, &local_signgam));
+ if (local_signgam < 0)
+ y = -y;
+ return y;
}
diff --git a/newlib/libm/math/erf_gamma.c b/newlib/libm/math/erf_gamma.c
index 9e529dce0..bddac60c7 100644
--- a/newlib/libm/math/erf_gamma.c
+++ b/newlib/libm/math/erf_gamma.c
@@ -24,11 +24,15 @@
#include "fdlibm.h"
#ifdef __STDC__
- float __ieee754_gammaf_r(float x, int *signgamp)
+ float __ieee754_gammaf(float x)
#else
- float __ieee754_gammaf_r(x,signgamp)
- float x; int *signgamp;
+ float __ieee754_gammaf(x)
+ float x;
#endif
{
- return __ieee754_expf (__ieee754_lgammaf_r(x,signgamp));
+ int local_signgam = 1;
+ float y = __ieee754_expf (__ieee754_lgammaf_r(x,&local_signgam));
+ if (local_signgam < 0)
+ y = -y;
+ return y;
}
diff --git a/newlib/libm/math/w_gamma.c b/newlib/libm/math/w_gamma.c
index b65d5cc4b..bb47fab31 100644
--- a/newlib/libm/math/w_gamma.c
+++ b/newlib/libm/math/w_gamma.c
@@ -148,18 +148,7 @@ in terms of the base return values, although the <[signgam]> global for
double x;
#endif
{
-#ifdef _IEEE_LIBM
- return __ieee754_gamma_r(x,&(_REENT_SIGNGAM(_REENT)));
-#else
- double y;
- y = __ieee754_gamma_r(x,&(_REENT_SIGNGAM(_REENT)));
- if(_LIB_VERSION == _IEEE_) return y;
- if(!finite(y)&&finite(x)) {
- /* gamma(finite) overflow */
- errno = ERANGE;
- }
- return y;
-#endif
-}
+ return tgamma(x);
+}
#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/newlib/libm/math/w_tgamma.c b/newlib/libm/math/w_tgamma.c
index c0c011dd0..cbb3e7f7f 100644
--- a/newlib/libm/math/w_tgamma.c
+++ b/newlib/libm/math/w_tgamma.c
@@ -27,9 +27,7 @@
#endif
{
double y;
- int local_signgam;
- y = __ieee754_gamma_r(x,&local_signgam);
- if (local_signgam < 0) y = -y;
+ y = __ieee754_gamma(x);
#ifdef _IEEE_LIBM
return y;
#else
diff --git a/newlib/libm/math/wf_gamma.c b/newlib/libm/math/wf_gamma.c
index f0284a282..4e961c864 100644
--- a/newlib/libm/math/wf_gamma.c
+++ b/newlib/libm/math/wf_gamma.c
@@ -25,19 +25,8 @@
float x;
#endif
{
-#ifdef _IEEE_LIBM
- return __ieee754_gammaf_r(x,&(_REENT_SIGNGAM(_REENT)));
-#else
- float y;
- y = __ieee754_gammaf_r(x,&(_REENT_SIGNGAM(_REENT)));
- if(_LIB_VERSION == _IEEE_) return y;
- if(!finitef(y)&&finitef(x)) {
- /* gammaf(finite) overflow */
- errno = ERANGE;
- }
- return y;
-#endif
-}
+ return tgammaf(x);
+}
#ifdef _DOUBLE_IS_32BITS
diff --git a/newlib/libm/math/wf_tgamma.c b/newlib/libm/math/wf_tgamma.c
index 92df39648..8f0c501b8 100644
--- a/newlib/libm/math/wf_tgamma.c
+++ b/newlib/libm/math/wf_tgamma.c
@@ -24,9 +24,7 @@
#endif
{
float y;
- int local_signgam;
- y = __ieee754_gammaf_r(x,&local_signgam);
- if (local_signgam < 0) y = -y;
+ y = __ieee754_gammaf(x);
#ifdef _IEEE_LIBM
return y;
#else
diff --git a/newlib/libm/math/wr_gamma.c b/newlib/libm/math/wr_gamma.c
deleted file mode 100644
index c4c2a829e..000000000
--- a/newlib/libm/math/wr_gamma.c
+++ /dev/null
@@ -1,49 +0,0 @@
-
-/* @(#)wr_gamma.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * wrapper double gamma_r(double x, int *signgamp)
- */
-
-#include "fdlibm.h"
-#include <errno.h>
-
-#ifndef _DOUBLE_IS_32BITS
-
-#ifdef __STDC__
- double gamma_r(double x, int *signgamp) /* wrapper lgamma_r */
-#else
- double gamma_r(x,signgamp) /* wrapper lgamma_r */
- double x; int *signgamp;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_gamma_r(x,signgamp);
-#else
- double y;
- y = __ieee754_gamma_r(x,signgamp);
- if(_LIB_VERSION == _IEEE_) return y;
- if(!finite(y)&&finite(x)) {
- if(floor(x)==x&&x<=0.0)
- /* gamma(-integer) or gamma(0) */
- errno = EDOM;
- else
- /* gamma(finite) overflow */
- errno = ERANGE;
- return HUGE_VALF;
- } else
- return y;
-#endif
-}
-
-#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/newlib/libm/math/wrf_gamma.c b/newlib/libm/math/wrf_gamma.c
deleted file mode 100644
index d43c7f03d..000000000
--- a/newlib/libm/math/wrf_gamma.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/* wrf_gamma.c -- float version of wr_gamma.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/*
- * wrapper float gammaf_r(float x, int *signgamp)
- */
-
-#include "fdlibm.h"
-#include <errno.h>
-
-#ifdef __STDC__
- float gammaf_r(float x, int *signgamp) /* wrapper lgammaf_r */
-#else
- float gammaf_r(x,signgamp) /* wrapper lgammaf_r */
- float x; int *signgamp;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_gammaf_r(x,signgamp);
-#else
- float y;
- y = __ieee754_gammaf_r(x,signgamp);
- if(_LIB_VERSION == _IEEE_) return y;
- if(!finitef(y)&&finitef(x)) {
- if(floorf(x)==x&&x<=0.0f) {
- /* gammaf(-integer) or gamma(0) */
- errno = EDOM;
- } else {
- /* gammaf(finite) overflow */
- errno = ERANGE;
- }
- return HUGE_VALF;
- } else
- return y;
-#endif
-}
--
2.28.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 3/3] libm: Adjust errno/exception values for gamma/lgamma
2020-08-26 17:03 [PATCH 0/3] libm: Clean up gamma functions Keith Packard
2020-08-26 17:03 ` [PATCH 1/3] libm: Fix sign value returned from __ieee754_lgamma*_r(-0) Keith Packard
2020-08-26 17:03 ` [PATCH 2/3] libm: Remove __ieee754_gamma_r variants Keith Packard
@ 2020-08-26 17:03 ` Keith Packard
[not found] ` <SN5P110MB0383012287522E8285674CAB9A550@SN5P110MB0383.NAMP110.PROD.OUTLOOK.COM>
[not found] ` <SN5P110MB0383186ECD9B028A4B0E2ECC9A550@SN5P110MB0383.NAMP110.PROD.OUTLOOK.COM>
3 siblings, 1 reply; 34+ messages in thread
From: Keith Packard @ 2020-08-26 17:03 UTC (permalink / raw)
To: newlib
This makes all of gamma/lgamma functions match POSIX (and glibc) for
errno and exception values for both gamma and lgamma functions.
The big change is to support the exception/errno value differences for
tgamma/lgamma for negative integer arguments. tgamma produces
EDOM/FE_INVALID while lgamma produces ERANGE/FE_DIVBYZERO.
This was done by splitting the lowest level __ieee754_lgamma*_r
functions apart. The new lower-level ___ieee754_lgamma*_r functions
can now produce exceptions which are correct for either lgamma or
tgamma and use the value in the signgamp parameter to select which
mode to operate in.
All functions now return EDOM/FE_INVALID for -INFINITY, although POSIX
doesn't specify this behavior for lgamma. It does match glibc at
least.
Signed-off-by: Keith Packard <keithp@keithp.com>
---
newlib/libm/common/fdlibm.h | 2 ++
newlib/libm/math/er_gamma.c | 2 +-
newlib/libm/math/er_lgamma.c | 32 ++++++++++++++++++++++++++------
newlib/libm/math/erf_gamma.c | 2 +-
newlib/libm/math/erf_lgamma.c | 30 +++++++++++++++++++++++++-----
newlib/libm/math/k_standard.c | 13 ++++++++++---
newlib/libm/math/w_tgamma.c | 6 ++++--
newlib/libm/math/wf_tgamma.c | 7 +++++--
8 files changed, 74 insertions(+), 20 deletions(-)
diff --git a/newlib/libm/common/fdlibm.h b/newlib/libm/common/fdlibm.h
index 5226c2e13..5613747bb 100644
--- a/newlib/libm/common/fdlibm.h
+++ b/newlib/libm/common/fdlibm.h
@@ -159,6 +159,7 @@ extern double __ieee754_cosh __P((double));
extern double __ieee754_fmod __P((double,double));
extern double __ieee754_pow __P((double,double));
extern double __ieee754_lgamma_r __P((double,int *));
+extern double ___ieee754_lgamma_r __P((double,int *));
extern double __ieee754_gamma __P((double));
extern double __ieee754_log10 __P((double));
extern double __ieee754_sinh __P((double));
@@ -205,6 +206,7 @@ extern float __ieee754_coshf __P((float));
extern float __ieee754_fmodf __P((float,float));
extern float __ieee754_powf __P((float,float));
extern float __ieee754_lgammaf_r __P((float,int *));
+extern float ___ieee754_lgammaf_r __P((float,int *));
extern float __ieee754_gammaf __P((float));
extern float __ieee754_log10f __P((float));
extern float __ieee754_sinhf __P((float));
diff --git a/newlib/libm/math/er_gamma.c b/newlib/libm/math/er_gamma.c
index 9252e2d04..d7731c1c3 100644
--- a/newlib/libm/math/er_gamma.c
+++ b/newlib/libm/math/er_gamma.c
@@ -29,7 +29,7 @@
#endif
{
int local_signgam = 1;
- double y = __ieee754_exp (__ieee754_lgamma_r(x, &local_signgam));
+ double y = __ieee754_exp (___ieee754_lgamma_r(x, &local_signgam));
if (local_signgam < 0)
y = -y;
return y;
diff --git a/newlib/libm/math/er_lgamma.c b/newlib/libm/math/er_lgamma.c
index 36408382f..a93d54cf2 100644
--- a/newlib/libm/math/er_lgamma.c
+++ b/newlib/libm/math/er_lgamma.c
@@ -210,21 +210,26 @@ static double zero= 0.00000000000000000000e+00;
#ifdef __STDC__
- double __ieee754_lgamma_r(double x, int *signgamp)
+ double ___ieee754_lgamma_r(double x, int *signgamp)
#else
- double __ieee754_lgamma_r(x,signgamp)
+ double ___ieee754_lgamma_r(x, signgamp)
double x; int *signgamp;
#endif
{
double t,y,z,nadj = 0.0,p,p1,p2,p3,q,r,w;
__int32_t i,hx,lx,ix;
+ int mode = *signgamp;
EXTRACT_WORDS(hx,lx,x);
/* purge off +-inf, NaN, +-0, and negative arguments */
*signgamp = 1;
ix = hx&0x7fffffff;
- if(ix>=0x7ff00000) return x*x;
+ if(ix>=0x7ff00000) {
+ if (hx<0 && mode)
+ return __math_invalid(x);
+ return x*x;
+ }
if((ix|lx)==0) {
if(hx<0)
*signgamp = -1;
@@ -237,10 +242,19 @@ static double zero= 0.00000000000000000000e+00;
} else return -__ieee754_log(x);
}
if(hx<0) {
- if(ix>=0x43300000) /* |x|>=2**52, must be -integer */
- return one/zero;
+ if(ix>=0x43300000) { /* |x|>=2**52, must be -integer */
+ if (mode)
+ return __math_invalid(x);
+ else
+ return one/zero; /* -integer */
+ }
t = sin_pi(x);
- if(t==zero) return one/zero; /* -integer */
+ if(t==zero) {
+ if (mode)
+ return __math_invalid(x);
+ else
+ return one/zero; /* -integer */
+ }
nadj = __ieee754_log(pi/fabs(t*x));
if(t<zero) *signgamp = -1;
x = -x;
@@ -311,3 +325,9 @@ static double zero= 0.00000000000000000000e+00;
if(hx<0) r = nadj - r;
return r;
}
+
+double __ieee754_lgamma_r(double x, int *signgamp)
+{
+ *signgamp = 0;
+ return ___ieee754_lgamma_r(x, signgamp);
+}
diff --git a/newlib/libm/math/erf_gamma.c b/newlib/libm/math/erf_gamma.c
index bddac60c7..9eeb5d978 100644
--- a/newlib/libm/math/erf_gamma.c
+++ b/newlib/libm/math/erf_gamma.c
@@ -31,7 +31,7 @@
#endif
{
int local_signgam = 1;
- float y = __ieee754_expf (__ieee754_lgammaf_r(x,&local_signgam));
+ float y = __ieee754_expf (___ieee754_lgammaf_r(x,&local_signgam));
if (local_signgam < 0)
y = -y;
return y;
diff --git a/newlib/libm/math/erf_lgamma.c b/newlib/libm/math/erf_lgamma.c
index a45423949..ec83c82ff 100644
--- a/newlib/libm/math/erf_lgamma.c
+++ b/newlib/libm/math/erf_lgamma.c
@@ -145,21 +145,26 @@ static float zero= 0.0000000000e+00;
#ifdef __STDC__
- float __ieee754_lgammaf_r(float x, int *signgamp)
+ float ___ieee754_lgammaf_r(float x, int *signgamp)
#else
- float __ieee754_lgammaf_r(x,signgamp)
+ float ___ieee754_lgammaf_r(x,signgamp)
float x; int *signgamp;
#endif
{
float t,y,z,nadj = 0.0,p,p1,p2,p3,q,r,w;
__int32_t i,hx,ix;
+ int mode = *signgamp;
GET_FLOAT_WORD(hx,x);
/* purge off +-inf, NaN, +-0, and negative arguments */
*signgamp = 1;
ix = hx&0x7fffffff;
- if(ix>=0x7f800000) return x*x;
+ if(ix>=0x7f800000) {
+ if (hx<0 && mode)
+ return __math_invalidf(x);
+ return x*x;
+ }
if(ix==0) {
if(hx<0)
*signgamp = -1;
@@ -172,10 +177,18 @@ static float zero= 0.0000000000e+00;
} else return -__ieee754_logf(x);
}
if(hx<0) {
- if(ix>=0x4b000000) /* |x|>=2**23, must be -integer */
+ if(ix>=0x4b000000) { /* |x|>=2**23, must be -integer */
+ if (mode)
+ return __math_invalidf(x);
return one/zero;
+ }
t = sin_pif(x);
- if(t==zero) return one/zero; /* -integer */
+ if(t==zero) {
+ /* tgamma wants NaN instead of INFINITY */
+ if (mode)
+ return __math_invalidf(x);
+ return one/zero; /* -integer */
+ }
nadj = __ieee754_logf(pi/fabsf(t*x));
if(t<zero) *signgamp = -1;
x = -x;
@@ -246,3 +259,10 @@ static float zero= 0.0000000000e+00;
if(hx<0) r = nadj - r;
return r;
}
+
+
+float __ieee754_lgammaf_r(float x, int *signgamp)
+{
+ *signgamp = 0;
+ return ___ieee754_lgammaf_r(x, signgamp);
+}
diff --git a/newlib/libm/math/k_standard.c b/newlib/libm/math/k_standard.c
index 906412ba7..8380ad682 100644
--- a/newlib/libm/math/k_standard.c
+++ b/newlib/libm/math/k_standard.c
@@ -74,7 +74,8 @@ static double zero = 0.0; /* used as const */
* 39-- yn(x>X_TLOSS, n)
* 40-- gamma(finite) overflow
* 41-- gamma(-integer)
- * 42-- pow(NaN,0.0)
+ * 42-- gamma(0)
+ * 43-- pow(NaN,0.0)
*/
@@ -336,12 +337,18 @@ static double zero = 0.0; /* used as const */
break;
case 41:
case 141:
- /* gamma(-integer) or gamma(0) */
- retval = HUGE_VAL;
+ /* gamma(-integer) */
+ retval = (double) NAN;
errno = EDOM;
break;
case 42:
case 142:
+ /* gamma(0) */
+ retval = copysign(HUGE_VAL,x);
+ errno = ERANGE;
+ break;
+ case 43:
+ case 143:
/* pow(NaN,0.0) */
/* Not an error. */
retval = 1.0;
diff --git a/newlib/libm/math/w_tgamma.c b/newlib/libm/math/w_tgamma.c
index cbb3e7f7f..af8d1e918 100644
--- a/newlib/libm/math/w_tgamma.c
+++ b/newlib/libm/math/w_tgamma.c
@@ -34,8 +34,10 @@
if(_LIB_VERSION == _IEEE_) return y;
if(!finite(y)&&finite(x)) {
- if(floor(x)==x&&x<=0.0)
- return __kernel_standard(x,x,41); /* tgamma pole */
+ if (x==0.0)
+ return __kernel_standard(x,x,42); /* tgamma pole */
+ else if(floor(x)==x&&x<0.0)
+ return __kernel_standard(x,x,41); /* tgamma domain */
else
return __kernel_standard(x,x,40); /* tgamma overflow */
}
diff --git a/newlib/libm/math/wf_tgamma.c b/newlib/libm/math/wf_tgamma.c
index 8f0c501b8..bf6273b60 100644
--- a/newlib/libm/math/wf_tgamma.c
+++ b/newlib/libm/math/wf_tgamma.c
@@ -31,8 +31,11 @@
if(_LIB_VERSION == _IEEE_) return y;
if(!finitef(y)&&finitef(x)) {
- if(floorf(x)==x&&x<=(float)0.0)
- /* tgammaf pole */
+ if (x==0.0f)
+ /* tgammf pole */
+ return (float)__kernel_standard((double)x,(double)x,142);
+ else if(floorf(x)==x&&x<(float)0.0)
+ /* tgammaf domain */
return (float)__kernel_standard((double)x,(double)x,141);
else
/* tgammaf overflow */
--
2.28.0
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
2020-08-26 17:03 ` [PATCH 2/3] libm: Remove __ieee754_gamma_r variants Keith Packard
@ 2020-08-26 18:20 ` Corinna Vinschen
2020-08-26 19:10 ` Keith Packard
0 siblings, 1 reply; 34+ messages in thread
From: Corinna Vinschen @ 2020-08-26 18:20 UTC (permalink / raw)
To: newlib
Hi Keith,
On Aug 26 10:03, Keith Packard via Newlib wrote:
> Gamma should consume the sign reported by lgamma internally instead of
> providing it back to the application. This removes the need to have _r
> variants as there is no longer any re-entrancy issues with the API.
You can't do that. gamma_r/gammaf_r/lgamma_r/lgammaf_r are BSD
functions. They have been exported by Cygwin since 2001. The entry
points need to be kept available with unchanged semantics.
Corinna
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
2020-08-26 18:20 ` Corinna Vinschen
@ 2020-08-26 19:10 ` Keith Packard
2020-08-27 7:24 ` Corinna Vinschen
0 siblings, 1 reply; 34+ messages in thread
From: Keith Packard @ 2020-08-26 19:10 UTC (permalink / raw)
To: Corinna Vinschen via Newlib, newlib; +Cc: Corinna Vinschen
[-- Attachment #1: Type: text/plain, Size: 413 bytes --]
Corinna Vinschen via Newlib <newlib@sourceware.org> writes:
> You can't do that. gamma_r/gammaf_r/lgamma_r/lgammaf_r are BSD
> functions. They have been exported by Cygwin since 2001. The entry
> points need to be kept available with unchanged semantics.
They changed on accident in 2002 -- gamma_r *used* to be an alias for
lgamma_r and was changed to be a (broken) alias for tgamma.
--
-keith
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
2020-08-26 19:10 ` Keith Packard
@ 2020-08-27 7:24 ` Corinna Vinschen
2020-08-27 17:05 ` Keith Packard
0 siblings, 1 reply; 34+ messages in thread
From: Corinna Vinschen @ 2020-08-27 7:24 UTC (permalink / raw)
To: newlib
On Aug 26 12:10, Keith Packard via Newlib wrote:
> Corinna Vinschen via Newlib <newlib@sourceware.org> writes:
>
> > You can't do that. gamma_r/gammaf_r/lgamma_r/lgammaf_r are BSD
> > functions. They have been exported by Cygwin since 2001. The entry
> > points need to be kept available with unchanged semantics.
>
> They changed on accident in 2002 -- gamma_r *used* to be an alias for
> lgamma_r and was changed to be a (broken) alias for tgamma.
Nevertheless, the symbols have to be exported for backward compatibility.
So you're saying aliasing gamma_r to lgamma_r and gammaf_r to lgammaf_r
in the DLLs export table would be sufficient?
Thanks,
Corinna
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
2020-08-27 7:24 ` Corinna Vinschen
@ 2020-08-27 17:05 ` Keith Packard
2020-08-28 8:19 ` Corinna Vinschen
0 siblings, 1 reply; 34+ messages in thread
From: Keith Packard @ 2020-08-27 17:05 UTC (permalink / raw)
To: Corinna Vinschen via Newlib, newlib; +Cc: Corinna Vinschen
[-- Attachment #1: Type: text/plain, Size: 3459 bytes --]
Corinna Vinschen via Newlib <newlib@sourceware.org> writes:
> Nevertheless, the symbols have to be exported for backward compatibility.
> So you're saying aliasing gamma_r to lgamma_r and gammaf_r to lgammaf_r
> in the DLLs export table would be sufficient?
It depends if you want the pre-2002 functionality or the post-2002
functionality.
Before 2002, gamma_r and gammaf_r were as BSD originally specified them,
returning the log of gamma (ln(|Γ(x)|)) with the sign of gamma stored
through the second, int *, argument. In 2002, this patch was made to
er_gamma.c:
$ git show 0953fe640f177b565578ed7ecc77169ec1a914fa er_gamma.c
diff --git a/newlib/libm/math/er_gamma.c b/newlib/libm/math/er_gamma.c
index a7183c50f..3c0e241e5 100644
@@ -28,5 +28,5 @@
double x; int *signgamp;
#endif
{
- return __ieee754_lgamma_r(x,signgamp);
+ return __ieee754_exp (__ieee754_lgamma_r(x,signgamp));
}
Before this patch, __ieee754_gamma_r was simply another name for
__ieee754_lgamma_r. After this patch, __ieee754_gamma_r became something
that doesn't exist in any other math library: it returns |Γ(x)| and
stores the sign through the second, int *, argument. Internally, this is
used in w_gamma.c, w_tgamma.c, wr_gamma.c.
w_tgamma.c uses it correctly:
y = __ieee754_gamma_r(x,&local_signgam);
if (local_signgam < 0) y = -y;
w_gamma.c, which exports the 'gamma' function uses it *incorrectly* --
it didn't change after the above patch, and so it unexpectedly changed
from returning ln(|Γ(x)|) to returning |Γ(x)|. Applications using
'gamma' instead of 'tgamma' will be getting the wrong answer for some
parameters.
I have to assume this was just an oversight. In 2009, another patch to
w_gamma.c adds a comment explicitly stating that gamma and gamma_r
return ln(|Γ(x)|), when in fact they had been changed to
|Γ(x)| due to the change to __ieee754_gamma_r in the above patch.
Even today, wr_gamma.c says:
double gamma_r(double x, int *signgamp) /* wrapper lgamma_r */
which is incorrect, as it calls __ieee754_gamma_r.
I see a couple of options here:
1) Leave things as they are. This makes the 'gamma' family of functions
incompatible with all other libc implementations and creates a trap
for applications expecting either lgamma or tgamma values.
2) Finish the work started in 2002 and make the 'gamma' family
compatible with their 'tgamma' equivalents. This is what my patch
does. This makes newlib compatible with 4.4 BSD libc, and leaves
'gamma' returning the same value anytime that value is non-negative.
3) Revert the 2002 change so that all of the 'gamma' family return the
same value as their lgamma equivalents. That would make gamma_r
useful again, as an alias for lgamma_r. This would make newlib
compatible with glibc.
4) Remove the 'gamma' family completely. Given that the meaning of
'gamma' differs between 4.4 BSD and glibc, it would be safest to
force applications to select between tgamma and lgamma.
I chose option 2 because that offers the best API compatibility -- the
gamma functions return the same value for most arguments (any positive
arguments, and half of negative arguments).
Any code using the gamma_r functions are likely expecting that to return
lgamma_r (as documented in several places). I can't see how we can leave
that function in the library as-is responsibly.
--
-keith
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Fw: [PATCH 0/3] libm: Clean up gamma functions
[not found] ` <SN5P110MB0383186ECD9B028A4B0E2ECC9A550@SN5P110MB0383.NAMP110.PROD.OUTLOOK.COM>
@ 2020-08-27 17:43 ` C Howland
2020-08-27 23:59 ` Keith Packard
0 siblings, 1 reply; 34+ messages in thread
From: C Howland @ 2020-08-27 17:43 UTC (permalink / raw)
To: newlib
> ------------------------------
> *From:* Newlib <newlib-bounces@sourceware.org> on behalf of Keith Packard
> via Newlib <newlib@sourceware.org>
> *Sent:* Wednesday, August 26, 2020 1:03 PM
> *To:* newlib@sourceware.org <newlib@sourceware.org>
> *Subject:* [PATCH 0/3] libm: Clean up gamma functions
>
> EXTERNAL EMAIL - This email originated from outside of CACI. Do not click
> any links or attachments unless you recognize and trust the sender.
>
>
>
>
>
> This series cleans up some API oddities and inaccuracies in
> errno/exception reporting from the various gamma related functions.
> With this series applied, newlib now matches the POSIX spec (and glibc)
> for tgamma/lgamma functions. I've left the 'gamma' functions BSD
> compatible (tgamma instead of lgamma) to avoid changing the API.
>
> [PATCH 1/3] libm: Fix sign value returned from __ieee754_lgamma*_r(-0)
>
> Following the C spec, gamma(-0) should be -INFINITY rather than
> +INFINITY, so the *signgamp value in lgamma should be -1
> rather than +1 for this case.
>
What C spec? Neither C99 nor C11 say so that I see for lgamma(). POSIX
makes the direct statement "If x is a non-positive integer, a pole error
shall occur and lgamma(), lgammaf(), and lgammal() shall return +HUGE_VAL,
+HUGE_VALF, and +HUGE_VALL, respectively." 0, regardless of sign, falls
under that.
https://pubs.opengroup.org/onlinepubs/9699919799/functions/lgamma.html
Additionally, the Linux lgamma man page, using GLIBC, says the same thing
as quoted from POSIX (not word for word, but the identical result).
(POSIX does require the +-0 +-INFINITY for tgamma(). Did these get crossed
up?)
Craig
>
> [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
>
> Back in 2002, a patch changed the various gamma functions so
> that the returned abs(gamma) instead of the ln of gamma. This
> left the _r variants in place, with their extra parameter to
> return the sign of the resulting value. This doesn't make any
> sense to me and looks like it was just a mistake. I've changed
> the __ieee754_gamma functions to apply the sign value locally
> and eliminated the gamma_r versions as those are no longer useful.
>
> [PATCH 3/3] libm: Adjust errno/exception values for gamma/lgamma
>
> There's a pretty detailed discussion in the commit message
> here, the short version is that tgamma and lgamma are
> specified with different errno/exception behaviour for
> one class of inputs (negative integers).
>
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Fw: [PATCH 3/3] libm: Adjust errno/exception values for gamma/lgamma
[not found] ` <SN5P110MB0383012287522E8285674CAB9A550@SN5P110MB0383.NAMP110.PROD.OUTLOOK.COM>
@ 2020-08-27 17:55 ` C Howland
2020-08-27 19:28 ` Brian Inglis
0 siblings, 1 reply; 34+ messages in thread
From: C Howland @ 2020-08-27 17:55 UTC (permalink / raw)
To: newlib
> ------------------------------
> *From:* Newlib <newlib-bounces@sourceware.org> on behalf of Keith Packard
> via Newlib <newlib@sourceware.org>
> *Sent:* Wednesday, August 26, 2020 1:03 PM
> *To:* newlib@sourceware.org <newlib@sourceware.org>
> *Subject:* [PATCH 3/3] libm: Adjust errno/exception values for
> gamma/lgamma
>
>
>
>
> This makes all of gamma/lgamma functions match POSIX (and glibc) for
> errno and exception values for both gamma and lgamma functions.
>
> The big change is to support the exception/errno value differences for
> tgamma/lgamma for negative integer arguments. tgamma produces
> EDOM/FE_INVALID while lgamma produces ERANGE/FE_DIVBYZERO.
>
> This was done by splitting the lowest level __ieee754_lgamma*_r
> functions apart. The new lower-level ___ieee754_lgamma*_r functions
> can now produce exceptions which are correct for either lgamma or
> tgamma and use the value in the signgamp parameter to select which
> mode to operate in.
>
> All functions now return EDOM/FE_INVALID for -INFINITY, although POSIX
> doesn't specify this behavior for lgamma. It does match glibc at
> least.
>
I think you're looking at an old GLIBC. From my RHEL7 lgamma() man page:
" If the result overflows, a range error occurs, and the functions
return
HUGE_VAL, HUGE_VALF, or HUGE_VALL, respectively, with the correct
math‐
ematical sign.
...
BUGS
In glibc 2.9 and earlier, when a pole error occurs, errno is set
to
EDOM; instead of the POSIX-mandated ERANGE. Since version 2.10,
glibc
does the right thing."
POSIX has only pole and range errors listed for lgamma(), both of which
return ERANGE, so it is definitely improper to return EDOM. It should be
range, so ERANGE/FE_OVERFLOW is what it ought to be.
>
> Signed-off-by: Keith Packard <keithp@keithp.com>
>
>
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Fw: [PATCH 3/3] libm: Adjust errno/exception values for gamma/lgamma
2020-08-27 17:55 ` Fw: " C Howland
@ 2020-08-27 19:28 ` Brian Inglis
0 siblings, 0 replies; 34+ messages in thread
From: Brian Inglis @ 2020-08-27 19:28 UTC (permalink / raw)
To: newlib
On 2020-08-27 11:55, C Howland via Newlib wrote:
> On Wednesday, August 26, 2020 1:03 PM, Keith Packard wrote:
>> This makes all of gamma/lgamma functions match POSIX (and glibc) for
>> errno and exception values for both gamma and lgamma functions.
>>
>> The big change is to support the exception/errno value differences for
>> tgamma/lgamma for negative integer arguments. tgamma produces
>> EDOM/FE_INVALID while lgamma produces ERANGE/FE_DIVBYZERO.
>>
>> This was done by splitting the lowest level __ieee754_lgamma*_r
>> functions apart. The new lower-level ___ieee754_lgamma*_r functions
>> can now produce exceptions which are correct for either lgamma or
>> tgamma and use the value in the signgamp parameter to select which
>> mode to operate in.
>>
>> All functions now return EDOM/FE_INVALID for -INFINITY, although POSIX
>> doesn't specify this behavior for lgamma. It does match glibc at
>> least.
> I think you're looking at an old GLIBC. From my RHEL7 lgamma() man page:
> " If the result overflows, a range error occurs, and the functions
> return
> HUGE_VAL, HUGE_VALF, or HUGE_VALL, respectively, with the correct
> math‐
> ematical sign.
> ...
> BUGS
> In glibc 2.9 and earlier, when a pole error occurs, errno is set
> to
> EDOM; instead of the POSIX-mandated ERANGE. Since version 2.10,
> glibc
> does the right thing."
> POSIX has only pole and range errors listed for lgamma(), both of which
> return ERANGE, so it is definitely improper to return EDOM. It should be
> range, so ERANGE/FE_OVERFLOW is what it ought to be.
RHEL7 uses an *old glibc* 2.17 from 2012, compared to Fedora Rawhide with latest
glibc release 2.32.
Check out the specs at the tops of the *current glibc* sources of the gamma
functions to be found nearby online under:
https://sourceware.org/git/?p=glibc.git;a=tree;f=sysdeps/ieee754/dbl-64
--
Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada
This email may be disturbing to some readers as it contains
too much technical detail. Reader discretion is advised.
[Data in IEC units and prefixes, physical quantities in SI.]
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Fw: [PATCH 0/3] libm: Clean up gamma functions
2020-08-27 17:43 ` Fw: [PATCH 0/3] libm: Clean up gamma functions C Howland
@ 2020-08-27 23:59 ` Keith Packard
2020-08-28 2:03 ` Brian Inglis
0 siblings, 1 reply; 34+ messages in thread
From: Keith Packard @ 2020-08-27 23:59 UTC (permalink / raw)
To: C Howland, newlib
[-- Attachment #1: Type: text/plain, Size: 1719 bytes --]
C Howland via Newlib <newlib@sourceware.org> writes:
>> Following the C spec, gamma(-0) should be -INFINITY rather than
>> +INFINITY, so the *signgamp value in lgamma should be -1
>> rather than +1 for this case.
>>
> What C spec? Neither C99 nor C11 say so that I see for lgamma(). POSIX
> makes the direct statement "If x is a non-positive integer, a pole error
> shall occur and lgamma(), lgammaf(), and lgammal() shall return +HUGE_VAL,
> +HUGE_VALF, and +HUGE_VALL, respectively." 0, regardless of sign, falls
> under that.
Right, C99/C11 doesn't mention signgam at all, so POSIX is free to
define it as it likes. That spec only says that it's value is undefined
when the parameter is a negative integer.
C99 says that , tgamma should return -INFINITY for -0. As newlib makes
'gamma' an alias for tgamma, gamma should probably return the same
thing. To make that work with our implementation of tgamma, (which uses
lgamma and the 'signgam' value), that signgam value should be -1.
> https://pubs.opengroup.org/onlinepubs/9699919799/functions/lgamma.html
> Additionally, the Linux lgamma man page, using GLIBC, says the same thing
> as quoted from POSIX (not word for word, but the identical result).
> (POSIX does require the +-0 +-INFINITY for tgamma(). Did these get crossed
> up?)
> Craig
I think we're probably just confusing gamma between lgamma and tgamma --
newlib defines gamma 'oddly' (fixed in 2/3).
I think the only problematic patch in the series is in changing the
semantics of gamma/gammaf and removing the gamma_r/gammaf_r -- we need
to decide how to recover from what looks like a mistake introduced 18
years ago.
--
-keith
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Fw: [PATCH 0/3] libm: Clean up gamma functions
2020-08-27 23:59 ` Keith Packard
@ 2020-08-28 2:03 ` Brian Inglis
2020-08-28 3:13 ` Keith Packard
0 siblings, 1 reply; 34+ messages in thread
From: Brian Inglis @ 2020-08-28 2:03 UTC (permalink / raw)
To: newlib
On 2020-08-27 17:59, Keith Packard via Newlib wrote:
> C Howland via Newlib <newlib@sourceware.org> writes:
>
>>> Following the C spec, gamma(-0) should be -INFINITY rather than
>>> +INFINITY, so the *signgamp value in lgamma should be -1 rather than +1
>>> for this case.
>>>
>> What C spec? Neither C99 nor C11 say so that I see for lgamma(). POSIX
>> makes the direct statement "If x is a non-positive integer, a pole error
>> shall occur and lgamma(), lgammaf(), and lgammal() shall return +HUGE_VAL,
>> +HUGE_VALF, and +HUGE_VALL, respectively." 0, regardless of sign, falls
>> under that.
>
> Right, C99/C11 doesn't mention signgam at all, so POSIX is free to
> define it as it likes. That spec only says that it's value is undefined
> when the parameter is a negative integer.
>
> C99 says that , tgamma should return -INFINITY for -0. As newlib makes
> 'gamma' an alias for tgamma, gamma should probably return the same
> thing. To make that work with our implementation of tgamma, (which uses
> lgamma and the 'signgam' value), that signgam value should be -1.
Last C17 public FDIS N2176 is available via:
https://web.archive.org/web/20181230041359if_/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf
see 7.12.8.3 lgamma and 7.12.8.4 tgamma on pp181-182, 7.26 tgmath #5 lgamma,
tgamma pp272-273, 7.31.1 complex clgamma, ctgamma p332, F10.5.3 lgamma and
F.10.5.4 tgamma.
>> https://pubs.opengroup.org/onlinepubs/9699919799/functions/lgamma.html
>> Additionally, the Linux lgamma man page, using GLIBC, says the same thing
>> as quoted from POSIX (not word for word, but the identical result).
>> (POSIX does require the +-0 +-INFINITY for tgamma(). Did these get crossed
>> up?)
>> Craig
>
> I think we're probably just confusing gamma between lgamma and tgamma --
> newlib defines gamma 'oddly' (fixed in 2/3).
>
> I think the only problematic patch in the series is in changing the
> semantics of gamma/gammaf and removing the gamma_r/gammaf_r -- we need
> to decide how to recover from what looks like a mistake introduced 18
> years ago.
--
Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada
This email may be disturbing to some readers as it contains
too much technical detail. Reader discretion is advised.
[Data in IEC units and prefixes, physical quantities in SI.]
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Fw: [PATCH 0/3] libm: Clean up gamma functions
2020-08-28 2:03 ` Brian Inglis
@ 2020-08-28 3:13 ` Keith Packard
2020-08-28 3:51 ` Brian Inglis
2020-08-28 18:29 ` Joseph Myers
0 siblings, 2 replies; 34+ messages in thread
From: Keith Packard @ 2020-08-28 3:13 UTC (permalink / raw)
To: Brian Inglis, newlib
[-- Attachment #1: Type: text/plain, Size: 5218 bytes --]
Brian Inglis <Brian.Inglis@SystematicSw.ab.ca> writes:
> Last C17 public FDIS N2176 is available via:
>
> https://web.archive.org/web/20181230041359if_/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf
>
> see 7.12.8.3 lgamma and 7.12.8.4 tgamma on pp181-182, 7.26 tgmath #5 lgamma,
> tgamma pp272-273, 7.31.1 complex clgamma, ctgamma p332, F10.5.3 lgamma and
> F.10.5.4 tgamma.
Thanks for the link -- the difference for lgamma is that in C99:
A range error occurs if x is too large. A range error may occur
if x is a negative integer or zero.
While in C17:
A range error occurs if positive x is too large. A pole error
may occur if x is a negative integer or zero.
Frustratingly, tgamma still returns different errors. In C99:
A domain error or range error may occur if x is a negative
integer or zero. A range error may occur if the magnitude of x
is too large or too small.
While in C17:
A domain error or pole error may occur if x is a negative
integer or zero. A range error occurs if the magnitude of x is
too large and may occur if the magnitude of x is too small.
C17 appears to have added this new 'pole' error, which seems to match
what the IEEE 754 calls a 'divideByZero exception'. Let's see if my
understanding of the various errors is correct:
IEEE C17 POSIX errno Exception
divideByZero Pole Pole ERANGE FE_DIVBYZERO
invalid Domain Domain EDOM FE_INVALID
overflow Range Range ERANGE FE_OVERFLOW
POSIX is more specific than C17, but it does appear to have been updated
to follow that spec, including the term 'Pole Error' which wasn't in
C99.
As my tests all refer to the POSIX spec (which defines the
errno/exception values), I think they're correct. Here's the set of
values I'm testing for both tgamma and lgamma (I'm not testing gamma
currently; we need to sort out what it should be doing first):
Value tgamma lgamma
POSIX result errno exception POSIX result errno exception
+0 Pole +INFINITY ERANGE FE_DIVBYZERO Pole +INFINITY ERANGE FE_DIVBYZERO
-0 Pole -INFINITY ERANGE FE_DIVBYZERO Pole +INFINITY ERANGE FE_DIVBYZERO
-1 Domain NAN EDOM FE_INVALID Pole +INFINITY ERANGE FE_DIVBYZERO
+3e38f Range +INFINITY ERANGE FE_OVERFLOW Range +INFINITY ERANGE FE_OVERFLOW
+1.7e308 Range +INFINITY ERANGE FE_OVERFLOW Range +INFINITY ERANGE FE_OVERFLOW
-3e38f Domain NAN EDOM FE_INVALID Pole +INFINITY ERANGE FE_DIVBYZERO
-1.7e308 Domain NAN EDOM FE_INVALID Pole +INFINITY ERANGE FE_DIVBYZERO
+inf None +INFINITY 0 0 None +INFINITY 0 0
-inf Domain NAN EDOM FE_INVALID None +INFINITY 0 0
I have rationalized the differences in this way:
Domain error means there is no defined limit for the function
approaching the parameter. Pole error means that there *is* a
defined limit in this case.
For non-positive inputs, the limit of the value of the tgamma
function depends on whether that limit is approached from above
or below.
For zero, we can separate out 'approach from below' and
'approach from above' with the sign -- -0 might well be the
result of an underflow from below, hence returning the value of
the function as approached from below makes "sense", in this
case -INFINITY. Similarly, +0 might well be underflow from
above, so the function can return +INFINITY. In both cases, as
the limit is well defined, this represents a Pole error rather
than a Domain error, hence the differences in errno and exceptions.
For negative integers, as the limit depends on whether the value
is approached from below or above and we have no way of
distinguishing these two cases from the input, the limit is not
well defined, so we have a Domain error and return
NAN/EDOM/FE_INVALID.
For the lgamma function, the limit for non-positive integers is
always +INFINITY because it returns ln(|Γ(x)|). This makes it
well defined and hence a Pole error rather than a Domain error
Huge negative values (-1e308) are negative integers, and hence
treated that way, generating a Domain error for tgamma and Range
error for lgamma
+INFINITY input and +INFINITY output generate *no* error
presumably because there's an assumption that the computation
which resulted in +INFINITY being provided to these functions
already raised a FE_OVERFLOW exception, and perhaps an ERANGE
errno.
Please review the table above to see if you agree about what errno and
exception values each of the provided inputs should generate. I'd really
like to know if you can suggest additional test cases to use to validate
the correctness of these functions.
--
-keith
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Fw: [PATCH 0/3] libm: Clean up gamma functions
2020-08-28 3:13 ` Keith Packard
@ 2020-08-28 3:51 ` Brian Inglis
2020-08-28 17:13 ` Keith Packard
2020-08-28 18:29 ` Joseph Myers
1 sibling, 1 reply; 34+ messages in thread
From: Brian Inglis @ 2020-08-28 3:51 UTC (permalink / raw)
To: newlib
[-- Attachment #1.1: Type: text/plain, Size: 6370 bytes --]
On 2020-08-27 21:13, Keith Packard wrote:
> Brian Inglis writes:
>
>> Last C17 public FDIS N2176 is available via:
>>
>> https://web.archive.org/web/20181230041359if_/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf
>>
>> see 7.12.8.3 lgamma and 7.12.8.4 tgamma on pp181-182, 7.26 tgmath #5 lgamma,
>> tgamma pp272-273, 7.31.1 complex clgamma, ctgamma p332, F10.5.3 lgamma and
>> F.10.5.4 tgamma.
>
> Thanks for the link -- the difference for lgamma is that in C99:
>
> A range error occurs if x is too large. A range error may occur
> if x is a negative integer or zero.
>
> While in C17:
>
> A range error occurs if positive x is too large. A pole error
> may occur if x is a negative integer or zero.
>
> Frustratingly, tgamma still returns different errors. In C99:
>
> A domain error or range error may occur if x is a negative
> integer or zero. A range error may occur if the magnitude of x
> is too large or too small.
>
> While in C17:
>
> A domain error or pole error may occur if x is a negative
> integer or zero. A range error occurs if the magnitude of x is
> too large and may occur if the magnitude of x is too small.
>
> C17 appears to have added this new 'pole' error, which seems to match
> what the IEEE 754 calls a 'divideByZero exception'. Let's see if my
> understanding of the various errors is correct:
>
> IEEE C17 POSIX errno Exception
> divideByZero Pole Pole ERANGE FE_DIVBYZERO
> invalid Domain Domain EDOM FE_INVALID
> overflow Range Range ERANGE FE_OVERFLOW
>
> POSIX is more specific than C17, but it does appear to have been updated
> to follow that spec, including the term 'Pole Error' which wasn't in
> C99.
>
> As my tests all refer to the POSIX spec (which defines the
> errno/exception values), I think they're correct. Here's the set of
> values I'm testing for both tgamma and lgamma (I'm not testing gamma
> currently; we need to sort out what it should be doing first):
>
> Value tgamma lgamma
> POSIX result errno exception POSIX result errno exception
>
> +0 Pole +INFINITY ERANGE FE_DIVBYZERO Pole +INFINITY ERANGE FE_DIVBYZERO
> -0 Pole -INFINITY ERANGE FE_DIVBYZERO Pole +INFINITY ERANGE FE_DIVBYZERO
> -1 Domain NAN EDOM FE_INVALID Pole +INFINITY ERANGE FE_DIVBYZERO
> +3e38f Range +INFINITY ERANGE FE_OVERFLOW Range +INFINITY ERANGE FE_OVERFLOW
> +1.7e308 Range +INFINITY ERANGE FE_OVERFLOW Range +INFINITY ERANGE FE_OVERFLOW
> -3e38f Domain NAN EDOM FE_INVALID Pole +INFINITY ERANGE FE_DIVBYZERO
> -1.7e308 Domain NAN EDOM FE_INVALID Pole +INFINITY ERANGE FE_DIVBYZERO
> +inf None +INFINITY 0 0 None +INFINITY 0 0
> -inf Domain NAN EDOM FE_INVALID None +INFINITY 0 0
>
> I have rationalized the differences in this way:
>
> Domain error means there is no defined limit for the function
> approaching the parameter. Pole error means that there *is* a
> defined limit in this case.
>
> For non-positive inputs, the limit of the value of the tgamma
> function depends on whether that limit is approached from above
> or below.
>
> For zero, we can separate out 'approach from below' and
> 'approach from above' with the sign -- -0 might well be the
> result of an underflow from below, hence returning the value of
> the function as approached from below makes "sense", in this
> case -INFINITY. Similarly, +0 might well be underflow from
> above, so the function can return +INFINITY. In both cases, as
> the limit is well defined, this represents a Pole error rather
> than a Domain error, hence the differences in errno and exceptions.
>
> For negative integers, as the limit depends on whether the value
> is approached from below or above and we have no way of
> distinguishing these two cases from the input, the limit is not
> well defined, so we have a Domain error and return
> NAN/EDOM/FE_INVALID.
>
> For the lgamma function, the limit for non-positive integers is
> always +INFINITY because it returns ln(|Γ(x)|). This makes it
> well defined and hence a Pole error rather than a Domain error
>
> Huge negative values (-1e308) are negative integers, and hence
> treated that way, generating a Domain error for tgamma and Range
> error for lgamma
>
> +INFINITY input and +INFINITY output generate *no* error
> presumably because there's an assumption that the computation
> which resulted in +INFINITY being provided to these functions
> already raised a FE_OVERFLOW exception, and perhaps an ERANGE
> errno.
>
> Please review the table above to see if you agree about what errno and
> exception values each of the provided inputs should generate. I'd really
> like to know if you can suggest additional test cases to use to validate
> the correctness of these functions.
I don't get so don't do maths above my comfort level: but it is possible that
ORs in the specs could mean that some important implementations (e.g BSD and
glibc) may differ in errors reported depending on which, possibly different,
exceptional input values are passed. You could check the BSD and glibc specs and
tests for these functions to see what the expected outputs are for what inputs,
what exceptional values generate which errno values, and whether all
possibilities are allowed by all the specs. POSIX always defers to C where the
latter defines library implementations, but as long as they do not contradict
normative content, POSIX may add additional conditions or requirements.
--
Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada
This email may be disturbing to some readers as it contains
too much technical detail. Reader discretion is advised.
[Data in IEC units and prefixes, physical quantities in SI.]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
2020-08-27 17:05 ` Keith Packard
@ 2020-08-28 8:19 ` Corinna Vinschen
2020-08-28 8:34 ` Corinna Vinschen
0 siblings, 1 reply; 34+ messages in thread
From: Corinna Vinschen @ 2020-08-28 8:19 UTC (permalink / raw)
To: newlib
On Aug 27 10:05, Keith Packard via Newlib wrote:
> Corinna Vinschen via Newlib <newlib@sourceware.org> writes:
>
> > Nevertheless, the symbols have to be exported for backward compatibility.
> > So you're saying aliasing gamma_r to lgamma_r and gammaf_r to lgammaf_r
> > in the DLLs export table would be sufficient?
>
> It depends if you want the pre-2002 functionality or the post-2002
> functionality.
The important point is that gamma_r and gammaf_r are exported by Cygwin
and must be kept available, otherwise building the DLL fails. If they
returned the wrong vaslue, that's a bug and needs fixing.
Whether gamma_r and gammaf_r are still functions on their own, or if
they are just defined as aliases to lgamma_r and lgammaf_r in
winsup/cygwin/common.din, as in
gamma_r = lgamma_r NOSIGFE
gammaf_r = lgammaf_r NOSIGFE
is up to you.
Corinna
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
2020-08-28 8:19 ` Corinna Vinschen
@ 2020-08-28 8:34 ` Corinna Vinschen
2020-09-01 16:33 ` Fabian Schriever
0 siblings, 1 reply; 34+ messages in thread
From: Corinna Vinschen @ 2020-08-28 8:34 UTC (permalink / raw)
To: newlib
On Aug 28 10:19, Corinna Vinschen via Newlib wrote:
> On Aug 27 10:05, Keith Packard via Newlib wrote:
> > Corinna Vinschen via Newlib <newlib@sourceware.org> writes:
> >
> > > Nevertheless, the symbols have to be exported for backward compatibility.
> > > So you're saying aliasing gamma_r to lgamma_r and gammaf_r to lgammaf_r
> > > in the DLLs export table would be sufficient?
> >
> > It depends if you want the pre-2002 functionality or the post-2002
> > functionality.
>
> The important point is that gamma_r and gammaf_r are exported by Cygwin
> and must be kept available, otherwise building the DLL fails. If they
> returned the wrong vaslue, that's a bug and needs fixing.
>
> Whether gamma_r and gammaf_r are still functions on their own, or if
> they are just defined as aliases to lgamma_r and lgammaf_r in
> winsup/cygwin/common.din, as in
>
> gamma_r = lgamma_r NOSIGFE
> gammaf_r = lgammaf_r NOSIGFE
>
> is up to you.
On second thought, given gamma_r and gammaf_r are BSD functions,
it might be a good idea to keep the wrapper functions for other
targets as well.
Any input from the RTEMS guys, perhaps?
Thanks,
Corinna
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Fw: [PATCH 0/3] libm: Clean up gamma functions
2020-08-28 3:51 ` Brian Inglis
@ 2020-08-28 17:13 ` Keith Packard
0 siblings, 0 replies; 34+ messages in thread
From: Keith Packard @ 2020-08-28 17:13 UTC (permalink / raw)
To: Brian Inglis, newlib
[-- Attachment #1: Type: text/plain, Size: 1366 bytes --]
Brian Inglis <Brian.Inglis@SystematicSw.ab.ca> writes:
> I don't get so don't do maths above my comfort level: but it is possible that
> ORs in the specs could mean that some important implementations (e.g BSD and
> glibc) may differ in errors reported depending on which, possibly different,
> exceptional input values are passed. You could check the BSD and glibc specs and
> tests for these functions to see what the expected outputs are for what inputs,
> what exceptional values generate which errno values, and whether all
> possibilities are allowed by all the specs. POSIX always defers to C where the
> latter defines library implementations, but as long as they do not contradict
> normative content, POSIX may add additional conditions or
> requirements.
Yeah, my testing could be more permissive to allow any valid
implementation to pass. Right now, I'm interested in making newlib
compliant with the relevant specs and, where that doesn't conflict,
compatible with glibc. And that means having hard requirements that
match glibc -- I haven't found any places where glibc gets the wrong
answer at least...
There's one place where that's a bit hard -- the gamma function has
changed meaning over time and the current newlib gamma implementation
is closer to the BSD one than glibc, but implements neither exactly.
--
-keith
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Fw: [PATCH 0/3] libm: Clean up gamma functions
2020-08-28 3:13 ` Keith Packard
2020-08-28 3:51 ` Brian Inglis
@ 2020-08-28 18:29 ` Joseph Myers
2020-08-28 19:32 ` Keith Packard
1 sibling, 1 reply; 34+ messages in thread
From: Joseph Myers @ 2020-08-28 18:29 UTC (permalink / raw)
To: Keith Packard; +Cc: Brian Inglis, newlib
On Thu, 27 Aug 2020, Keith Packard via Newlib wrote:
> +INFINITY input and +INFINITY output generate *no* error
> presumably because there's an assumption that the computation
> which resulted in +INFINITY being provided to these functions
> already raised a FE_OVERFLOW exception, and perhaps an ERANGE
> errno.
The basic principles for infinite results from IEEE floating-point
operations and libm functions are that overflow is when infinity is an
*inexact* result from rounding (or, in some rounding modes, the largest
finite value results from rounding but rounding with infinite exponent
range would have produced an exponent that could not be represented in the
actual format). Divide by zero is when infinity is an *exact* result from
*finite* arguments. If infinity is an exact result and at least one
argument is infinite, there is no error or exception (unless it's some of
the new minimum/maximum operations in IEEE 754-2019 and the other argument
is a signaling NaN).
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Fw: [PATCH 0/3] libm: Clean up gamma functions
2020-08-28 18:29 ` Joseph Myers
@ 2020-08-28 19:32 ` Keith Packard
2020-08-28 19:53 ` Joseph Myers
0 siblings, 1 reply; 34+ messages in thread
From: Keith Packard @ 2020-08-28 19:32 UTC (permalink / raw)
To: Joseph Myers; +Cc: Brian Inglis, newlib
[-- Attachment #1: Type: text/plain, Size: 800 bytes --]
Joseph Myers <joseph@codesourcery.com> writes:
> If infinity is an exact result and at least one
> argument is infinite, there is no error or exception (unless it's some of
> the new minimum/maximum operations in IEEE 754-2019 and the other argument
> is a signaling NaN).
Thanks for the clarification. That all seems consistent, and I think I
can now (mostly) understand how the POSIX error values relate back to
the IEEE 754-2019 specification.
I do wonder if POSIX will add the new minimum/maximum operations; they
seem more like what I expect wrt NaN handling than the existing
minimumNumber/fmin maximumNumber/fmax operations.
Any other concerns about the testing values I'm using? Should we adopt
the newlib patches necessary to have it pass those tests?
--
-keith
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: Fw: [PATCH 0/3] libm: Clean up gamma functions
2020-08-28 19:32 ` Keith Packard
@ 2020-08-28 19:53 ` Joseph Myers
0 siblings, 0 replies; 34+ messages in thread
From: Joseph Myers @ 2020-08-28 19:53 UTC (permalink / raw)
To: Keith Packard; +Cc: newlib
On Fri, 28 Aug 2020, Keith Packard via Newlib wrote:
> I do wonder if POSIX will add the new minimum/maximum operations; they
> seem more like what I expect wrt NaN handling than the existing
> minimumNumber/fmin maximumNumber/fmax operations.
C bindings for the new operations are given in
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2532.pdf - but the target
completion date for the next revision of POSIX (2022) is before that for
C2x (publication aiming for 2023), so the next revision of POSIX is more
likely to have only features from the 2011/2018 edition of ISO C.
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
2020-08-28 8:34 ` Corinna Vinschen
@ 2020-09-01 16:33 ` Fabian Schriever
2020-09-01 17:23 ` Keith Packard
0 siblings, 1 reply; 34+ messages in thread
From: Fabian Schriever @ 2020-09-01 16:33 UTC (permalink / raw)
To: newlib
Hi Keith,
We welcome your efforts to clean up - and correct the error return
values of - the gamma/lgamma/tgamma families.
Regarding Corinna's concern with lgamma_r/gamma_r being BSD-functions:
> You can't do that. gamma_r/gammaf_r/lgamma_r/lgammaf_r are BSD
> functions. They have been exported by Cygwin since 2001. The entry
> points need to be kept available with unchanged semantics.
We would favor the removal of all non C/POSIX(+XSI)-standard functions
from the interface.
The reason to regard lgamma_r and gamma_r as "BSD-functions" comes from
the fact that BSD (same as newlib) took fdlibm as the base for its libm
back in the early 90s when some non-standard functions were part of that
library.
We would encourage the use of only the C/POSIX(+XSI)-standard functions
as the only way to get rid of the confusing semantics of the historical
function interfaces otherwise the problem will only perpetuate into the
future.
If something was changed in 2002, that is working incorrectly and no one
found out until now, that is also not part of any standard, it suggests
that no one is actually using it and should be able to be safely
removed. Does Newlib have a policy to remove elements?
An interesting discussion about the standard lgamma/tgamma functions
would be to discuss accuracy improvements in line with the glibc
improvements from Joseph Myers (see
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=050f29c18873ec05ba04a4034bed8cb3f6ae4463).
Best regards,
Fabian
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
2020-09-01 16:33 ` Fabian Schriever
@ 2020-09-01 17:23 ` Keith Packard
2020-09-02 8:03 ` Corinna Vinschen
0 siblings, 1 reply; 34+ messages in thread
From: Keith Packard @ 2020-09-01 17:23 UTC (permalink / raw)
To: Fabian Schriever, newlib
[-- Attachment #1: Type: text/plain, Size: 2033 bytes --]
Fabian Schriever <fabian.schriever@gtd-gmbh.de> writes:
> Hi Keith,
>
> We welcome your efforts to clean up - and correct the error return
> values of - the gamma/lgamma/tgamma families.
Thanks! I'm doing continuous integration testing as a part of embedded
toolchain support for RISC-V as part of my SiFive dayjob; fixing bugs
like this is part of that process.
> We would favor the removal of all non C/POSIX(+XSI)-standard functions
> from the interface.
Oh, that's probably the best idea of all. Applications should not be
using 'gamma' at all given the different definitions over time and
space.
Any thoughts about the newlib __ieee754 interfaces? Those are
essentially the same as the C/POSIX interfaces but do not use errno or
other global variables, reporting exceptions only through the fenv API.
> If something was changed in 2002, that is working incorrectly and no one
> found out until now, that is also not part of any standard, it suggests
> that no one is actually using it and should be able to be safely
> removed. Does Newlib have a policy to remove elements?
I don't think it's 'newlib' which would need any policy; newlib is used
downstream in a wide variety of projects, including cygwin and picolibc,
which may have separate policies. Cygwin has binary interface
definitions, changing those could affect applications there.
I'm using newlib as part of picolibc which is used for embedded
toolchains where removing things from the ABI to fix bugs would be just
fine.
> An interesting discussion about the standard lgamma/tgamma functions
> would be to discuss accuracy improvements in line with the glibc
> improvements from Joseph Myers (see
> https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=050f29c18873ec05ba04a4034bed8cb3f6ae4463).
I read through that patch and agree that it would be nice to incorporate
something similar. We need to be cautious as code cannot be directly
brought in from glibc due to licensing differences.
--
-keith
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
2020-09-01 17:23 ` Keith Packard
@ 2020-09-02 8:03 ` Corinna Vinschen
2020-09-02 20:37 ` Keith Packard
0 siblings, 1 reply; 34+ messages in thread
From: Corinna Vinschen @ 2020-09-02 8:03 UTC (permalink / raw)
To: newlib
On Sep 1 10:23, Keith Packard via Newlib wrote:
> Fabian Schriever <fabian.schriever@gtd-gmbh.de> writes:
>
> > Hi Keith,
> >
> > We welcome your efforts to clean up - and correct the error return
> > values of - the gamma/lgamma/tgamma families.
>
> Thanks! I'm doing continuous integration testing as a part of embedded
> toolchain support for RISC-V as part of my SiFive dayjob; fixing bugs
> like this is part of that process.
>
> > We would favor the removal of all non C/POSIX(+XSI)-standard functions
> > from the interface.
>
> Oh, that's probably the best idea of all. Applications should not be
> using 'gamma' at all given the different definitions over time and
> space.
>
> Any thoughts about the newlib __ieee754 interfaces? Those are
> essentially the same as the C/POSIX interfaces but do not use errno or
> other global variables, reporting exceptions only through the fenv API.
>
> > If something was changed in 2002, that is working incorrectly and no one
> > found out until now, that is also not part of any standard, it suggests
> > that no one is actually using it and should be able to be safely
> > removed. Does Newlib have a policy to remove elements?
>
> I don't think it's 'newlib' which would need any policy; newlib is used
> downstream in a wide variety of projects, including cygwin and picolibc,
> which may have separate policies. Cygwin has binary interface
> definitions, changing those could affect applications there.
Removing interfaces is not an option for Cygwin. If you remove
functions from newlib exported as symbols in Cygwin, you must provide
replacement interfaces for Cygwin alone, otherwise Cygwin won't build
anymore. And one step further, removing interfaces from the list of
exported symbols of the Cygwin DLL will break user space and that's
simply a no-no.
Corinna
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
2020-09-02 8:03 ` Corinna Vinschen
@ 2020-09-02 20:37 ` Keith Packard
2020-09-03 8:04 ` Corinna Vinschen
0 siblings, 1 reply; 34+ messages in thread
From: Keith Packard @ 2020-09-02 20:37 UTC (permalink / raw)
To: Corinna Vinschen via Newlib, newlib; +Cc: Corinna Vinschen
[-- Attachment #1: Type: text/plain, Size: 824 bytes --]
Corinna Vinschen via Newlib <newlib@sourceware.org> writes:
> Removing interfaces is not an option for Cygwin. If you remove
> functions from newlib exported as symbols in Cygwin, you must provide
> replacement interfaces for Cygwin alone, otherwise Cygwin won't build
> anymore. And one step further, removing interfaces from the list of
> exported symbols of the Cygwin DLL will break user space and that's
> simply a no-no.
Then tell us what you want gamma and gamma_r to do for Cygwin. They're
non-standard interfaces for POSIX, C99 and C17, so you get to
pick.
Removing them for non-Cygwin uses appears to be the safest choice as
that will (intentionally) break applications which were expecting them
to implement either the BSD or Linux behavior, when in fact they do
neither (!).
--
-keith
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
2020-09-02 20:37 ` Keith Packard
@ 2020-09-03 8:04 ` Corinna Vinschen
2020-09-03 15:59 ` Brian Inglis
0 siblings, 1 reply; 34+ messages in thread
From: Corinna Vinschen @ 2020-09-03 8:04 UTC (permalink / raw)
To: newlib
On Sep 2 13:37, Keith Packard via Newlib wrote:
> Corinna Vinschen via Newlib <newlib@sourceware.org> writes:
>
> > Removing interfaces is not an option for Cygwin. If you remove
> > functions from newlib exported as symbols in Cygwin, you must provide
> > replacement interfaces for Cygwin alone, otherwise Cygwin won't build
> > anymore. And one step further, removing interfaces from the list of
> > exported symbols of the Cygwin DLL will break user space and that's
> > simply a no-no.
>
> Then tell us what you want gamma and gamma_r to do for Cygwin.
I did: https://sourceware.org/pipermail/newlib/2020/017946.html
Thanks,
Corinna
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
2020-09-03 8:04 ` Corinna Vinschen
@ 2020-09-03 15:59 ` Brian Inglis
2020-09-03 21:25 ` Keith Packard
0 siblings, 1 reply; 34+ messages in thread
From: Brian Inglis @ 2020-09-03 15:59 UTC (permalink / raw)
To: newlib
On 2020-09-03 02:04, Corinna Vinschen via Newlib wrote:
> On Sep 2 13:37, Keith Packard via Newlib wrote:
>> Corinna Vinschen via Newlib <newlib@sourceware.org> writes:
>>
>>> Removing interfaces is not an option for Cygwin. If you remove
>>> functions from newlib exported as symbols in Cygwin, you must provide
>>> replacement interfaces for Cygwin alone, otherwise Cygwin won't build
>>> anymore. And one step further, removing interfaces from the list of
>>> exported symbols of the Cygwin DLL will break user space and that's
>>> simply a no-no.
>>
>> Then tell us what you want gamma and gamma_r to do for Cygwin.
>
> I did: https://sourceware.org/pipermail/newlib/2020/017946.html
FYI docs/spec:
https://sca.uwaterloo.ca/coldfire/gcc-doc/docs/libm_21.html#SEC21
http://www.ece.ualberta.ca/~cmpe401/docs/coldfire/libm.pdf#page=20
https://ftp.rtems.org/pub/rtems/docs/3.2.0/libm-3.2.0.ps - see p.18
--
Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada
This email may be disturbing to some readers as it contains
too much technical detail. Reader discretion is advised.
[Data in IEC units and prefixes, physical quantities in SI.]
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
2020-09-03 15:59 ` Brian Inglis
@ 2020-09-03 21:25 ` Keith Packard
2020-09-03 22:09 ` Brian Inglis
0 siblings, 1 reply; 34+ messages in thread
From: Keith Packard @ 2020-09-03 21:25 UTC (permalink / raw)
To: Brian Inglis, newlib
[-- Attachment #1: Type: text/plain, Size: 950 bytes --]
Brian Inglis <Brian.Inglis@SystematicSw.ab.ca> writes:
>>> Then tell us what you want gamma and gamma_r to do for Cygwin.
>>
>> I did: https://sourceware.org/pipermail/newlib/2020/017946.html
Oops! I appear to have missed that mail.
> FYI docs/spec:
> https://sca.uwaterloo.ca/coldfire/gcc-doc/docs/libm_21.html#SEC21
> http://www.ece.ualberta.ca/~cmpe401/docs/coldfire/libm.pdf#page=20
> https://ftp.rtems.org/pub/rtems/docs/3.2.0/libm-3.2.0.ps - see p.18
That's quite helpful actually and says that cygwin's gamma matches
glibc, which makes the change from 2002 just a bug. Switching gamma back
to lgamma is quite simple.
Here's what I did:
1. Remove the gamma* function implementations and make them explicit
aliases to lgamma*.
2. Change the name of the __ieee754_gamma* functions to
__ieee754_tgamma* and remove the _ieee754_gamma*_r variants
I've sent a patch doing this to the list.
--
-keith
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
2020-09-03 21:25 ` Keith Packard
@ 2020-09-03 22:09 ` Brian Inglis
2020-09-04 0:01 ` Keith Packard
0 siblings, 1 reply; 34+ messages in thread
From: Brian Inglis @ 2020-09-03 22:09 UTC (permalink / raw)
To: newlib
[-- Attachment #1.1: Type: text/plain, Size: 2109 bytes --]
On 2020-09-03 15:25, Keith Packard wrote:
> Brian Inglis <Brian.Inglis@SystematicSw.ab.ca> writes:
>
>>>> Then tell us what you want gamma and gamma_r to do for Cygwin.
>>>
>>> I did: https://sourceware.org/pipermail/newlib/2020/017946.html
>
> Oops! I appear to have missed that mail.
>
>> FYI docs/spec:
>> https://sca.uwaterloo.ca/coldfire/gcc-doc/docs/libm_21.html#SEC21
>> http://www.ece.ualberta.ca/~cmpe401/docs/coldfire/libm.pdf#page=20
>> https://ftp.rtems.org/pub/rtems/docs/3.2.0/libm-3.2.0.ps - see p.18
>
> That's quite helpful actually and says that cygwin's gamma matches
> glibc, which makes the change from 2002 just a bug. Switching gamma back
> to lgamma is quite simple.
>
> Here's what I did:
>
> 1. Remove the gamma* function implementations and make them explicit
> aliases to lgamma*.
>
> 2. Change the name of the __ieee754_gamma* functions to
> __ieee754_tgamma* and remove the _ieee754_gamma*_r variants
>
> I've sent a patch doing this to the list.
I don't think you can "remove the _ieee754_gamma*_r variants" as I believe
Cygwin has to keep these:
$ nm --defined-only --extern-only /bin/cygwin1.dll | fgrep gamma
00000001801a76c0 T __ieee754_gamma_r
00000001801a7f90 T __ieee754_gammaf_r
00000001801a76e0 T __ieee754_lgamma_r
00000001801a7fb0 T __ieee754_lgammaf_r
000000018018a8c0 T __lgammal_r
000000018018ce10 T __tgammal_r
000000018019f690 T gamma
00000001801a0a40 T gamma_r
00000001801a0200 T gammaf
00000001801a0b80 T gammaf_r
000000018019fb00 T lgamma
00000001801a0ae0 T lgamma_r
00000001801a0660 T lgammaf
00000001801a0c20 T lgammaf_r
000000018018ae10 T lgammal
000000018018ae90 T lgammal_r
000000018019fe50 T tgamma
00000001801a0970 T tgammaf
000000018018d290 T tgammal
although I don't have the Windows utilities to check the exports directly.
--
Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada
This email may be disturbing to some readers as it contains
too much technical detail. Reader discretion is advised.
[Data in IEC units and prefixes, physical quantities in SI.]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
2020-09-03 22:09 ` Brian Inglis
@ 2020-09-04 0:01 ` Keith Packard
2020-09-04 0:27 ` Brian Inglis
0 siblings, 1 reply; 34+ messages in thread
From: Keith Packard @ 2020-09-04 0:01 UTC (permalink / raw)
To: Brian Inglis, newlib
[-- Attachment #1: Type: text/plain, Size: 344 bytes --]
Brian Inglis <Brian.Inglis@SystematicSw.ab.ca> writes:
> I don't think you can "remove the _ieee754_gamma*_r variants" as I believe
> Cygwin has to keep these:
I added a note to that effect in my patch email; if someone can let me
know, I'll add them back in. I'd prefer to leave them out if they aren't
needed though.
--
-keith
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
2020-09-04 0:01 ` Keith Packard
@ 2020-09-04 0:27 ` Brian Inglis
2020-09-04 1:37 ` Keith Packard
0 siblings, 1 reply; 34+ messages in thread
From: Brian Inglis @ 2020-09-04 0:27 UTC (permalink / raw)
To: newlib
[-- Attachment #1.1: Type: text/plain, Size: 995 bytes --]
On 2020-09-03 18:01, Keith Packard wrote:
> Brian Inglis <Brian.Inglis@SystematicSw.ab.ca> writes:
>
>> I don't think you can "remove the _ieee754_gamma*_r variants" as I believe
>> Cygwin has to keep these:
>
> I added a note to that effect in my patch email; if someone can let me
> know, I'll add them back in. I'd prefer to leave them out if they aren't
> needed though.
$ fgrep gamma newlib-cygwin/winsup/cygwin/common.din
and
$ fgrep gamma newlib-cygwin/x86_64-pc-cygwin/winsup/cygwin/cygwin.def
have the same 13 function names:
gamma
gamma_r
gammaf
gammaf_r
lgamma
lgamma_r
lgammaf
lgammaf_r
lgammal
lgammal_r
tgamma
tgammaf
tgammal
so these may be the official ABI, and the others don't matter?
--
Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada
This email may be disturbing to some readers as it contains
too much technical detail. Reader discretion is advised.
[Data in IEC units and prefixes, physical quantities in SI.]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
2020-09-04 0:27 ` Brian Inglis
@ 2020-09-04 1:37 ` Keith Packard
2020-09-04 13:03 ` Corinna Vinschen
0 siblings, 1 reply; 34+ messages in thread
From: Keith Packard @ 2020-09-04 1:37 UTC (permalink / raw)
To: Brian Inglis, newlib
[-- Attachment #1: Type: text/plain, Size: 485 bytes --]
Brian Inglis <Brian.Inglis@SystematicSw.ab.ca> writes:
> gamma
> gamma_r
> gammaf
> gammaf_r
> lgamma
> lgamma_r
> lgammaf
> lgammaf_r
> lgammal
> lgammal_r
> tgamma
> tgammaf
> tgammal
>
> so these may be the official ABI, and the others don't matter?
I would hope so -- the __ieee754 functions seem mostly like an internal
implementation detail, but it's hard to know.
If this is true, then I think the patch as posted should be what we want.
--
-keith
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
2020-09-04 1:37 ` Keith Packard
@ 2020-09-04 13:03 ` Corinna Vinschen
2020-09-04 16:19 ` Keith Packard
0 siblings, 1 reply; 34+ messages in thread
From: Corinna Vinschen @ 2020-09-04 13:03 UTC (permalink / raw)
To: newlib
On Sep 3 18:37, Keith Packard via Newlib wrote:
> Brian Inglis <Brian.Inglis@SystematicSw.ab.ca> writes:
>
> > gamma
> > gamma_r
> > gammaf
> > gammaf_r
> > lgamma
> > lgamma_r
> > lgammaf
> > lgammaf_r
> > lgammal
> > lgammal_r
> > tgamma
> > tgammaf
> > tgammal
> >
> > so these may be the official ABI, and the others don't matter?
>
> I would hope so -- the __ieee754 functions seem mostly like an internal
> implementation detail, but it's hard to know.
>
> If this is true, then I think the patch as posted should be what we want.
The ieee functions can go away. The symbols from cygwin1.dll don't
count, the ones exported from /usr/lib/libcygwin.a do. These are
defined in winsup/cygwin/{common.din,i686.din,x86_64.din}
Corinna
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 2/3] libm: Remove __ieee754_gamma_r variants
2020-09-04 13:03 ` Corinna Vinschen
@ 2020-09-04 16:19 ` Keith Packard
0 siblings, 0 replies; 34+ messages in thread
From: Keith Packard @ 2020-09-04 16:19 UTC (permalink / raw)
To: Corinna Vinschen via Newlib, newlib; +Cc: Corinna Vinschen
[-- Attachment #1: Type: text/plain, Size: 317 bytes --]
Corinna Vinschen via Newlib <newlib@sourceware.org> writes:
> The ieee functions can go away. The symbols from cygwin1.dll don't
> count, the ones exported from /usr/lib/libcygwin.a do. These are
> defined in winsup/cygwin/{common.din,i686.din,x86_64.din}
Which matches what we had guessed.
--
-keith
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 34+ messages in thread
end of thread, other threads:[~2020-09-04 16:19 UTC | newest]
Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-26 17:03 [PATCH 0/3] libm: Clean up gamma functions Keith Packard
2020-08-26 17:03 ` [PATCH 1/3] libm: Fix sign value returned from __ieee754_lgamma*_r(-0) Keith Packard
2020-08-26 17:03 ` [PATCH 2/3] libm: Remove __ieee754_gamma_r variants Keith Packard
2020-08-26 18:20 ` Corinna Vinschen
2020-08-26 19:10 ` Keith Packard
2020-08-27 7:24 ` Corinna Vinschen
2020-08-27 17:05 ` Keith Packard
2020-08-28 8:19 ` Corinna Vinschen
2020-08-28 8:34 ` Corinna Vinschen
2020-09-01 16:33 ` Fabian Schriever
2020-09-01 17:23 ` Keith Packard
2020-09-02 8:03 ` Corinna Vinschen
2020-09-02 20:37 ` Keith Packard
2020-09-03 8:04 ` Corinna Vinschen
2020-09-03 15:59 ` Brian Inglis
2020-09-03 21:25 ` Keith Packard
2020-09-03 22:09 ` Brian Inglis
2020-09-04 0:01 ` Keith Packard
2020-09-04 0:27 ` Brian Inglis
2020-09-04 1:37 ` Keith Packard
2020-09-04 13:03 ` Corinna Vinschen
2020-09-04 16:19 ` Keith Packard
2020-08-26 17:03 ` [PATCH 3/3] libm: Adjust errno/exception values for gamma/lgamma Keith Packard
[not found] ` <SN5P110MB0383012287522E8285674CAB9A550@SN5P110MB0383.NAMP110.PROD.OUTLOOK.COM>
2020-08-27 17:55 ` Fw: " C Howland
2020-08-27 19:28 ` Brian Inglis
[not found] ` <SN5P110MB0383186ECD9B028A4B0E2ECC9A550@SN5P110MB0383.NAMP110.PROD.OUTLOOK.COM>
2020-08-27 17:43 ` Fw: [PATCH 0/3] libm: Clean up gamma functions C Howland
2020-08-27 23:59 ` Keith Packard
2020-08-28 2:03 ` Brian Inglis
2020-08-28 3:13 ` Keith Packard
2020-08-28 3:51 ` Brian Inglis
2020-08-28 17:13 ` Keith Packard
2020-08-28 18:29 ` Joseph Myers
2020-08-28 19:32 ` Keith Packard
2020-08-28 19:53 ` Joseph Myers
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).