]> gcc.gnu.org Git - gcc.git/commitdiff
re PR tree-optimization/31605 (VRP eliminates a useful test due with conversion from...
authorIan Lance Taylor <iant@google.com>
Tue, 24 Apr 2007 22:24:01 +0000 (22:24 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Tue, 24 Apr 2007 22:24:01 +0000 (22:24 +0000)
./: PR tree-optimization/31605
* tree-vrp.c (set_value_range): Check that min and max are not
both overflow infinities.
(set_value_range_to_value): New static function.
(extract_range_from_binary_expr): Call set_value_range_to_value.
(extract_range_from_cond_expr): Likewise.
(extract_range_from_expr): Likewise.
(extract_range_from_unary_expr): Likewise.  Don't create a range
which overflows on both sides.
(vrp_meet): Check for a useless range.
(vrp_visit_phi_node): If we see a constant which looks like an
overflow infinity, turn off the TREE_OVERFLOW flag.
testsuite/:
PR tree-optimizatoin/31605
* gcc.c-torture/execute/pr31605.c: New test.

From-SVN: r124128

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr31605.c [new file with mode: 0644]
gcc/tree-vrp.c

index 0826135faacd97c2c4b8f6ca9cd7f246f25fbd57..ba37f732c2a536f999bfb24a72830fa0b10c7322 100644 (file)
@@ -1,3 +1,18 @@
+2007-04-24  Ian Lance Taylor  <iant@google.com>
+
+       PR tree-optimization/31605
+       * tree-vrp.c (set_value_range): Check that min and max are not
+       both overflow infinities.
+       (set_value_range_to_value): New static function.
+       (extract_range_from_binary_expr): Call set_value_range_to_value.
+       (extract_range_from_cond_expr): Likewise.
+       (extract_range_from_expr): Likewise.
+       (extract_range_from_unary_expr): Likewise.  Don't create a range
+       which overflows on both sides.
+       (vrp_meet): Check for a useless range.
+       (vrp_visit_phi_node): If we see a constant which looks like an
+       overflow infinity, turn off the TREE_OVERFLOW flag.
+
 2007-04-24  Ian Lance Taylor  <iant@google.com>
 
        * flow.c (elim_reg_cond): Handle a comparison of a subreg.
index 3195c15539ef01f8ee36bf83418deb496cef6204..cc0033e62b8d6ae109ad774e079e097296f457ae 100644 (file)
@@ -1,3 +1,8 @@
+2007-04-24  Ian Lance Taylor  <iant@google.com>
+
+       PR tree-optimizatoin/31605
+       * gcc.c-torture/execute/pr31605.c: New test.
+
 2007-04-24  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
 
        PR fortran/31587
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr31605.c b/gcc/testsuite/gcc.c-torture/execute/pr31605.c
new file mode 100644 (file)
index 0000000..12a57ac
--- /dev/null
@@ -0,0 +1,13 @@
+void put_field (unsigned int start, unsigned int len)
+{
+  int cur_bitshift = ((start + len) % 8) - 8;
+  if (cur_bitshift > -8)
+    exit (0);
+}
+
+int
+main ()
+{
+  put_field (0, 1);
+  abort ();
+}
index e35a6e9008d0ed065d846559ddf91c4283795622..78675e723241214f1ba53d2ff8e75d2a269df407 100644 (file)
@@ -272,6 +272,10 @@ set_value_range (value_range_t *vr, enum value_range_type t, tree min,
 
       cmp = compare_values (min, max);
       gcc_assert (cmp == 0 || cmp == -1 || cmp == -2);
+
+      if (needs_overflow_infinity (TREE_TYPE (min)))
+       gcc_assert (!is_overflow_infinity (min)
+                   || !is_overflow_infinity (max));
     }
 
   if (t == VR_UNDEFINED || t == VR_VARYING)
@@ -320,6 +324,23 @@ set_value_range_to_varying (value_range_t *vr)
     bitmap_clear (vr->equiv);
 }
 
+/* Set value range VR to a single value.  This function is only called
+   with values we get from statements, and exists to clear the
+   TREE_OVERFLOW flag so that we don't think we have an overflow
+   infinity when we shouldn't.  */
+
+static inline void
+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;
+    }
+  set_value_range (vr, VR_RANGE, val, val, NULL);
+}
+
 /* Set value range VR to a non-negative range of type TYPE.
    OVERFLOW_INFINITY indicates whether to use a overflow infinity
    rather than TYPE_MAX_VALUE; this should be true if we determine
@@ -1646,7 +1667,7 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
   if (TREE_CODE (op0) == SSA_NAME)
     vr0 = *(get_value_range (op0));
   else if (is_gimple_min_invariant (op0))
-    set_value_range (&vr0, VR_RANGE, op0, op0, NULL);
+    set_value_range_to_value (&vr0, op0);
   else
     set_value_range_to_varying (&vr0);
 
@@ -1654,7 +1675,7 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
   if (TREE_CODE (op1) == SSA_NAME)
     vr1 = *(get_value_range (op1));
   else if (is_gimple_min_invariant (op1))
-    set_value_range (&vr1, VR_RANGE, op1, op1, NULL);
+    set_value_range_to_value (&vr1, op1);
   else
     set_value_range_to_varying (&vr1);
 
@@ -2053,7 +2074,7 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
   if (TREE_CODE (op0) == SSA_NAME)
     vr0 = *(get_value_range (op0));
   else if (is_gimple_min_invariant (op0))
-    set_value_range (&vr0, VR_RANGE, op0, op0, NULL);
+    set_value_range_to_value (&vr0, op0);
   else
     set_value_range_to_varying (&vr0);
 
@@ -2185,7 +2206,9 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
        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)))
+         if (supports_overflow_infinity (TREE_TYPE (expr))
+             && !is_overflow_infinity (vr0.min)
+             && vr0.min != TYPE_MIN_VALUE (TREE_TYPE (expr)))
            min = positive_overflow_infinity (TREE_TYPE (expr));
          else
            {
@@ -2361,6 +2384,18 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
       if (needs_overflow_infinity (TREE_TYPE (expr)))
        {
          gcc_assert (code != NEGATE_EXPR && code != ABS_EXPR);
+
+         /* If both sides have overflowed, we don't know
+            anything.  */
+         if ((is_overflow_infinity (vr0.min)
+              || TREE_OVERFLOW (min))
+             && (is_overflow_infinity (vr0.max)
+                 || TREE_OVERFLOW (max)))
+           {
+             set_value_range_to_varying (vr);
+             return;
+           }
+
          if (is_overflow_infinity (vr0.min))
            min = vr0.min;
          else if (TREE_OVERFLOW (min))
