about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAdhemerval Zanella <azanella@linux.vnet.ibm.com>2012-04-11 16:30:13 -0300
committerAndreas Jaeger <aj@suse.de>2012-04-17 22:12:53 +0200
commit76da7265320010c7a273ed99f53938c0f32d5fad (patch)
treef094871a5f38652d2d320a11423fee602a8746e6
parent0396e69dbefb3630651d93e0a7526c4326a071bb (diff)
downloadglibc-76da7265320010c7a273ed99f53938c0f32d5fad.tar.gz
glibc-76da7265320010c7a273ed99f53938c0f32d5fad.tar.xz
glibc-76da7265320010c7a273ed99f53938c0f32d5fad.zip
Fix ilogb exception and errno (bug 6794)
[BZ #6794]
Following Joseph comments about bug 6794, here is a proposed fix. It turned out
to be a large fix mainly because I had to move some file along to follow libm
files/names conventions.

Basically I have added wrappers (w_ilogb.c, w_ilogbf.c, w_ilogbl.c) that now calls
the symbol '__ieee754_ilogb'. The wrappers checks for '__ieee754_ilogb' output and
set the errno and raise exceptions as expected.

The '__ieee754_ilogb' is implemented in sysdeps. I have moved the 's_ilogb[f|l]' files
to e_ilogb[f|l] and renamed the '__ilogb[f|l]' to '__ieee754_ilogb[f|l]'.

I also found out a bug in i386 and x86-64 assembly coded ilogb implementation where
it raises a FE_DIVBYZERO when argument is '0.0'. I corrected this issue as well.

Finally I added the errno and FE_INVALID tests for 0.0, NaN and +-InF argument. Tested
on i386, x86-64, ppc32 and ppc64.
-rw-r--r--ChangeLog31
-rw-r--r--NEWS20
-rw-r--r--math/Makefile4
-rw-r--r--math/libm-test.inc23
-rw-r--r--math/w_ilogb.c42
-rw-r--r--math/w_ilogbf.c38
-rw-r--r--math/w_ilogbl.c37
-rw-r--r--sysdeps/generic/math_private.h3
-rw-r--r--sysdeps/i386/fpu/e_ilogb.S (renamed from sysdeps/i386/fpu/s_ilogb.S)11
-rw-r--r--sysdeps/i386/fpu/e_ilogbf.S (renamed from sysdeps/i386/fpu/s_ilogbf.S)11
-rw-r--r--sysdeps/i386/fpu/e_ilogbl.S (renamed from sysdeps/i386/fpu/s_ilogbl.S)11
-rw-r--r--sysdeps/ieee754/dbl-64/e_ilogb.c (renamed from sysdeps/ieee754/dbl-64/s_ilogb.c)8
-rw-r--r--sysdeps/ieee754/flt-32/e_ilogbf.c (renamed from sysdeps/ieee754/flt-32/s_ilogbf.c)4
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c (renamed from sysdeps/ieee754/ldbl-128ibm/s_ilogbl.c)3
-rw-r--r--sysdeps/ieee754/ldbl-opt/w_ilogb.c (renamed from sysdeps/ieee754/ldbl-opt/s_ilogb.c)2
-rw-r--r--sysdeps/ieee754/ldbl-opt/w_ilogbl.c5
-rw-r--r--sysdeps/x86_64/fpu/e_ilogbl.S (renamed from sysdeps/x86_64/fpu/s_ilogbl.S)11
17 files changed, 223 insertions, 41 deletions
diff --git a/ChangeLog b/ChangeLog
index 982ac14562..0d458fde60 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+2012-04-17  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	[BZ #6794]
+	* math/Makefile: Add e_ilogb and w_ilogb, remove s_logb.
+	* math/libm-test.inc: Add ilogb errno and exception tests.
+	* math/w_ilogb.c: New file: ilogb wrapper.
+	* math/w_ilogbf.c: New file: ilogbf wrapper.
+	* math/w_ilogbl.c: New file: ilogbl wrapper.
+	* sysdeps/generic/math_private.h: Add __ieee754_ilogb[l|f] prototypes.
+	* sysdeps/i386/fpu/s_ilogb.S: Moved to ...
+	* sysdeps/i386/fpu/e_ilogb.S: ... here. Also fixed a FE_DIVBYZERO
+	exception being thrown with 0.0 as argument.
+	* sysdeps/i386/fpu/s_ilogbf.S: Moved to ...
+	* sysdeps/i386/fpu/e_ilogbf.S: ... here. Also fixed a FE_DIVBYZERO
+	exception being thrown with 0.0 as argument.
+	* sysdeps/i386/fpu/s_ilogbl.S: Moved to ...
+	* sysdeps/i386/fpu/e_ilogbl.S: ... here. Also fixed a FE_DIVBYZERO
+	exception being thrown with 0.0 as argument.
+	* sysdeps/x86_64/fpu/s_ilogbl.S: Moved to ...
+	* sysdeps/x86_64/fpu/e_ilogbl.S: ... here. Also fixed a FE_DIVBYZERO
+	exception being thrown with 0.0 as argument.
+	* sysdeps/ieee754/dbl-64/s_ilogb.c: Moved to ...
+	* sysdeps/ieee754/dbl-64/e_ilogb.c: ... here.
+	* sysdeps/ieee754/flt-32/e_ilogbf.c: Moved to ...
+	* sysdeps/ieee754/flt-32/e_ilogbf.c: ... here.
+	* sysdeps/ieee754/ldbl-128ibm/s_ilogbl.c: Moved to ...
+	* sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c: ... here.
+	* sysdeps/ieee754/ldbl-opt/s_ilogb.c: Moved to ...
+	* sysdeps/ieee754/ldbl-opt/w_ilogb.c: ... here.
+	* sysdeps/ieee754/ldbl-opt/w_ilogbl.c: New file: ilogbl wrapper.
+
 2012-04-17  Petr Baudis  <pasky@ucw.cz>
 
 	* include/sys/uio.h: Change __vector to __iovec to avoid clash
diff --git a/NEWS b/NEWS
index 9812e0e56f..7ccb50b848 100644
--- a/NEWS
+++ b/NEWS
@@ -12,16 +12,16 @@ Version 2.16
   174, 350, 369, 411, 706, 2074, 2541, 2547, 2548, 2551, 2552, 2553, 2554,
   2562, 2563, 2565, 2566, 2576, 2636, 2678, 3335, 3768, 3866, 3868, 3976,
   3992, 4026, 4108, 4596, 4822, 5077, 5461, 5805, 5993, 6471, 6486, 6578,
-  6649, 6730, 6770, 6884, 6890, 6894, 6895, 6907, 6911, 9739, 9902, 10110,
-  10135, 10140, 10153, 10210, 10254, 10346, 10545, 10716, 11174, 11322,
-  11365, 11451, 11494, 11521, 11959, 12047, 12340, 13058, 13525, 13526,
-  13527, 13528, 13529, 13530, 13531, 13532, 13533, 13547, 13551, 13552,
-  13553, 13555, 13559, 13566, 13583, 13592, 13618, 13637, 13656, 13658,
-  13673, 13691, 13695, 13704, 13705, 13706, 13726, 13738, 13760, 13761,
-  13786, 13792, 13806, 13824, 13840, 13841, 13844, 13846, 13851, 13852,
-  13854, 13871, 13872, 13873, 13879, 13883, 13892, 13895, 13908, 13910,
-  13911, 13912, 13913, 13915, 13916, 13917, 13918, 13919, 13920, 13921,
-  13926, 13928, 13938, 13963, 13967, 13973
+  6649, 6730, 6770, 6794, 6884, 6890, 6894, 6895, 6907, 6911, 9739, 9902,
+  10110, 10135, 10140, 10153, 10210, 10254, 10346, 10545, 10716, 11174,
+  11322, 11365, 11451, 11494, 11521, 11959, 12047, 12340, 13058, 13525,
+  13526, 13527, 13528, 13529, 13530, 13531, 13532, 13533, 13547, 13551,
+  13552, 13553, 13555, 13559, 13566, 13583, 13592, 13618, 13637, 13656,
+  13658, 13673, 13691, 13695, 13704, 13705, 13706, 13726, 13738, 13760,
+  13761, 13786, 13792, 13806, 13824, 13840, 13841, 13844, 13846, 13851,
+  13852, 13854, 13871, 13872, 13873, 13879, 13883, 13892, 13895, 13908,
+  13910, 13911, 13912, 13913, 13915, 13916, 13917, 13918, 13919, 13920,
+  13921, 13926, 13928, 13938, 13963, 13967, 13973
 
 * ISO C11 support:
 
diff --git a/math/Makefile b/math/Makefile
index 3a671aac71..abeba7a931 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -42,14 +42,16 @@ libm-support = k_standard s_lib_version s_matherr s_signgam		\
 libm-calls = e_acos e_acosh e_asin e_atan2 e_atanh e_cosh e_exp e_fmod	\
 	     e_hypot e_j0 e_j1 e_jn e_lgamma_r e_log e_log10 e_pow	\
 	     e_rem_pio2 e_remainder e_scalb e_sinh e_sqrt e_gamma_r	\
+	     e_ilogb							\
 	     k_cos k_rem_pio2 k_sin k_tan s_asinh s_atan s_cbrt		\
 	     s_ceil s_cos s_erf s_expm1 s_fabs				\
-	     s_floor s_ilogb s_log1p s_logb				\
+	     s_floor s_log1p s_logb					\
 	     s_nextafter s_nexttoward s_rint s_scalbln			\
 	     s_significand s_sin s_tan s_tanh w_acos w_acosh w_asin	\
 	     w_atan2 w_atanh w_cosh w_drem w_exp w_exp2 w_exp10 w_fmod	\
 	     w_tgamma w_hypot w_j0 w_j1 w_jn w_lgamma w_lgamma_r	\
 	     w_log w_log10 w_pow w_remainder w_scalb w_sinh w_sqrt	\
+	     w_ilogb							\
 	     s_fpclassify s_fmax s_fmin s_fdim s_nan s_trunc		\
 	     s_remquo e_log2 e_exp2 s_round s_nearbyint s_sincos	\
 	     conj cimag creal cabs carg s_cexp s_csinh s_ccosh s_clog	\
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 2809d57d09..94d60bff7e 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -3802,13 +3802,22 @@ ilogb_test (void)
   TEST_f_i (ilogb, 1024, 10);
   TEST_f_i (ilogb, -2000, 10);
 
-  /* XXX We have a problem here: the standard does not tell us whether
-     exceptions are allowed/required.  ignore them for now.  */
-
-  TEST_f_i (ilogb, 0.0, FP_ILOGB0, EXCEPTIONS_OK);
-  TEST_f_i (ilogb, nan_value, FP_ILOGBNAN, EXCEPTIONS_OK);
-  TEST_f_i (ilogb, plus_infty, INT_MAX, EXCEPTIONS_OK);
-  TEST_f_i (ilogb, minus_infty, INT_MAX, EXCEPTIONS_OK);
+  /* ilogb (0.0) == FP_ILOGB0 plus invalid exception  */
+  errno = 0;
+  TEST_f_i (ilogb, 0.0, FP_ILOGB0, INVALID_EXCEPTION);
+  check_int ("errno for ilogb(0.0) unchanged", errno, EDOM, 0, 0, 0);
+  /* ilogb (NaN) == FP_ILOGBNAN plus invalid exception  */
+  errno = 0;
+  TEST_f_i (ilogb, nan_value, FP_ILOGBNAN, INVALID_EXCEPTION);
+  check_int ("errno for ilogb(NaN) unchanged", errno, EDOM, 0, 0, 0);
+  /* ilogb (inf) == INT_MAX plus invalid exception  */
+  errno = 0;
+  TEST_f_i (ilogb, plus_infty, INT_MAX, INVALID_EXCEPTION);
+  check_int ("errno for ilogb(Inf) unchanged", errno, EDOM, 0, 0, 0);
+  /* ilogb (-inf) == INT_MAX plus invalid exception  */
+  errno = 0;
+  TEST_f_i (ilogb, minus_infty, INT_MAX, INVALID_EXCEPTION);
+  check_int ("errno for ilogb(-Inf) unchanged", errno, EDOM, 0, 0, 0);
 
   END (ilogb);
 }
diff --git a/math/w_ilogb.c b/math/w_ilogb.c
new file mode 100644
index 0000000000..c87b517c50
--- /dev/null
+++ b/math/w_ilogb.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Adhemerval Zanella <azanella@linux.vnet.ibm.com>, 2011.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <errno.h>
+#include <math_private.h>
+
+/* wrapper ilogb */
+int
+__ilogb (double x)
+{
+  int r = __ieee754_ilogb (x);
+  if (__builtin_expect (r == FP_ILOGB0, 0)
+      || __builtin_expect (r == FP_ILOGBNAN, 0)
+      || __builtin_expect (r == INT_MAX, 0))
+    {
+      __set_errno (EDOM);
+      feraiseexcept (FE_INVALID);
+    }
+  return r;
+}
+
+weak_alias (__ilogb, ilogb)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__ilogb, __ilogbl)
+weak_alias (__ilogb, ilogbl)
+#endif
diff --git a/math/w_ilogbf.c b/math/w_ilogbf.c
new file mode 100644
index 0000000000..ae3574a75d
--- /dev/null
+++ b/math/w_ilogbf.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Adhemerval Zanella <azanella@linux.vnet.ibm.com>, 2011.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <errno.h>
+#include <math_private.h>
+
+/* wrapper ilogbf */
+int
+__ilogbf (float x)
+{
+  int r = __ieee754_ilogbf (x);
+  if (__builtin_expect (r == FP_ILOGB0, 0)
+      || __builtin_expect (r == FP_ILOGBNAN, 0)
+      || __builtin_expect (r == INT_MAX, 0))
+    {
+      __set_errno (EDOM);
+      feraiseexcept (FE_INVALID);
+    }
+  return r;
+}
+
+weak_alias (__ilogbf, ilogbf)
diff --git a/math/w_ilogbl.c b/math/w_ilogbl.c
new file mode 100644
index 0000000000..8c30caa48b
--- /dev/null
+++ b/math/w_ilogbl.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Adhemerval Zanella <azanella@linux.vnet.ibm.com>, 2011.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <errno.h>
+#include <math_private.h>
+
+/* wrapper ilogbl */
+int
+__ilogbl (long double x)
+{
+  int r = __ieee754_ilogbl (x);
+  if (__builtin_expect (r == FP_ILOGB0, 0)
+      || __builtin_expect (r == FP_ILOGBNAN, 0)
+      || __builtin_expect (r == INT_MAX, 0))
+    {
+      __set_errno (EDOM);
+      feraiseexcept (FE_INVALID);
+    }
+  return r;
+}
+weak_alias (__ilogbl, ilogbl)
diff --git a/sysdeps/generic/math_private.h b/sysdeps/generic/math_private.h
index e2172246f2..5267ec327b 100644
--- a/sysdeps/generic/math_private.h
+++ b/sysdeps/generic/math_private.h
@@ -213,6 +213,7 @@ extern double __ieee754_yn (int,double);
 extern double __ieee754_remainder (double,double);
 extern int32_t __ieee754_rem_pio2 (double,double*);
 extern double __ieee754_scalb (double,double);
