OSDN Git Service

* tree-vrp.c (test_for_singularity): Extracted from ...
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 28 Jul 2005 16:12:03 +0000 (16:12 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 28 Jul 2005 16:12:03 +0000 (16:12 +0000)
        (simplify_cond_using_ranges): Attempt to simplify a relational
        test to NE_EXPR.  Dump information when a COND_EXPR is simplified.

        * gcc.dg/tree-ssa/vrp17.c: Update expected output.
        * gcc.dg/tree-ssa/vrp18.c: New test.

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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/vrp17.c
gcc/testsuite/gcc.dg/tree-ssa/vrp18.c [new file with mode: 0644]
gcc/tree-vrp.c

index 404286c..e9f5558 100644 (file)
@@ -1,3 +1,9 @@
+2005-07-28  Jeff Law  <law@redhat.com>
+
+        * tree-vrp.c (test_for_singularity): Extracted from  ...
+        (simplify_cond_using_ranges): Attempt to simplify a relational
+        test to NE_EXPR.  Dump information when a COND_EXPR is simplified.
+
 2005-07-28  Dorit Nuzman  <dorit@il.ibm.com>
 
        PR tree-optimization/22506
index 16c797a..d2382f3 100644 (file)
@@ -1,3 +1,8 @@
+2005-07-28  Jeff Law  <law@redhat.com>
+
+       * gcc.dg/tree-ssa/vrp17.c: Update expected output.
+       * gcc.dg/tree-ssa/vrp18.c: New test.
+
 2005-07-28  Dorit Nuzman  <dorit@il.ibm.com>
 
        * gcc.dg/vect/vect-reduc-1char.c: Fix data to fit in char.
index 3df4acd..217929d 100644 (file)
@@ -27,6 +27,6 @@ gimplify_for_stmt (tree stmt)
     abort ();
 }
 
-/* { dg-final { scan-tree-dump-times "== 3" 1 "vrp" } } */
+/* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp" } } */
 /* { dg-final { cleanup-tree-dump "vrp" } } */
 
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp18.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp18.c
new file mode 100644 (file)
index 0000000..366c079
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp" } */
+
+static int blocksize = 4096;
+
+int bar (int);
+
+void foo (void)
+{
+  int toread;
+  int bytes;
+  static char eof_reached = 0;
+
+  toread = blocksize;
+  bytes = 1;
+
+  while (toread != 0)
+    {
+      bytes = bar (toread);
+      if (bytes <= 0)
+        {
+          if (bytes < 0)
+            continue;
+          break;
+        }
+      toread -= bytes;
+    }
+
+  if (bytes == 0)
+    eof_reached = 1;
+}
+
+/* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp" } } */
+/* { dg-final { cleanup-tree-dump "vrp" } } */
index af79ba4..be5f8b8 100644 (file)
@@ -3616,6 +3616,66 @@ simplify_abs_using_ranges (tree stmt, tree rhs)
     }
 }
 
+/* We are comparing trees OP0 and OP1 using COND_CODE.  OP0 has
+   a known value range VR.
+
+   If there is one and only one value which will satisfy the
+   conditional, then return that value.  Else return NULL.  */
+
+static tree
+test_for_singularity (enum tree_code cond_code, tree op0,
+                     tree op1, value_range_t *vr)
+{
+  tree min = NULL;
+  tree max = NULL;
+
+  /* Extract minimum/maximum values which satisfy the
+     the conditional as it was written.  */
+  if (cond_code == LE_EXPR || cond_code == LT_EXPR)
+    {
+      min = TYPE_MIN_VALUE (TREE_TYPE (op0));
+
+      max = op1;
+      if (cond_code == LT_EXPR)
+       {
+         tree one = build_int_cst (TREE_TYPE (op0), 1);
+         max = fold (build (MINUS_EXPR, TREE_TYPE (op0), max, one));
+       }
+    }
+  else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
+    {
+      max = TYPE_MAX_VALUE (TREE_TYPE (op0));
+
+      min = op1;
+      if (cond_code == GT_EXPR)
+       {
+         tree one = build_int_cst (TREE_TYPE (op0), 1);
+         max = fold (build (PLUS_EXPR, TREE_TYPE (op0), max, one));
+       }
+    }
+
+  /* Now refine the minimum and maximum values using any
+     value range information we have for op0.  */
+  if (min && max)
+    {
+      if (compare_values (vr->min, min) == -1)
+       min = min;
+      else
+       min = vr->min;
+      if (compare_values (vr->max, max) == 1)
+       max = max;
+      else
+       max = vr->max;
+
+      /* If the new min/max values have converged to a
+        single value, then there is only one value which
+        can satisfy the condition, return that value.  */
+      if (min == max && is_gimple_min_invariant (min))
+       return min;
+    }
+  return NULL;
+}
+
 /* Simplify a conditional using a relational operator to an equality
    test if the range information indicates only one value can satisfy
    the original conditional.  */