@@ -2422,7 +2457,7 @@ extract_range_from_cond_expr (value_range_t *vr, tree expr)
   if (TREE_CODE (op0) == SSA_NAME)
     vr0 = *(get_value_range (op0));
   else if (is_gimple_min_invariant (op0))
-    set_value_range (&vr0, VR_RANGE, op0, op0, NULL);
+    set_value_range_to_value (&vr0, op0);
   else
     set_value_range_to_varying (&vr0);
 
@@ -2430,7 +2465,7 @@ extract_range_from_cond_expr (value_range_t *vr, tree expr)
   if (TREE_CODE (op1) == SSA_NAME)
     vr1 = *(get_value_range (op1));
   else if (is_gimple_min_invariant (op1))
-    set_value_range (&vr1, VR_RANGE, op1, op1, NULL);
+    set_value_range_to_value (&vr1, op1);
   else
     set_value_range_to_varying (&vr1);
 
@@ -2494,7 +2529,7 @@ extract_range_from_expr (value_range_t *vr, tree expr)
   else if (TREE_CODE_CLASS (code) == tcc_comparison)
     extract_range_from_comparison (vr, expr);
   else if (is_gimple_min_invariant (expr))
-    set_value_range (vr, VR_RANGE, expr, expr, NULL);
+    set_value_range_to_value (vr, expr);
   else
     set_value_range_to_varying (vr);
 
@@ -5106,6 +5141,14 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1)
       else
        goto give_up;
 
+      /* 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))))
+       goto give_up;
+
       /* The resulting set of equivalences is the intersection of
         the two sets.  */
       if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
@@ -5235,6 +5278,12 @@ vrp_visit_phi_node (tree phi)
            }
          else
            {
+             if (is_overflow_infinity (arg))
+               {
+                 arg = copy_node (arg);
+                 TREE_OVERFLOW (arg) = 0;
+               }
+
              vr_arg.type = VR_RANGE;
              vr_arg.min = arg;
              vr_arg.max = arg;
This page took 0.148709 seconds and 5 git commands to generate.