OSDN Git Service

PR tree-optimization/31739
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 1 May 2007 17:51:56 +0000 (17:51 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 1 May 2007 17:51:56 +0000 (17:51 +0000)
* tree-vrp.c (vrp_val_is_max): New static function.
(vrp_val_is_min): New static function.
(set_value_range_to_value): Use TYPE_{MAX,MIN}_VALUE rather than
copying the node.
(set_value_range): Use vrp_val_is_{max,min}.
(extract_range_from_assert): Likewise.
(extract_range_from_binary_expr): Likewise.
(extract_range_from_unary_expr): Likewise.
(dump_value_range, vrp_meet): Likewise.
(vrp_visit_phi_node): Likewise.
* tree.c (build_distinct_type_copy): Revert change of 2007-04-27.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@124334 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/tree-vrp.c
gcc/tree.c

index d284429..4d52f19 100644 (file)
@@ -1,3 +1,18 @@
+2007-05-01  Ian Lance Taylor  <iant@google.com>
+
+       PR tree-optimization/31739
+       * tree-vrp.c (vrp_val_is_max): New static function.
+       (vrp_val_is_min): New static function.
+       (set_value_range_to_value): Use TYPE_{MAX,MIN}_VALUE rather than
+       copying the node.
+       (set_value_range): Use vrp_val_is_{max,min}.
+       (extract_range_from_assert): Likewise.
+       (extract_range_from_binary_expr): Likewise.
+       (extract_range_from_unary_expr): Likewise.
+       (dump_value_range, vrp_meet): Likewise.
+       (vrp_visit_phi_node): Likewise.
+       * tree.c (build_distinct_type_copy): Revert change of 2007-04-27.
+
 2007-05-01  Mark Mitchell  <mark@codesourcery.com>
 
        * config/i386/gmon-sol2.c (size_t): New type.
index b165418..a9141d7 100644 (file)
@@ -202,6 +202,36 @@ is_overflow_infinity (tree val)
 }
 
 
+/* Return whether VAL is equal to the maximum value of its type.  This
+   will be true for a positive overflow infinity.  We can't do a
+   simple equality comparison with TYPE_MAX_VALUE because C typedefs
+   and Ada subtypes can produce types whose TYPE_MAX_VALUE is not ==
+   to the integer constant with the same value in the type.  */
+
+static inline bool
+vrp_val_is_max (tree val)
+{
+  tree type_max = TYPE_MAX_VALUE (TREE_TYPE (val));
+
+  return (val == type_max
+         || (type_max != NULL_TREE
+             && operand_equal_p (val, type_max, 0)));
+}
+
+/* Return whether VAL is equal to the minimum value of its type.  This
+   will be true for a negative overflow infinity.  */
+
+static inline bool
+vrp_val_is_min (tree val)
+{
+  tree type_min = TYPE_MIN_VALUE (TREE_TYPE (val));
+
+  return (val == type_min
+         || (type_min != NULL_TREE
+             && operand_equal_p (val, type_min, 0)));
+}
+
+
 /* Return true if ARG is marked with the nonnull attribute in the
    current function signature.  */
 
@@ -265,10 +295,7 @@ set_value_range (value_range_t *vr, enum value_range_type t, tree min,
       gcc_assert (min && max);
 
       if (INTEGRAL_TYPE_P (TREE_TYPE (min)) && t == VR_ANTI_RANGE)
-       gcc_assert ((min != TYPE_MIN_VALUE (TREE_TYPE (min))
-                    && !is_negative_overflow_infinity (min))
-                   || (max != TYPE_MAX_VALUE (TREE_TYPE (max))
-                       && !is_positive_overflow_infinity (max)));
+       gcc_assert (!vrp_val_is_min (min) || !vrp_val_is_max (max));
 
       cmp = compare_values (min, max);
       gcc_assert (cmp == 0 || cmp == -1 || cmp == -2);
@@ -336,8 +363,16 @@ set_value_range_to_value (value_range_t *vr, tree val)
   gcc_assert (is_gimple_min_invariant (val));
   if (is_overflow_infinity (val))
     {
-      val = copy_node (val);
-      TREE_OVERFLOW (val) = 0;
+      if (operand_equal_p (val, TYPE_MAX_VALUE (TREE_TYPE (val)), 0))
+       val = TYPE_MAX_VALUE (TREE_TYPE (val));
+      else
+       {
+#ifdef ENABLE_CHECKING
+         gcc_assert (operand_equal_p (val,
+                                      TYPE_MIN_VALUE (TREE_TYPE (val)), 0));
+#endif
+         val = TYPE_MIN_VALUE (TREE_TYPE (val));
+       }
     }
   set_value_range (vr, VR_RANGE, val, val, NULL);
 }
