re PR middle-end/49840 (New test failures)
authorRichard Guenther <rguenther@suse.de>
Tue, 26 Jul 2011 12:37:00 +0000 (12:37 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 26 Jul 2011 12:37:00 +0000 (12:37 +0000)
2011-07-26  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/49840
* tree-vrp.c (range_fits_type_p): Properly handle full
double-int precision.

From-SVN: r176790

gcc/ChangeLog
gcc/tree-vrp.c

index 7825a25882fd3edcb441b97c57060eff916c345c..74f58cdde69c7f3a744bfada1c09db0c706e357a 100644 (file)
@@ -1,3 +1,9 @@
+2011-07-26  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/49840
+       * tree-vrp.c (range_fits_type_p): Properly handle full
+       double-int precision.
+
 2011-07-26  Martin Jambor  <mjambor@suse.cz>
 
        PR bootstrap/49786
index c6a4c4476ff496bb03528077b7aec781c885bff8..1756dd25bd35c3ab18e5d9afa1e10ef7c7d79cb4 100644 (file)
@@ -7423,18 +7423,40 @@ simplify_conversion_using_ranges (gimple stmt)
 static bool
 range_fits_type_p (value_range_t *vr, unsigned precision, bool unsigned_p)
 {
+  tree src_type;
+  unsigned src_precision;
   double_int tem;
 
-  /* We can only handle constant ranges.  */
+  /* We can only handle integral and pointer types.  */
+  src_type = TREE_TYPE (vr->min);
+  if (!INTEGRAL_TYPE_P (src_type)
+      && !POINTER_TYPE_P (src_type))
+    return false;
+
+  /* An extension is always fine, so is an identity transform.  */
+  src_precision = TYPE_PRECISION (TREE_TYPE (vr->min));
+  if (src_precision < precision
+      || (src_precision == precision
+         && TYPE_UNSIGNED (src_type) == unsigned_p))
+    return true;
+
+  /* Now we can only handle ranges with constant bounds.  */
   if (vr->type != VR_RANGE
       || TREE_CODE (vr->min) != INTEGER_CST
       || TREE_CODE (vr->max) != INTEGER_CST)
     return false;
 
+  /* For precision-preserving sign-changes the MSB of the double-int
+     has to be clear.  */
+  if (src_precision == precision
+      && (TREE_INT_CST_HIGH (vr->min) | TREE_INT_CST_HIGH (vr->max)) < 0)
+    return false;
+
+  /* Then we can perform the conversion on both ends and compare
+     the result for equality.  */
   tem = double_int_ext (tree_to_double_int (vr->min), precision, unsigned_p);
   if (!double_int_equal_p (tree_to_double_int (vr->min), tem))
     return false;
-
   tem = double_int_ext (tree_to_double_int (vr->max), precision, unsigned_p);
   if (!double_int_equal_p (tree_to_double_int (vr->max), tem))
     return false;