OSDN Git Service

./:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 17 Apr 2007 05:33:38 +0000 (05:33 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 17 Apr 2007 05:33:38 +0000 (05:33 +0000)
PR tree-optimization/31522
* tree-vrp.c (vr_phi_edge_counts): New static variable.
(vrp_initialize): Allocate vr_phi_edge_counts.
(vrp_visit_phi_node): Don't push to infinity if we saw a new
executable edge.  Drop test for all constants.
(vrp_finalize): Free vrp_phi_edge_counts.
testsuite/:
PR tree-optimization/31522
* gcc.dg/Wstrict-overflow-16.c: New test.

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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/Wstrict-overflow-16.c [new file with mode: 0644]
gcc/tree-vrp.c

index 5ff8fab..2003af8 100644 (file)
@@ -1,5 +1,12 @@
 2007-04-16  Ian Lance Taylor  <iant@google.com>
 
+       PR tree-optimization/31522
+       * tree-vrp.c (vr_phi_edge_counts): New static variable.
+       (vrp_initialize): Allocate vr_phi_edge_counts.
+       (vrp_visit_phi_node): Don't push to infinity if we saw a new
+       executable edge.  Drop test for all constants.
+       (vrp_finalize): Free vrp_phi_edge_counts.
+
        * doc/cpp.texi (Common Predefined Macros): Clarify description of
        __GNUC_GNU_INLINE__ and __GNUC_STDC_INLINE__.
 
index 82ea641..ea93fcc 100644 (file)
@@ -1,3 +1,8 @@
+2007-04-16  Ian Lance Taylor  <iant@google.com>
+
+       PR tree-optimization/31522
+       * gcc.dg/Wstrict-overflow-16.c: New test.
+
 2007-04-17  Kazu Hirata  <kazu@codesourcery.com>
 
        * gcc.dg/cpp/_Pragma6.c: Skip on fido-*-* and m68k-*-*.
diff --git a/gcc/testsuite/gcc.dg/Wstrict-overflow-16.c b/gcc/testsuite/gcc.dg/Wstrict-overflow-16.c
new file mode 100644 (file)
index 0000000..e8c31cf
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrict-overflow -O2 -Wstrict-overflow" } */
+
+/* From PR 31522.  */
+
+int f (int x) {
+  int y;
+  if (x <= 4) y = 1;
+  else y = x / 4;
+  return y <= 0;
+}
index ff07939..43cd0eb 100644 (file)
@@ -95,6 +95,11 @@ static sbitmap blocks_visited;
    of values that SSA name N_I may take.  */
 static value_range_t **vr_value;
 
+/* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the
+   number of executable edges we saw the last time we visited the
+   node.  */
+static int *vr_phi_edge_counts;
+
 
 /* Return whether TYPE should use an overflow infinity distinct from
    TYPE_{MIN,MAX}_VALUE.  We use an overflow infinity value to
@@ -4433,6 +4438,7 @@ vrp_initialize (void)
   basic_block bb;
 
   vr_value = XCNEWVEC (value_range_t *, num_ssa_names);
+  vr_phi_edge_counts = XCNEWVEC (int, num_ssa_names);
 
   FOR_EACH_BB (bb)
     {
@@ -5185,7 +5191,7 @@ vrp_visit_phi_node (tree phi)
   tree lhs = PHI_RESULT (phi);
   value_range_t *lhs_vr = get_value_range (lhs);
   value_range_t vr_result = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
-  bool all_const = true;
+  int edges, old_edges;
 
   copy_value_range (&vr_result, lhs_vr);
 
@@ -5195,6 +5201,7 @@ vrp_visit_phi_node (tree phi)
       print_generic_expr (dump_file, phi, dump_flags);
     }
 
+  edges = 0;
   for (i = 0; i < PHI_NUM_ARGS (phi); i++)
     {
       edge e = PHI_ARG_EDGE (phi, i);
@@ -5212,10 +5219,11 @@ vrp_visit_phi_node (tree phi)
          tree arg = PHI_ARG_DEF (phi, i);
          value_range_t vr_arg;
 
+         ++edges;
+
          if (TREE_CODE (arg) == SSA_NAME)
            {
              vr_arg = *(get_value_range (arg));
-             all_const = false;
            }
          else
            {
@@ -5244,11 +5252,16 @@ vrp_visit_phi_node (tree phi)
   if (vr_result.type == VR_VARYING)
     goto varying;
 
+  old_edges = vr_phi_edge_counts[SSA_NAME_VERSION (lhs)];
+  vr_phi_edge_counts[SSA_NAME_VERSION (lhs)] = edges;
+
   /* To prevent infinite iterations in the algorithm, derive ranges
      when the new value is slightly bigger or smaller than the
-     previous one.  */
+     previous one.  We don't do this if we have seen a new executable
+     edge; this helps us avoid an overflow infinity for conditionals
+     which are not in a loop.  */
   if (lhs_vr->type == VR_RANGE && vr_result.type == VR_RANGE
-      && !all_const)
+      && edges <= old_edges)
     {
       if (!POINTER_TYPE_P (TREE_TYPE (lhs)))
        {
@@ -5827,10 +5840,12 @@ vrp_finalize (void)
 
   free (single_val_range);
   free (vr_value);
+  free (vr_phi_edge_counts);
 
   /* So that we can distinguish between VRP data being available
      and not available.  */
   vr_value = NULL;
+  vr_phi_edge_counts = NULL;
 }