OSDN Git Service

2007-01-08 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 8 Jan 2007 11:20:00 +0000 (11:20 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 8 Jan 2007 11:20:00 +0000 (11:20 +0000)
        PR tree-optimization/23603
        * tree-vrp.c (set_value_range_to_truthvalue): New function.
        (extract_range_from_binary): Fall back to truthvalue instead of
        varying for TRUTH_*_EXPR.
        (extract_range_from_comparison): Fall back to truthvalue instead of
        varying.
        (vrp_visit_phi_node): Don't adjust new range bounds to +INF/-INF
        if all visited PHI values were constant.

        * gcc.dg/tree-ssa/vrp31.c: New testcase.
        * gcc.dg/tree-ssa/vrp32.c: Likewise.

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

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

index dae9b9c..9e9f510 100644 (file)
@@ -1,3 +1,14 @@
+2007-01-08  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/23603
+       * tree-vrp.c (set_value_range_to_truthvalue): New function.
+       (extract_range_from_binary): Fall back to truthvalue instead of
+       varying for TRUTH_*_EXPR.
+       (extract_range_from_comparison): Fall back to truthvalue instead of
+       varying.
+       (vrp_visit_phi_node): Don't adjust new range bounds to +INF/-INF
+       if all visited PHI values were constant.
+
 2007-01-08  Jan Hubicka  <jh@suse.cz>
 
        * cgraphunit.c (cgraph_process_new_functions): Reset reachable flag.
index 80eeb11..22e4718 100644 (file)
@@ -1,3 +1,9 @@
+2007-01-08  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/23603
+       * gcc.dg/tree-ssa/vrp31.c: New testcase.
+       * gcc.dg/tree-ssa/vrp32.c: Likewise.
+
 2007-01-08  Mark Shinwell  <shinwell@codesourcery.com>
 
        * gcc.target/i386/20020531-1.c: Use "char" not "unsigned char"
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp31.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp31.c
new file mode 100644 (file)
index 0000000..5b4aa5d
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp1" } */
+
+int f(int i)
+{
+  int t = i == 1;
+  int g = t == 2;
+  int h = g == 3;
+  return h;
+}
+
+/* { dg-final { scan-tree-dump "return 0;" "vrp1" } } */
+/* { dg-final { cleanup-tree-dump "vrp1" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp32.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp32.c
new file mode 100644 (file)
index 0000000..a42b3ca
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp1" } */
+
+int f(int i)
+{
+  _Bool t = !i;
+  int g = !t && i;
+  int h = g == 3;
+  return h;
+}
+
+/* { dg-final { scan-tree-dump "return 0;" "vrp1" } } */
+/* { dg-final { cleanup-tree-dump "vrp1" } } */
+
index 36e9a3b..1092d17 100644 (file)
@@ -236,6 +236,20 @@ set_value_range_to_varying (value_range_t *vr)
 }
 
 
+/* Set value range VR to a range of a truthvalue of type TYPE.  */
+
+static inline void
+set_value_range_to_truthvalue (value_range_t *vr, tree type)
+{
+  if (TYPE_PRECISION (type) == 1)
+    set_value_range_to_varying (vr);
+  else
+    set_value_range (vr, VR_RANGE,
+                    build_int_cst (type, 0), build_int_cst (type, 1),
+                    vr->equiv);
+}
+
+
 /* Set value range VR to VR_UNDEFINED.  */
 
 static inline void
@@ -1439,7 +1453,8 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
        }
       else
        {
-         set_value_range_to_varying (vr);
+         /* The result of a TRUTH_*_EXPR is always true or false.  */
+         set_value_range_to_truthvalue (vr, TREE_TYPE (expr));
          return;
        }
     }
@@ -1920,7 +1935,8 @@ extract_range_from_comparison (value_range_t *vr, tree expr)
       set_value_range (vr, VR_RANGE, val, val, vr->equiv);
     }
   else
-    set_value_range_to_varying (vr);
+    /* The result of a comparison is always true or false.  */
+    set_value_range_to_truthvalue (vr, TREE_TYPE (expr));
 }
 
 
@@ -4182,6 +4198,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;
 
   copy_value_range (&vr_result, lhs_vr);
 
@@ -4209,7 +4226,10 @@ vrp_visit_phi_node (tree phi)
          value_range_t vr_arg;
 
          if (TREE_CODE (arg) == SSA_NAME)
-           vr_arg = *(get_value_range (arg));
+           {
+             vr_arg = *(get_value_range (arg));
+             all_const = false;
+           }
          else
            {
              vr_arg.type = VR_RANGE;
@@ -4240,7 +4260,8 @@ vrp_visit_phi_node (tree phi)
   /* To prevent infinite iterations in the algorithm, derive ranges
      when the new value is slightly bigger or smaller than the
      previous one.  */
-  if (lhs_vr->type == VR_RANGE && vr_result.type == VR_RANGE)
+  if (lhs_vr->type == VR_RANGE && vr_result.type == VR_RANGE
+      && !all_const)
     {
       if (!POINTER_TYPE_P (TREE_TYPE (lhs)))
        {