+extern int __ieee754_ilogb (double);
 
 /* fdlibm kernel function */
 extern double __kernel_standard (double,double,int);
@@ -260,6 +261,7 @@ extern float __ieee754_ynf (int,float);
 extern float __ieee754_remainderf (float,float);
 extern int32_t __ieee754_rem_pio2f (float,float*);
 extern float __ieee754_scalbf (float,float);
+extern int __ieee754_ilogbf (float);
 
 
 /* float versions of fdlibm kernel functions */
@@ -305,6 +307,7 @@ extern long double __ieee754_ynl (int,long double);
 extern long double __ieee754_remainderl (long double,long double);
 extern int   __ieee754_rem_pio2l (long double,long double*);
 extern long double __ieee754_scalbl (long double,long double);
+extern int   __ieee754_ilogbl (long double);
 
 /* long double versions of fdlibm kernel functions */
 extern long double __kernel_sinl (long double,long double,int);
diff --git a/sysdeps/i386/fpu/s_ilogb.S b/sysdeps/i386/fpu/e_ilogb.S
index 0cf1ad7419..4fb635041f 100644
--- a/sysdeps/i386/fpu/s_ilogb.S
+++ b/sysdeps/i386/fpu/e_ilogb.S
@@ -7,7 +7,7 @@
 
 RCSID("$NetBSD: s_ilogb.S,v 1.5 1995/10/12 15:53:09 jtc Exp $")
 
