OSDN Git Service

PR tree-optimization/23744
authorbaldrick <baldrick@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 29 Nov 2006 16:00:07 +0000 (16:00 +0000)
committerbaldrick <baldrick@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 29 Nov 2006 16:00:07 +0000 (16:00 +0000)
* tree-vrp.c (vrp_meet): do not require ranges to intersect.
* testsuite/gcc.dg/tree-ssa/pr23744.c: new test.
* testsuite/gcc.dg/tree-ssa/update-threading.c: xfail.

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

gcc/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr23744.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/update-threading.c
gcc/tree-vrp.c

index 30b8410..5bb4362 100644 (file)
@@ -1,3 +1,18 @@
+2006-11-29  Duncan Sands  <baldrick@free.fr>
+
+       PR tree-optimization/23744
+       * tree-vrp.c (vrp_meet): do not require ranges to intersect.
+
+2006-11-29  Duncan Sands  <baldrick@free.fr>
+
+       PR tree-optimization/23744
+       * testsuite/gcc.dg/tree-ssa/pr23744.c: new test.
+
+2006-11-29  Duncan Sands  <baldrick@free.fr>
+
+       PR tree-optimization/23744
+       * testsuite/gcc.dg/tree-ssa/update-threading.c: xfail.
+
 2006-11-29  Jie Zhang  <jie.zhang@analog.com>
 
        * doc/tm.texi (NO_PROFILE_COUNTERS): Document more accurately.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23744.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23744.c
new file mode 100644 (file)
index 0000000..8ba238c
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp1" } */
+
+int g (int i, int j)
+{
+  int t = 0;
+  int i1;
+
+  if (i == j)
+    t = 3;
+  for (i1 = 0; i1 < 10000; i1++) h();
+  if (t != 5)
+    return 0;
+  else
+    return 1;
+}
+
+/* { dg-final { scan-tree-dump-times "Folding predicate.*to 1" 1 "vrp1" } } */
+/* { dg-final { cleanup-tree-dump "vrp1" } } */
index e960d3a..e0e33b6 100644 (file)
@@ -20,5 +20,5 @@ main (int argc, char **argv)
     foo (((A) { ((!(i >> 4) ? 8 : 64 + (i >> 4)) << 8) + (i << 4) } ).a);
   exit (0);
 }
-/* { dg-final { scan-tree-dump-times "Invalid sum" 0 "optimized"} } */
+/* { dg-final { scan-tree-dump-times "Invalid sum" 0 "optimized" { xfail *-*-* } } } */
 /* { dg-final { cleanup-tree-dump "optimized" } } */
index fed86cb..b55480e 100644 (file)
@@ -3978,14 +3978,8 @@ vrp_visit_stmt (tree stmt, edge *taken_edge_p, tree *output_p)
 
 
 /* Meet operation for value ranges.  Given two value ranges VR0 and
-   VR1, store in VR0 the result of meeting VR0 and VR1.
-   
-   The meeting rules are as follows:
-
-   1- If VR0 and VR1 have an empty intersection, set VR0 to VR_VARYING.
-
-   2- If VR0 and VR1 have a non-empty intersection, set VR0 to the
-      union of VR0 and VR1.  */
+   VR1, store in VR0 a range that contains both VR0 and VR1.  This
+   may not be the smallest possible such range.  */
 
 static void
 vrp_meet (value_range_t *vr0, value_range_t *vr1)
