On Oct 18, 2013, at 6:11 AM, Kenneth Zadeck <zad...@naturalbridge.com> wrote:
>>> Does this look ok?  Kenny, can you double check the cases, think I have 
>>> them right, but?  a double check would be good.
>> That works for me.
>> 
> i talked to mike about this last night, but did not follow up with an email 
> until now.   The problem is that this code is wrong!!!   He is working to fix 
> that and so i would expect something from him later (tomorrow for those in 
> europe).

Ok, updated the patch, here is what I checked in:

diff --git a/gcc/wide-int.h b/gcc/wide-int.h
index 2ff130b..738ae11 100644
--- a/gcc/wide-int.h
+++ b/gcc/wide-int.h
@@ -185,7 +185,9 @@ along with GCC; see the file COPYING3.  If not see
 
      assuming t is a int_cst.
 
-   Note that the bits above the precision are not defined and the
+   Note, the bits past the precision up to the nearest HOST_WDE_INT
+   boundary are defined to be copies of the top bit of the value,
+   however the bits above those defined bits not defined and the
    algorithms used here are careful not to depend on their value.  In
    particular, values that come in from rtx constants may have random
    bits.  When the precision is 0, all the bits in the LEN elements of
@@ -1283,7 +1285,7 @@ namespace wi
     static const bool host_dependent_precision = false;
     static unsigned int get_precision (const wi::hwi_with_prec &);
     static wi::storage_ref decompose (HOST_WIDE_INT *, unsigned int,
-    const wi::hwi_with_prec &);
+                                     const wi::hwi_with_prec &);
   };
 }
 
@@ -1461,12 +1463,26 @@ wi::ne_p (const T1 &x, const T2 &y)
 inline bool
 wi::lts_p (const wide_int_ref &x, const wide_int_ref &y)
 {
-  if (x.precision <= HOST_BITS_PER_WIDE_INT
-      && y.precision <= HOST_BITS_PER_WIDE_INT)
-    return x.slow () < y.slow ();
-  else
-    return lts_p_large (x.val, x.len, x.precision, y.val, y.len,
-                       y.precision);
+  // We optimize x < y, where y is 64 or fewer bits.
+  // We have to be careful to not allow comparison to a large positive
+  // unsigned value like 0x8000000000000000, those would be encoded
+  // with a y.len == 2.
+  if (y.precision <= HOST_BITS_PER_WIDE_INT
+      && y.len == 1)
+    {
+      // If x fits directly into a shwi, we can compare directly.
+      if (wi::fits_shwi_p (x))
+       return x.slow () < y.slow ();
+      // If x doesn't fit and is negative, then it must be more
+      // negative than any value in y, and hence smaller than y.
+      if (neg_p (x, SIGNED))
+       return true;
+      // If x is positve, then it must be larger than any value in y,
+      // and hence greater than y.
+      return false;
+    }
+  return lts_p_large (x.val, x.len, x.precision, y.val, y.len,
+                     y.precision);
 }
 
 /* Return true if X < Y when both are treated as unsigned values.  */

Reply via email to