-ENTRY(__ilogb)
+ENTRY(__ieee754_ilogb)
 	fldl	4(%esp)
 /* I added the following ugly construct because ilogb(+-Inf) is
    required to return INT_MAX in ISO C99.
@@ -18,6 +18,8 @@ ENTRY(__ilogb)
 	andb    %ah, %dh
 	cmpb    $0x05, %dh
 	je      1f		/* Is +-Inf, jump.  */
+	cmpb    $0x40, %dh
+	je      2f		/* Is +-0, jump.  */
 
 	fxtract
 	pushl	%eax
@@ -34,5 +36,8 @@ ENTRY(__ilogb)
 1:	fstp	%st
 	movl	$0x7fffffff, %eax
 	ret
-END (__ilogb)
-weak_alias (__ilogb, ilogb)
+2:	fstp	%st
+	movl	$0x80000000, %eax	/* FP_ILOGB0  */
+	ret
+END (__ieee754_ilogb)
+weak_alias (__ieee754_ilogb, __ilogb_finite)
diff --git a/sysdeps/i386/fpu/s_ilogbf.S b/sysdeps/i386/fpu/e_ilogbf.S
index 99e53edd75..fbb50be07f 100644
--- a/sysdeps/i386/fpu/s_ilogbf.S
+++ b/sysdeps/i386/fpu/e_ilogbf.S
@@ -7,7 +7,7 @@
 
 RCSID("$NetBSD: s_ilogbf.S,v 1.4 1995/10/22 20:32:43 pk Exp $")
 
