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 0ace298..9055159 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 622cdbf..ca3ef63 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 0d467a2..fa8e238 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 a202bc7..73ff0ff 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 f4f9a8c..344eeb4 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 bd51b56..0f5f7e5 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 1e89284..d7424a6 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 6c7da0e..991a3b7 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 323ded0..442ad97 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 956489f..c12906d 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 bb549d2..92fef5a 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