@@ -3640,58 +3700,56 @@ simplify_cond_using_ranges (tree stmt)
         able to simplify this conditional. */
       if (vr->type == VR_RANGE)
        {
-         tree min = NULL;
-         tree max = NULL;
+         tree new = test_for_singularity (cond_code, op0, op1, vr);
 
-         /* Extract minimum/maximum values which satisfy the
-            the conditional as it was written.  */
-         if (cond_code == LE_EXPR || cond_code == LT_EXPR)
+         if (new)
            {
-             min = TYPE_MIN_VALUE (TREE_TYPE (op0));
-
-             max = op1;
-             if (cond_code == LT_EXPR)
+             if (dump_file)
                {
-                 tree one = build_int_cst (TREE_TYPE (op0), 1);
-                 max = fold (build (MINUS_EXPR, TREE_TYPE (op0), max, one));
+                 fprintf (dump_file, "Simplified relational ");
+                 print_generic_expr (dump_file, cond, 0);
+                 fprintf (dump_file, " into ");
                }
-           }
-         else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
-           {
-             max = TYPE_MAX_VALUE (TREE_TYPE (op0));
 
-             min = op1;
-             if (cond_code == GT_EXPR)
+             COND_EXPR_COND (stmt)
+               = build (EQ_EXPR, boolean_type_node, op0, new);
+             update_stmt (stmt);
+
+             if (dump_file)
                {
-                 tree one = build_int_cst (TREE_TYPE (op0), 1);
-                 max = fold (build (PLUS_EXPR, TREE_TYPE (op0), max, one));
+                 print_generic_expr (dump_file, COND_EXPR_COND (stmt), 0);
+                 fprintf (dump_file, "\n");
                }
+             return;
+
            }
 
-         /* Now refine the minimum and maximum values using any
-            value range information we have for op0.  */
-         if (min && max)
+         /* Try again after inverting the condition.  We only deal
+            with integral types here, so no need to worry about
+            issues with inverting FP comparisons.  */
+         cond_code = invert_tree_comparison (cond_code, false);
+         new = test_for_singularity (cond_code, op0, op1, vr);
+
+         if (new)
            {
-             if (compare_values (vr->min, min) == -1)
-               min = min;
-             else
-               min = vr->min;
-             if (compare_values (vr->max, max) == 1)
-               max = max;
-             else
-               max = vr->max;
-
-             /* If the new min/max values have converged to a
-                single value, then there is only one value which
-                can satisfy the condition.  Rewrite the condition
-                to test for equality.  */
-             if (min == max
-                 && is_gimple_min_invariant (min))
+             if (dump_file)
                {
-                 COND_EXPR_COND (stmt)
-                   = build (EQ_EXPR, boolean_type_node, op0, min);
-                 update_stmt (stmt);
+                 fprintf (dump_file, "Simplified relational ");
+                 print_generic_expr (dump_file, cond, 0);
+                 fprintf (dump_file, " into ");
                }
+
+             COND_EXPR_COND (stmt)
+               = build (NE_EXPR, boolean_type_node, op0, new);
+             update_stmt (stmt);
+
+             if (dump_file)
+               {
+                 print_generic_expr (dump_file, COND_EXPR_COND (stmt), 0);
+                 fprintf (dump_file, "\n");
+               }
+             return;
+
            }
        }
     }