-ENTRY(__ilogbf)
+ENTRY(__ieee754_ilogbf)
 	flds	4(%esp)
 /* I added the following ugly construct because ilogb(+-Inf) is
    required to return INT_MAX in ISO C99.
@@ -18,6 +18,8 @@ ENTRY(__ilogbf)
 	andb    %ah, %dh
 	cmpb    $0x05, %dh
 	je      1f		/* Is +-Inf, jump.  */
+	cmpb    $0x40, %dh
+	je      2f		/* Is +-0, jump.  */
 
 	fxtract
 	pushl	%eax
@@ -34,5 +36,8 @@ ENTRY(__ilogbf)
 1:	fstp	%st
 	movl	$0x7fffffff, %eax
 	ret
-END (__ilogbf)
-weak_alias (__ilogbf, ilogbf)
+2:	fstp	%st
+	movl	$0x80000000, %eax	/* FP_ILOGB0  */
+	ret
+END (__ieee754_ilogbf)
+weak_alias (__ieee754_ilogbf, __ilogbf_finite)
diff --git a/sysdeps/i386/fpu/s_ilogbl.S b/sysdeps/i386/fpu/e_ilogbl.S
index 1f559b311e..6e2be9a300 100644
--- a/sysdeps/i386/fpu/s_ilogbl.S
+++ b/sysdeps/i386/fpu/e_ilogbl.S
@@ -8,7 +8,7 @@
 
 RCSID("$NetBSD: $")
 
