]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix log2 (1) in round-downward mode (bug 17042).
authorJoseph Myers <joseph@codesourcery.com>
Tue, 10 Jun 2014 12:07:15 +0000 (12:07 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Tue, 10 Jun 2014 12:07:15 +0000 (12:07 +0000)
As with other issues of this kind, bug 17042 is log2 (1) wrongly
returning -0 instead of +0 in round-downward mode because of
implementations effectively in terms of log1p (x - 1).  This patch
fixes the issue in the same way used for log and log10.

Tested x86_64 and x86 and ulps updated accordingly.  Also tested for
mips64 to confirm a fix was needed for ldbl-128 and to validate that
fix (also applied to ldbl-128ibm since that version of log2l is
essentially the same as the ldbl-128 one).

[BZ #17042]
* sysdeps/i386/fpu/e_log2.S (__ieee754_log2): Take absolete value
when x - 1 is zero.
* sysdeps/i386/fpu/e_log2f.S (__ieee754_log2f): Likewise.
* sysdeps/i386/fpu/e_log2l.S (__ieee754_log2l): Likewise.
* sysdeps/ieee754/ldbl-128/e_log2l.c (__ieee754_log2l): Return
0.0L for an argument of 1.0L.
* sysdeps/ieee754/ldbl-128ibm/e_log2l.c (__ieee754_log2l):
Likewise.
* sysdeps/x86_64/fpu/e_log2l.S (__ieee754_log2l): Take absolute
value when x - 1 is zero.
* math/libm-test.inc (log2_test): Use ALL_RM_TEST.
* sysdeps/i386/fpu/libm-test-ulps: Update.
* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.

ChangeLog
NEWS
math/libm-test.inc
sysdeps/i386/fpu/e_log2.S
sysdeps/i386/fpu/e_log2f.S
sysdeps/i386/fpu/e_log2l.S
sysdeps/i386/fpu/libm-test-ulps
sysdeps/ieee754/ldbl-128/e_log2l.c
sysdeps/ieee754/ldbl-128ibm/e_log2l.c
sysdeps/x86_64/fpu/e_log2l.S
sysdeps/x86_64/fpu/libm-test-ulps

index 0ace298b9edc4108f12f1873b27a5346ac4b6e0c..9055159cf0af49b663b6592737b4fad58e666381 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2014-06-10  Joseph Myers  <joseph@codesourcery.com>
+
+       [BZ #17042]
+       * sysdeps/i386/fpu/e_log2.S (__ieee754_log2): Take absolete value
+       when x - 1 is zero.
+       * sysdeps/i386/fpu/e_log2f.S (__ieee754_log2f): Likewise.
+       * sysdeps/i386/fpu/e_log2l.S (__ieee754_log2l): Likewise.
+       * sysdeps/ieee754/ldbl-128/e_log2l.c (__ieee754_log2l): Return
+       0.0L for an argument of 1.0L.
+       * sysdeps/ieee754/ldbl-128ibm/e_log2l.c (__ieee754_log2l):
+       Likewise.
+       * sysdeps/x86_64/fpu/e_log2l.S (__ieee754_log2l): Take absolute
+       value when x - 1 is zero.
+       * math/libm-test.inc (log2_test): Use ALL_RM_TEST.
+       * sysdeps/i386/fpu/libm-test-ulps: Update.
+       * sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
+
 2014-06-09  Bernard Ogden  <bernie.ogden@linaro.org>
 
        [BZ #15119]
diff --git a/NEWS b/NEWS
index 622cdbf21d21b89d9dc18a2dd666437908cdf796..ca3ef633b01de6a185d33e6c26d21f5940be8cf3 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -19,7 +19,7 @@ Version 2.20
   16791, 16796, 16799, 16800, 16815, 16823, 16824, 16831, 16838, 16849,
   16854, 16876, 16877, 16878, 16882, 16885, 16888, 16890, 16912, 16915,
   16916, 16917, 16922, 16927, 16928, 16932, 16943, 16958, 16965, 16966,
-  16967, 16977, 16978, 16984, 16990, 17009.
+  16967, 16977, 16978, 16984, 16990, 17009, 17042.
 
 * The minimum Linux kernel version that this version of the GNU C Library
   can be used with is 2.6.32.
index 0d467a2195132ed367327f7345974d25e5e53e2a..fa8e2385dc1bbb1f9944ee10061ea956071b630f 100644 (file)
@@ -7840,9 +7840,7 @@ static const struct test_f_f_data log2_test_data[] =
 static void
 log2_test (void)
 {
-  START (log2, 0);
-  RUN_TEST_LOOP_f_f (log2, log2_test_data, );
-  END;
+  ALL_RM_TEST (log2, 0, log2_test_data, RUN_TEST_LOOP_f_f, END);
 }
 
 
index a202bc731df606b655c438e3f28d43f8db349ba9..73ff0fffd386e6fb0714b63a7fd2885db51dbf5a 100644 (file)
@@ -47,7 +47,13 @@ ENTRY(__ieee754_log2)
        fnstsw                  // x-1 : x : 1
        andb    $0x45, %ah
        jz      2f
-       fstp    %st(1)          // x-1 : 1
+       fxam
+       fnstsw
+       andb    $0x45, %ah
+       cmpb    $0x40, %ah
+       jne     5f
+       fabs                    // log2(1) is +0 in all rounding modes.
+5:     fstp    %st(1)          // x-1 : 1
        fyl2xp1                 // log(x)
        ret
 
index f4f9a8c3bfcb0c845d866be6aa2662927ac6dfc6..344eeb495e4a1fea3dbe73ac2835025729b1cba3 100644 (file)
@@ -47,7 +47,13 @@ ENTRY(__ieee754_log2f)
        fnstsw                  // x-1 : x : 1
        andb    $0x45, %ah
        jz      2f
-       fstp    %st(1)          // x-1 : 1
+       fxam
+       fnstsw
+       andb    $0x45, %ah
+       cmpb    $0x40, %ah
+       jne     5f
+       fabs                    // log2(1) is +0 in all rounding modes.
+5:     fstp    %st(1)          // x-1 : 1
        fyl2xp1                 // log(x)
        ret
 
index bd51b5651ecfd702b414c025cf6a86ba16f20763..0f5f7e5789ada54a31d83bb34c1faa540722f998 100644 (file)
@@ -47,7 +47,13 @@ ENTRY(__ieee754_log2l)
        fnstsw                  // x-1 : x : 1
        andb    $0x45, %ah
        jz      2f
-       fstp    %st(1)          // x-1 : 1
+       fxam
+       fnstsw
+       andb    $0x45, %ah
+       cmpb    $0x40, %ah
+       jne     5f
+       fabs                    // log2(1) is +0 in all rounding modes.
+5:     fstp    %st(1)          // x-1 : 1
        fyl2xp1                 // log(x)
        ret
 
index 1e8928445509e36d4066e59b5fe23fe732443666..d7424a6f86a13e00115ddb84c97928f1d6793359 100644 (file)
@@ -1588,6 +1588,22 @@ ifloat: 1
 ildouble: 1
 ldouble: 1
 
+Function: "log2_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "log2_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
 Function: "log_downward":
 ildouble: 1
 ldouble: 1
index 6c7da0e44b9e1997bb2c38b195fdffd767f5e33f..991a3b73e2e1924a1d44d35876b42e925017e72e 100644 (file)
@@ -188,6 +188,9 @@ __ieee754_log2l (x)
   if (hx >= 0x7fff000000000000LL)
     return (x + x);
 
+  if (x == 1.0L)
+    return 0.0L;
+
 /* separate mantissa from exponent */
 
 /* Note, frexp is used so that denormal numbers
index 323ded0c0fa5e2e151fa4837ed9fa05249757eba..442ad972545cb1ce719f98d036574ac3f543138b 100644 (file)
@@ -190,6 +190,9 @@ __ieee754_log2l (x)
   if (hx >= 0x7ff0000000000000LL)
     return (x + x);
 
+  if (x == 1.0L)
+    return 0.0L;
+
 /* separate mantissa from exponent */
 
 /* Note, frexp is used so that denormal numbers
index 956489fc3eba687e645e6656163e5c78f5165855..c12906d456cb55e2883c1584edc827b689407e92 100644 (file)
@@ -45,7 +45,13 @@ ENTRY(__ieee754_log2l)
        fnstsw                  // x-1 : x : 1
        andb    $0x45, %ah
        jz      2f
-       fstp    %st(1)          // x-1 : 1
+       fxam
+       fnstsw
+       andb    $0x45, %ah
+       cmpb    $0x40, %ah
+       jne     5f
+       fabs                    // log2(1) is +0 in all rounding modes.
+5:     fstp    %st(1)          // x-1 : 1
        fyl2xp1                 // log(x)
        ret
 
index bb549d2b0d724bcabf37cc845acac23eeaf32db2..92fef5a134f84a6c55425cfd984659de9a62ae3a 100644 (file)
@@ -1665,6 +1665,28 @@ ifloat: 1
 ildouble: 1
 ldouble: 1
 
+Function: "log2_downward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+
+Function: "log2_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "log2_upward":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
 Function: "log_downward":
 float: 1
 ifloat: 1