@@ -4016,56 +4010,44 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1)
 
   if (vr0->type == VR_RANGE && vr1->type == VR_RANGE)
     {
-      /* If VR0 and VR1 have a non-empty intersection, compute the
-        union of both ranges.  */
-      if (value_ranges_intersect_p (vr0, vr1))
-       {
-         int cmp;
-         tree min, max;
-
-         /* The lower limit of the new range is the minimum of the
-            two ranges.  If they cannot be compared, the result is
-            VARYING.  */
-         cmp = compare_values (vr0->min, vr1->min);
-         if (cmp == 0 || cmp == 1)
-           min = vr1->min;
-         else if (cmp == -1)
-           min = vr0->min;
-         else
-           {
-             set_value_range_to_varying (vr0);
-             return;
-           }
-
-         /* Similarly, the upper limit of the new range is the
-            maximum of the two ranges.  If they cannot be compared,
-            the result is VARYING.  */
-         cmp = compare_values (vr0->max, vr1->max);
-         if (cmp == 0 || cmp == -1)
-           max = vr1->max;
-         else if (cmp == 1)
-           max = vr0->max;
-         else
-           {
-             set_value_range_to_varying (vr0);
-             return;
-           }
+      int cmp;
+      tree min, max;
+
+      /* Compute the convex hull of the ranges.  The lower limit of
+         the new range is the minimum of the two ranges.  If they
+        cannot be compared, then give up.  */
+      cmp = compare_values (vr0->min, vr1->min);
+      if (cmp == 0 || cmp == 1)
+        min = vr1->min;
+      else if (cmp == -1)
+        min = vr0->min;
+      else
+       goto give_up;
+
+      /* Similarly, the upper limit of the new range is the maximum
+         of the two ranges.  If they cannot be compared, then
+        give up.  */
+      cmp = compare_values (vr0->max, vr1->max);
+      if (cmp == 0 || cmp == -1)
+        max = vr1->max;
+      else if (cmp == 1)
+        max = vr0->max;
+      else
+       goto give_up;
 
-         /* The resulting set of equivalences is the intersection of
-            the two sets.  */
-         if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
-           bitmap_and_into (vr0->equiv, vr1->equiv);
-         else if (vr0->equiv && !vr1->equiv)
-           bitmap_clear (vr0->equiv);
+      /* The resulting set of equivalences is the intersection of
+        the two sets.  */
+      if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
+        bitmap_and_into (vr0->equiv, vr1->equiv);
+      else if (vr0->equiv && !vr1->equiv)
+        bitmap_clear (vr0->equiv);
 
-         set_value_range (vr0, vr0->type, min, max, vr0->equiv);
-       }
-      else
-       goto no_meet;
+      set_value_range (vr0, vr0->type, min, max, vr0->equiv);
     }
   else if (vr0->type == VR_ANTI_RANGE && vr1->type == VR_ANTI_RANGE)
     {
-      /* Two anti-ranges meet only if they are both identical.  */
+      /* Two anti-ranges meet only if their complements intersect.
+         Only handle the case of identical ranges.  */
       if (compare_values (vr0->min, vr1->min) == 0
          && compare_values (vr0->max, vr1->max) == 0
          && compare_values (vr0->min, vr0->max) == 0)
@@ -4078,13 +4060,13 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1)
            bitmap_clear (vr0->equiv);
        }
       else
-       goto no_meet;
+       goto give_up;
     }
   else if (vr0->type == VR_ANTI_RANGE || vr1->type == VR_ANTI_RANGE)
     {
-      /* A numeric range [VAL1, VAL2] and an anti-range ~[VAL3, VAL4]
-        meet only if the ranges have an empty intersection.  The
-        result of the meet operation is the anti-range.  */
+      /* For a numeric range [VAL1, VAL2] and an anti-range ~[VAL3, VAL4],
+         only handle the case where the ranges have an empty intersection.
+        The result of the meet operation is the anti-range.  */
       if (!symbolic_range_p (vr0)
          && !symbolic_range_p (vr1)
          && !value_ranges_intersect_p (vr0, vr1))
@@ -4103,17 +4085,17 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1)
            bitmap_clear (vr0->equiv);
        }
       else
-       goto no_meet;
+       goto give_up;
     }
   else
     gcc_unreachable ();
 
   return;
 
-no_meet:
-  /* The two range VR0 and VR1 do not meet.  Before giving up and
-     setting the result to VARYING, see if we can at least derive a
-     useful anti-range.  FIXME, all this nonsense about distinguishing
+give_up:
+  /* Failed to find an efficient meet.  Before giving up and setting
+     the result to VARYING, see if we can at least derive a useful
+     anti-range.  FIXME, all this nonsense about distinguishing
      anti-ranges from ranges is necessary because of the odd
      semantics of range_includes_zero_p and friends.  */
   if (!symbolic_range_p (vr0)