-ENTRY(__ilogbl)
+ENTRY(__ieee754_ilogbl)
 	fldt	4(%esp)
 /* I added the following ugly construct because ilogb(+-Inf) is
    required to return INT_MAX in ISO C99.
@@ -19,6 +19,8 @@ ENTRY(__ilogbl)
 	andb    %ah, %dh
 	cmpb    $0x05, %dh
 	je      1f		/* Is +-Inf, jump.  */
+	cmpb    $0x40, %dh
+	je      2f		/* Is +-0, jump.  */
 
 	fxtract
 	pushl	%eax
@@ -35,5 +37,8 @@ ENTRY(__ilogbl)
 1:	fstp	%st
 	movl	$0x7fffffff, %eax
 	ret
-END (__ilogbl)
-weak_alias (__ilogbl, ilogbl)
+2:	fstp	%st
+	movl	$0x80000000, %eax	/* FP_ILOGB0  */
+	ret
+END (__ieee754_ilogbl)
+weak_alias (__ieee754_ilogbl, __ilogbl_finite)
diff --git a/sysdeps/ieee754/dbl-64/s_ilogb.c b/sysdeps/ieee754/dbl-64/e_ilogb.c
index 05c66d70fe..7772880a1f 100644
--- a/sysdeps/ieee754/dbl-64/s_ilogb.c
+++ b/sysdeps/ieee754/dbl-64/e_ilogb.c
@@ -25,7 +25,7 @@ static char rcsid[] = "$NetBSD: s_ilogb.c,v 1.9 1995/05/10 20:47:28 jtc Exp $";
 #include <math.h>
 #include <math_private.h>
 
-int __ilogb(double x)
+int __ieee754_ilogb(double x)
 {
 	int32_t hx,lx,ix;
 
@@ -52,8 +52,4 @@ int __ilogb(double x)
 	}
 	return FP_ILOGBNAN;
 }
