This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

Re: [wide-int] Fix signed min / -1 quotient


This is fine with me.

kenny

On 04/24/2014 10:34 AM, Richard Sandiford wrote:
For signed min / -1 we set the overflow flag (good) but also returned a
quotient of 0.  It should be 0x80...0 instead.  Since that's also the
value of the original dividend, we can just copy the representation over.

The value for division by 0 is probably pretty arbitrary.  double-int.c
seems to treat it as division by one:

   if (hden == 0 && lden == 0)
     overflow = 1, lden = 1;

and while not important, it has the nice feature that here too we could
just copy the original dividend, rather than treat it differently from
signed min / -1.

This fixes libjava's Divide_1, which was the last remaining regression
on x86_64-linux-gnu.  I have a couple of other patches queued up, but
I'm still running tests to compare the asm output for the gcc and g++
testsuites on a range of targets.  (FWIW, the first round of these
tests picked up the same bug as Divide_1, in the output for
gcc.c-torture/compile/20010404-1.c.)

OK to install?

Thanks,
Richard


Index: gcc/wide-int.cc
===================================================================
--- gcc/wide-int.cc	2014-04-24 09:51:08.056774754 +0100
+++ gcc/wide-int.cc	2014-04-24 11:52:35.996541888 +0100
@@ -1726,8 +1726,10 @@ wi::divmod_internal (HOST_WIDE_INT *quot
        && wi::only_sign_bit_p (dividend))
      overflow = true;
- /* If overflow is set, just get out. There will only be grief by
-     continuing.  */
+  /* Handle the overflow cases.  Viewed as unsigned value, the quotient of
+     (signed min / -1) has the same representation as the orignal dividend.
+     We have traditionally made division by zero act as division by one,
+     so there too we use the original dividend.  */
    if (overflow)
      {
        if (remainder)
@@ -1738,8 +1741,9 @@ wi::divmod_internal (HOST_WIDE_INT *quot
        if (oflow != 0)
  	*oflow = true;
        if (quotient)
-	quotient[0] = 0;
-      return 1;
+	for (unsigned int i = 0; i < dividend_len; ++i)
+	  quotient[i] = dividend_val[i];
+      return dividend_len;
      }
if (oflow)



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