@@ -1173,10 +1208,8 @@ extract_range_from_assert (value_range_t *vr_p, tree expr)
       /* If MIN and MAX cover the whole range for their type, then
         just use the original LIMIT.  */
       if (INTEGRAL_TYPE_P (type)
-         && (min == TYPE_MIN_VALUE (type)
-             || is_negative_overflow_infinity (min))
-         && (max == TYPE_MAX_VALUE (type)
-             || is_positive_overflow_infinity (max)))
+         && vrp_val_is_min (min)
+         && vrp_val_is_max (max))
        min = max = limit;
 
       set_value_range (vr_p, VR_ANTI_RANGE, min, max, vr_p->equiv);
@@ -1411,7 +1444,7 @@ extract_range_from_assert (value_range_t *vr_p, tree expr)
            {
              gcc_assert (!is_positive_overflow_infinity (anti_max));
              if (needs_overflow_infinity (TREE_TYPE (anti_max))
-                 && anti_max == TYPE_MAX_VALUE (TREE_TYPE (anti_max)))
+                 && vrp_val_is_max (anti_max))
                {
                  if (!supports_overflow_infinity (TREE_TYPE (var_vr->min)))
                    {
@@ -1436,7 +1469,7 @@ extract_range_from_assert (value_range_t *vr_p, tree expr)
            {
              gcc_assert (!is_negative_overflow_infinity (anti_min));
              if (needs_overflow_infinity (TREE_TYPE (anti_min))
-                 && anti_min == TYPE_MIN_VALUE (TREE_TYPE (anti_min)))
+                 && vrp_val_is_min (anti_min))
                {
                  if (!supports_overflow_infinity (TREE_TYPE (var_vr->min)))
                    {
@@ -2025,10 +2058,8 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
      We learn nothing when we have INF and INF(OVF) on both sides.
      Note that we do accept [-INF, -INF] and [+INF, +INF] without
      overflow.  */
-  if ((min == TYPE_MIN_VALUE (TREE_TYPE (min))
-       || is_overflow_infinity (min))
-      && (max == TYPE_MAX_VALUE (TREE_TYPE (max))
-         || is_overflow_infinity (max)))
+  if ((vrp_val_is_min (min) || is_overflow_infinity (min))
+      && (vrp_val_is_max (max) || is_overflow_infinity (max)))
     {
       set_value_range_to_varying (vr);
       return;
@@ -2204,13 +2235,13 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
        min = negative_overflow_infinity (TREE_TYPE (expr));
       else if (is_negative_overflow_infinity (vr0.max))
        min = positive_overflow_infinity (TREE_TYPE (expr));
-      else if (vr0.max != TYPE_MIN_VALUE (TREE_TYPE (expr)))
+      else if (!vrp_val_is_min (vr0.max))
        min = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
       else if (needs_overflow_infinity (TREE_TYPE (expr)))
        {
          if (supports_overflow_infinity (TREE_TYPE (expr))
              && !is_overflow_infinity (vr0.min)
-             && vr0.min != TYPE_MIN_VALUE (TREE_TYPE (expr)))
+             && !vrp_val_is_min (vr0.min))
            min = positive_overflow_infinity (TREE_TYPE (expr));
          else
            {
@@ -2225,7 +2256,7 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
        max = negative_overflow_infinity (TREE_TYPE (expr));
       else if (is_negative_overflow_infinity (vr0.min))
        max = positive_overflow_infinity (TREE_TYPE (expr));
-      else if (vr0.min != TYPE_MIN_VALUE (TREE_TYPE (expr)))
+      else if (!vrp_val_is_min (vr0.min))
        max = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
       else if (needs_overflow_infinity (TREE_TYPE (expr)))
        {
@@ -2264,9 +2295,9 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
          useful range.  */
       if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (expr))
          && ((vr0.type == VR_RANGE
-              && vr0.min == TYPE_MIN_VALUE (TREE_TYPE (expr)))
+              && vrp_val_is_min (vr0.min))
              || (vr0.type == VR_ANTI_RANGE
-                 && vr0.min != TYPE_MIN_VALUE (TREE_TYPE (expr))
+                 && !vrp_val_is_min (vr0.min)
                  && !range_includes_zero_p (&vr0))))
        {
          set_value_range_to_varying (vr);
@@ -2277,7 +2308,7 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
         included negative values.  */
       if (is_overflow_infinity (vr0.min))
        min = positive_overflow_infinity (TREE_TYPE (expr));
-      else if (vr0.min != TYPE_MIN_VALUE (TREE_TYPE (expr)))
+      else if (!vrp_val_is_min (vr0.min))
        min = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
       else if (!needs_overflow_infinity (TREE_TYPE (expr)))
        min = TYPE_MAX_VALUE (TREE_TYPE (expr));
@@ -2291,7 +2322,7 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
 
       if (is_overflow_infinity (vr0.max))
        max = positive_overflow_infinity (TREE_TYPE (expr));
-      else if (vr0.max != TYPE_MIN_VALUE (TREE_TYPE (expr)))
+      else if (!vrp_val_is_min (vr0.max))
        max = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
       else if (!needs_overflow_infinity (TREE_TYPE (expr)))
        max = TYPE_MAX_VALUE (TREE_TYPE (expr));
@@ -2987,24 +3018,22 @@ dump_value_range (FILE *file, value_range_t *vr)
 
       fprintf (file, "%s[", (vr->type == VR_ANTI_RANGE) ? "~" : "");
 
-      if (INTEGRAL_TYPE_P (type)
-         && !TYPE_UNSIGNED (type)
-         && vr->min == TYPE_MIN_VALUE (type))
-       fprintf (file, "-INF");
-      else if (needs_overflow_infinity (type)
-              && is_negative_overflow_infinity (vr->min))
+      if (is_negative_overflow_infinity (vr->min))
        fprintf (file, "-INF(OVF)");
+      else if (INTEGRAL_TYPE_P (type)
+              && !TYPE_UNSIGNED (type)
+              && vrp_val_is_min (vr->min))
+       fprintf (file, "-INF");
       else
        print_generic_expr (file, vr->min, 0);
 
       fprintf (file, ", ");
 
-      if (INTEGRAL_TYPE_P (type)
-         && vr->max == TYPE_MAX_VALUE (type))
-       fprintf (file, "+INF");
-      else if (needs_overflow_infinity (type)
-              && is_positive_overflow_infinity (vr->max))
+      if (is_positive_overflow_infinity (vr->max))
        fprintf (file, "+INF(OVF)");
+      else if (INTEGRAL_TYPE_P (type)
+              && vrp_val_is_max (vr->max))
+       fprintf (file, "+INF");
       else
        print_generic_expr (file, vr->max, 0);
 
@@ -5157,10 +5186,8 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1)
 
       /* Check for useless ranges.  */
       if (INTEGRAL_TYPE_P (TREE_TYPE (min))
-         && ((min == TYPE_MIN_VALUE (TREE_TYPE (min))
-              || is_overflow_infinity (min))
-             && (max == TYPE_MAX_VALUE (TREE_TYPE (max))
-                 || is_overflow_infinity (max))))
+         && ((vrp_val_is_min (min) || is_overflow_infinity (min))
+             && (vrp_val_is_max (max) || is_overflow_infinity (max))))
        goto give_up;
 
       /* The resulting set of equivalences is the intersection of
@@ -5348,9 +5375,7 @@ vrp_visit_phi_node (tree phi)
            {
              /* If we will end up with a (-INF, +INF) range, set it
                 to VARYING.  */
-             if (is_positive_overflow_infinity (vr_result.max)
-                 || (vr_result.max
-                     == TYPE_MAX_VALUE (TREE_TYPE (vr_result.max))))
+             if (vrp_val_is_max (vr_result.max))
                goto varying;
 
              if (!needs_overflow_infinity (TREE_TYPE (vr_result.min)))
@@ -5368,9 +5393,7 @@ vrp_visit_phi_node (tree phi)
            {
              /* If we will end up with a (-INF, +INF) range, set it
                 to VARYING.  */
-             if (is_negative_overflow_infinity (vr_result.min)
-                 || (vr_result.min
-                     == TYPE_MIN_VALUE (TREE_TYPE (vr_result.min))))
+             if (vrp_val_is_min (vr_result.min))
                goto varying;
 
              if (!needs_overflow_infinity (TREE_TYPE (vr_result.max)))
index 472477c..b636de6 100644 (file)
@@ -4173,15 +4173,10 @@ build_distinct_type_copy (tree type)
   /* Make it its own variant.  */
   TYPE_MAIN_VARIANT (t) = t;
   TYPE_NEXT_VARIANT (t) = 0;
-  
-  /* VRP assumes that TREE_TYPE (TYPE_MIN_VALUE (type)) == type.  */
-  if (INTEGRAL_TYPE_P (t) || SCALAR_FLOAT_TYPE_P (t))
-    {
-      if (TYPE_MIN_VALUE (t) != NULL_TREE)
-       TYPE_MIN_VALUE (t) = fold_convert (t, TYPE_MIN_VALUE (t));
-      if (TYPE_MAX_VALUE (t) != NULL_TREE)
-       TYPE_MAX_VALUE (t) = fold_convert (t, TYPE_MAX_VALUE (t));
-    }
+
+  /* Note that it is now possible for TYPE_MIN_VALUE to be a value
+     whose TREE_TYPE is not t.  This can also happen in the Ada
+     frontend when using subtypes.  */
 
   return t;
 }