-weak_alias (__ilogb, ilogb)
-#ifdef NO_LONG_DOUBLE
-strong_alias (__ilogb, __ilogbl)
-weak_alias (__ilogb, ilogbl)
-#endif
+strong_alias (__ieee754_ilogb, __ilogb_finite)
diff --git a/sysdeps/ieee754/flt-32/s_ilogbf.c b/sysdeps/ieee754/flt-32/e_ilogbf.c
index 21f9cd9704..c7441a8561 100644
--- a/sysdeps/ieee754/flt-32/s_ilogbf.c
+++ b/sysdeps/ieee754/flt-32/e_ilogbf.c
@@ -21,7 +21,7 @@ static char rcsid[] = "$NetBSD: s_ilogbf.c,v 1.4 1995/05/10 20:47:31 jtc Exp $";
 #include <math.h>
 #include <math_private.h>
 
-int __ilogbf(float x)
+int __ieee754_ilogbf(float x)
 {
 	int32_t hx,ix;
 
@@ -42,4 +42,4 @@ int __ilogbf(float x)
 	}
 	return FP_ILOGBNAN;
 }
-weak_alias (__ilogbf, ilogbf)
+strong_alias (__ieee754_ilogbf, __ilogbf_finite)
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_ilogbl.c b/sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c
index a6f0e1e678..55f87ed422 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_ilogbl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c
@@ -29,7 +29,7 @@ static char rcsid[] = "$NetBSD: $";
 #include <math_private.h>
 #include <math_ldbl_opt.h>
 
-int __ilogbl(long double x)
+int __ieee754_ilogbl(long double x)
 {
 	int64_t hx,lx;
 	int ix;
@@ -55,4 +55,3 @@ int __ilogbl(long double x)
 	}
 	return FP_ILOGBNAN;
 }
-long_double_symbol (libm, __ilogbl, ilogbl);
diff --git a/sysdeps/ieee754/ldbl-opt/s_ilogb.c b/sysdeps/ieee754/ldbl-opt/w_ilogb.c
index 3a6ccbd09d..f518087a5f 100644
--- a/sysdeps/ieee754/ldbl-opt/s_ilogb.c
+++ b/sysdeps/ieee754/ldbl-opt/w_ilogb.c
@@ -1,5 +1,5 @@
 #include <math_ldbl_opt.h>
-#include <sysdeps/ieee754/dbl-64/s_ilogb.c>
+#include <math/w_ilogb.c>
 #if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
 compat_symbol (libm, __ilogb, ilogbl, GLIBC_2_0);
 #endif
diff --git a/sysdeps/ieee754/ldbl-opt/w_ilogbl.c b/sysdeps/ieee754/ldbl-opt/w_ilogbl.c
new file mode 100644
index 0000000000..36f83f6ade
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-opt/w_ilogbl.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#undef weak_alias
+#define weak_alias(n,a)
+#include <math/w_ilogbl.c>
+long_double_symbol (libm, __ilogbl, ilogbl);
diff --git a/sysdeps/x86_64/fpu/s_ilogbl.S b/sysdeps/x86_64/fpu/e_ilogbl.S
index f59040c11e..44f92159a8 100644
--- a/sysdeps/x86_64/fpu/s_ilogbl.S
+++ b/sysdeps/x86_64/fpu/e_ilogbl.S
@@ -7,7 +7,7 @@
 
 #include <machine/asm.h>
 
-ENTRY(__ilogbl)
+ENTRY(__ieee754_ilogbl)
 	fldt	8(%rsp)
 /* I added the following ugly construct because ilogb(+-Inf) is
    required to return INT_MAX in ISO C99.
@@ -18,6 +18,8 @@ ENTRY(__ilogbl)
 	andb    %ah, %dh
 	cmpb    $0x05, %dh
 	je      1f		/* Is +-Inf, jump.  */
+	cmpb    $0x40, %dh
+	je      2f		/* Is +-Inf, jump.  */
 
 	fxtract
 	fstp	%st
@@ -31,5 +33,8 @@ ENTRY(__ilogbl)
 1:	fstp	%st
 	movl	$0x7fffffff, %eax
 	ret
-END (__ilogbl)
-weak_alias (__ilogbl, ilogbl)
+2:	fstp	%st
+	movl	$0x80000000, %eax	/* FP_ILOGB0  */
+	ret
+END (__ieee754_ilogbl)
+weak_alias (__ieee754_ilogbl, __ilogbl_finite)