This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix ldbl-128 lrintl, lroundl missing exceptions for 32-bit long (bug 19085) [committed]


The ldbl-128 implementations of lrintl and lroundl miss "invalid"
exceptions on systems with 32-bit long for arguments that overflow
long but have exponent below 48.  This patch fixes this by rearranging
the sequence of tests in the code so the exponent < 48 case is only
used for exponents that don't overflow long.

Tested for mips64 (n32 and n64).  Committed.

2015-10-07  Joseph Myers  <joseph@codesourcery.com>

	[BZ #19085]
	* sysdeps/ieee754/ldbl-128/s_lrintl.c (__lrintl): Move test for
	exponent below 48 inside case for non-overflowing exponent.
	* sysdeps/ieee754/ldbl-128/s_lroundl.c (__lroundl): Likewise.

diff --git a/sysdeps/ieee754/ldbl-128/s_lrintl.c b/sysdeps/ieee754/ldbl-128/s_lrintl.c
index b0e0cfc..d0b0aeb 100644
--- a/sysdeps/ieee754/ldbl-128/s_lrintl.c
+++ b/sysdeps/ieee754/ldbl-128/s_lrintl.c
@@ -45,20 +45,20 @@ __lrintl (long double x)
   i0 &= 0x0000ffffffffffffLL;
   i0 |= 0x0001000000000000LL;
 
-  if (j0 < 48)
+  if (j0 < (int32_t) (8 * sizeof (long int)) - 1)
     {
-      w = two112[sx] + x;
-      t = w - two112[sx];
-      GET_LDOUBLE_WORDS64 (i0, i1, t);
-      j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
-      i0 &= 0x0000ffffffffffffLL;
-      i0 |= 0x0001000000000000LL;
+      if (j0 < 48)
+	{
+	  w = two112[sx] + x;
+	  t = w - two112[sx];
+	  GET_LDOUBLE_WORDS64 (i0, i1, t);
+	  j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
+	  i0 &= 0x0000ffffffffffffLL;
+	  i0 |= 0x0001000000000000LL;
 
-      result = (j0 < 0 ? 0 : i0 >> (48 - j0));
-    }
-  else if (j0 < (int32_t) (8 * sizeof (long int)) - 1)
-    {
-      if (j0 >= 112)
+	  result = (j0 < 0 ? 0 : i0 >> (48 - j0));
+	}
+      else if (j0 >= 112)
 	result = ((long int) i0 << (j0 - 48)) | (i1 << (j0 - 112));
       else
 	{
diff --git a/sysdeps/ieee754/ldbl-128/s_lroundl.c b/sysdeps/ieee754/ldbl-128/s_lroundl.c
index 8421609..64b285e 100644
--- a/sysdeps/ieee754/ldbl-128/s_lroundl.c
+++ b/sysdeps/ieee754/ldbl-128/s_lroundl.c
@@ -37,19 +37,19 @@ __lroundl (long double x)
   i0 &= 0x0000ffffffffffffLL;
   i0 |= 0x0001000000000000LL;
 
-  if (j0 < 48)
+  if (j0 < (int32_t) (8 * sizeof (long int)) - 1)
     {
-      if (j0 < 0)
-	return j0 < -1 ? 0 : sign;
-      else
+      if (j0 < 48)
 	{
-	  i0 += 0x0000800000000000LL >> j0;
-	  result = i0 >> (48 - j0);
+	  if (j0 < 0)
+	    return j0 < -1 ? 0 : sign;
+	  else
+	    {
+	      i0 += 0x0000800000000000LL >> j0;
+	      result = i0 >> (48 - j0);
+	    }
 	}
-    }
-  else if (j0 < (int32_t) (8 * sizeof (long int)) - 1)
-    {
-      if (j0 >= 112)
+      else if (j0 >= 112)
 	result = ((long int) i0 << (j0 - 48)) | (i1 << (j0 - 112));
       else
 	{

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]