aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/ieee754
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2015-09-17 15:51:54 +0000
committerJoseph Myers <joseph@codesourcery.com>2015-09-17 15:51:54 +0000
commit46f74e1deee549b41160d353ce0c8f7db555d36c (patch)
tree19f07ad8fb51bb5e8de5106dc98654e7817eb04e /sysdeps/ieee754
parente67dc1b57f1fc8407cb45bdb38ae1eaa0a5c6f78 (diff)
downloadglibc-46f74e1deee549b41160d353ce0c8f7db555d36c.tar
glibc-46f74e1deee549b41160d353ce0c8f7db555d36c.tar.gz
glibc-46f74e1deee549b41160d353ce0c8f7db555d36c.tar.bz2
glibc-46f74e1deee549b41160d353ce0c8f7db555d36c.zip
Fix tgamma missing underflows (bug 18951).
Similar to various other bugs in this area, tgamma functions can fail to raise the underflow exception when the result is tiny and inexact but one or more low bits of the intermediate result that is scaled down are zero. This patch forces the exception in a similar way to previous fixes. Tested for x86_64, x86, mips64 and powerpc. [BZ #18951] * sysdeps/ieee754/dbl-64/e_gamma_r.c (__ieee754_gamma_r): Force underflow exception for small results. * sysdeps/ieee754/flt-32/e_gammaf_r.c (__ieee754_gammaf_r): Likewise. * sysdeps/ieee754/ldbl-128/e_gammal_r.c (__ieee754_gammal_r): Likewise. * sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c (__ieee754_gammal_r): Likewise. * sysdeps/ieee754/ldbl-96/e_gammal_r.c (__ieee754_gammal_r): Likewise. * math/auto-libm-test-in: Add more tests of tgamma. * math/auto-libm-test-out: Regenerated.
Diffstat (limited to 'sysdeps/ieee754')
-rw-r--r--sysdeps/ieee754/dbl-64/e_gamma_r.c5
-rw-r--r--sysdeps/ieee754/flt-32/e_gammaf_r.c5
-rw-r--r--sysdeps/ieee754/ldbl-128/e_gammal_r.c5
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c5
-rw-r--r--sysdeps/ieee754/ldbl-96/e_gammal_r.c5
5 files changed, 25 insertions, 0 deletions
diff --git a/sysdeps/ieee754/dbl-64/e_gamma_r.c b/sysdeps/ieee754/dbl-64/e_gamma_r.c
index adeb61a248..d1acaa6a12 100644
--- a/sysdeps/ieee754/dbl-64/e_gamma_r.c
+++ b/sysdeps/ieee754/dbl-64/e_gamma_r.c
@@ -194,6 +194,11 @@ __ieee754_gamma_r (double x, int *signgamp)
double tret = M_PI / (-x * sinpix
* gamma_positive (-x, &exp2_adj));
ret = __scalbn (tret, -exp2_adj);
+ if (ret < DBL_MIN)
+ {
+ double force_underflow = ret * ret;
+ math_force_eval (force_underflow);
+ }
}
}
}
diff --git a/sysdeps/ieee754/flt-32/e_gammaf_r.c b/sysdeps/ieee754/flt-32/e_gammaf_r.c
index 29fe8b46c2..250e412aa7 100644
--- a/sysdeps/ieee754/flt-32/e_gammaf_r.c
+++ b/sysdeps/ieee754/flt-32/e_gammaf_r.c
@@ -186,6 +186,11 @@ __ieee754_gammaf_r (float x, int *signgamp)
float tret = (float) M_PI / (-x * sinpix
* gammaf_positive (-x, &exp2_adj));
ret = __scalbnf (tret, -exp2_adj);
+ if (ret < FLT_MIN)
+ {
+ float force_underflow = ret * ret;
+ math_force_eval (force_underflow);
+ }
}
}
}
diff --git a/sysdeps/ieee754/ldbl-128/e_gammal_r.c b/sysdeps/ieee754/ldbl-128/e_gammal_r.c
index c51b050e0e..c44f031745 100644
--- a/sysdeps/ieee754/ldbl-128/e_gammal_r.c
+++ b/sysdeps/ieee754/ldbl-128/e_gammal_r.c
@@ -194,6 +194,11 @@ __ieee754_gammal_r (long double x, int *signgamp)
ret = M_PIl / (-x * sinpix
* gammal_positive (-x, &exp2_adj));
ret = __scalbnl (ret, -exp2_adj);
+ if (ret < LDBL_MIN)
+ {
+ long double force_underflow = ret * ret;
+ math_force_eval (force_underflow);
+ }
}
}
}
diff --git a/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c b/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c
index 48098c18f6..420842e2d6 100644
--- a/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c
+++ b/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c
@@ -194,6 +194,11 @@ __ieee754_gammal_r (long double x, int *signgamp)
ret = M_PIl / (-x * sinpix
* gammal_positive (-x, &exp2_adj));
ret = __scalbnl (ret, -exp2_adj);
+ if (ret < LDBL_MIN)
+ {
+ long double force_underflow = ret * ret;
+ math_force_eval (force_underflow);
+ }
}
}
}
diff --git a/sysdeps/ieee754/ldbl-96/e_gammal_r.c b/sysdeps/ieee754/ldbl-96/e_gammal_r.c
index 9da5db33f0..a5767e7795 100644
--- a/sysdeps/ieee754/ldbl-96/e_gammal_r.c
+++ b/sysdeps/ieee754/ldbl-96/e_gammal_r.c
@@ -186,6 +186,11 @@ __ieee754_gammal_r (long double x, int *signgamp)
ret = M_PIl / (-x * sinpix
* gammal_positive (-x, &exp2_adj));
ret = __scalbnl (ret, -exp2_adj);
+ if (ret < LDBL_MIN)
+ {
+ long double force_underflow = ret * ret;
+ math_force_eval (force_underflow);
+ }
}
}
}