]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix ldbl-128 expm1l (-min_subnorm) result sign (bug 18619).
authorJoseph Myers <joseph@codesourcery.com>
Wed, 1 Jul 2015 22:27:49 +0000 (22:27 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Wed, 1 Jul 2015 22:27:49 +0000 (22:27 +0000)
In the ldbl-128 implementation of expm1l, when expm1l's result should
underflow to 0 (argument minus the least subnormal, in some rounding
modes), it can be a zero of the wrong sign.  This patch fixes this in
the same way previously used for the x86 / x86_64 versions.

Tested for mips64.

[BZ #18619]
* sysdeps/ieee754/ldbl-128/s_expm1l.c (__expm1l): Force underflow
and return argument in case of subnormal argument.

ChangeLog
NEWS
sysdeps/ieee754/ldbl-128/s_expm1l.c

index a2fd2139518ba3dd30435589f694f360d9f3d61e..7d501d54912cefdeee0457f7db13102dd5a5f3f7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2015-07-01  Joseph Myers  <joseph@codesourcery.com>
+
+       [BZ #18619]
+       * sysdeps/ieee754/ldbl-128/s_expm1l.c (__expm1l): Force underflow
+       and return argument in case of subnormal argument.
+
 2015-07-01  Martin Sebor  <msebor@redhat.com>
 
        [BZ #18435]
diff --git a/NEWS b/NEWS
index 91320dd429c3f843eca7bd74f254f1a0741f2e11..eecc9a1cc6999646c4eaba08c8f026696464f8e1 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -25,7 +25,7 @@ Version 2.22
   18496, 18497, 18498, 18502, 18507, 18512, 18513, 18519, 18520, 18522,
   18527, 18528, 18529, 18530, 18532, 18533, 18534, 18536, 18539, 18540,
   18542, 18544, 18545, 18546, 18547, 18549, 18553, 18558, 18569, 18583,
-  18585, 18586, 18593, 18594, 18602, 18612, 18613.
+  18585, 18586, 18593, 18594, 18602, 18612, 18613, 18619.
 
 * Cache information can be queried via sysconf() function on s390 e.g. with
   _SC_LEVEL1_ICACHE_SIZE as argument.
index f708af504c6bb920c6e569f74ab9c80e867438e5..573d00be57274a53ee6c2873afdd55458fff0a34 100644 (file)
@@ -137,9 +137,18 @@ __expm1l (long double x)
   if (x < minarg)
     return (4.0/big - 1.0L);
 
-  /* Avoid internal underflow when result does not underflow.  */
-  if (fabsl (x) < 0x1p-113L && fabsl (x) >= LDBL_MIN)
-    return x;
+  /* Avoid internal underflow when result does not underflow, while
+     ensuring underflow (without returning a zero of the wrong sign)
+     when the result does underflow.  */
+  if (fabsl (x) < 0x1p-113L)
+    {
+      if (fabsl (x) < LDBL_MIN)
+       {
+         long double force_underflow = x * x;
+         math_force_eval (force_underflow);
+       }
+      return x;
+    }
 
   /* Express x = ln 2 (k + remainder), remainder not exceeding 1/2. */
   xx = C1 + C2;                        /* ln 2. */