OSDN Git Service

2011-10-17 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / tree-vrp.c
index 604e7f0..248bc61 100644 (file)
@@ -2913,15 +2913,10 @@ extract_range_from_unary_expr_1 (value_range_t *vr,
         determining if it evaluates to NULL [0, 0] or non-NULL (~[0, 0]).  */
       if (POINTER_TYPE_P (type))
        {
-         if (CONVERT_EXPR_CODE_P (code))
-           {
-             if (range_is_nonnull (&vr0))
-               set_value_range_to_nonnull (vr, type);
-             else if (range_is_null (&vr0))
-               set_value_range_to_null (vr, type);
-             else
-               set_value_range_to_varying (vr);
-           }
+         if (range_is_nonnull (&vr0))
+           set_value_range_to_nonnull (vr, type);
+         else if (range_is_null (&vr0))
+           set_value_range_to_null (vr, type);
          else
            set_value_range_to_varying (vr);
          return;
@@ -7288,10 +7283,17 @@ simplify_conversion_using_ranges (gimple stmt)
                              TYPE_UNSIGNED (TREE_TYPE (middleop)));
   middlemax = double_int_ext (innermax, TYPE_PRECISION (TREE_TYPE (middleop)),
                              TYPE_UNSIGNED (TREE_TYPE (middleop)));
-  /* If the middle values do not represent a proper range fail.  */
-  if (double_int_cmp (middlemin, middlemax,
-                     TYPE_UNSIGNED (TREE_TYPE (middleop))) > 0)
+  /* If the middle values are not equal to the original values fail.
+     But only if the inner cast truncates (thus we ignore differences
+     in extension to handle the case going from a range to an anti-range
+     and back).  */
+  if ((TYPE_PRECISION (TREE_TYPE (innerop))
+       > TYPE_PRECISION (TREE_TYPE (middleop)))
+      && (!double_int_equal_p (innermin, middlemin)
+         || !double_int_equal_p (innermax, middlemax)))
     return false;
+  /* Require that the final conversion applied to both the original
+     and the intermediate range produces the same result.  */
   if (!double_int_equal_p (double_int_ext (middlemin,
                                           TYPE_PRECISION (finaltype),
                                           TYPE_UNSIGNED (finaltype)),