OSDN Git Service

gcc/
authorkazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 26 Jun 2005 03:49:20 +0000 (03:49 +0000)
committerkazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 26 Jun 2005 03:49:20 +0000 (03:49 +0000)
PR tree-optimization/22026
* tree-vrp.c (extract_range_from_binary_expr): Drop to
VR_VARYING if a binary expression involving VR_ANTI_RANGE is
PLUS_EXPR, MINUS_EXPR, or unsigned MULT_EXPR.

testsuite/
PR tree-optimization/22026
* gcc.dg/tree-ssa/pr22026.c: New.

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

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

index 6c7bb98..18c7e41 100644 (file)
@@ -1,4 +1,11 @@
-2005-06-25  Kazu Hirata  <kazu@codesourcery.com>
+2005-06-26  Kazu Hirata  <kazu@codesourcery.com>
+
+       PR tree-optimization/22026
+       * tree-vrp.c (extract_range_from_binary_expr): Drop to
+       VR_VARYING if a binary expression involving VR_ANTI_RANGE is
+       PLUS_EXPR, MINUS_EXPR, or unsigned MULT_EXPR.
+
+2005-06-26  Kazu Hirata  <kazu@codesourcery.com>
 
        * Makefile.in (OBJS-common): Remove duplicate object file
        names.
index 419e012..7196184 100644 (file)
@@ -1,3 +1,8 @@
+2005-06-26  Kazu Hirata  <kazu@codesourcery.com>
+
+       PR tree-optimization/22026
+       * gcc.dg/tree-ssa/pr22026.c: New.
+
 2005-06-25  Thomas Koenig <Thomas.Koenig@online.de>
 
        PR libfortran/21144
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr22026.c b/gcc/testsuite/gcc.dg/tree-ssa/pr22026.c
new file mode 100644 (file)
index 0000000..e56e4a1
--- /dev/null
@@ -0,0 +1,49 @@
+/* PR tree-optimization/22026
+   VRP used think that ~[0,0] + ~[0,0] = ~[0,0], which is wrong.  The
+   same applies to subtraction and unsigned multiplication.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp" } */
+
+int
+plus (int x, int y)
+{
+  if (x != 0)
+    if (y != 0)
+      {
+        int z = x + y;
+        if (z != 0)
+          return 1;
+      }
+  return 0;
+}
+
+int
+minus (int x, int y)
+{
+  if (x != 0)
+    if (y != 0)
+      {
+        int z = x - y;
+        if (z != 0)
+          return 1;
+      }
+  return 0;
+}
+
+int
+mult (unsigned x, unsigned y)
+{
+  if (x != 0)
+    if (y != 0)
+      {
+       unsigned z = x * y;
+       if (z != 0)
+         return 1;
+      }
+  return 0;
+}
+
+/* None of the predicates can be folded in these functions.  */
+/* { dg-final { scan-tree-dump-times "Folding predicate" 0 "vrp" } } */
+/* { dg-final { cleanup-tree-dump "vrp" } } */
index 37bcb1b..e733a8d 100644 (file)
@@ -1107,6 +1107,19 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
           || code == MIN_EXPR
           || code == MAX_EXPR)
     {
+      /* If we have a PLUS_EXPR with two VR_ANTI_RANGEs, drop to
+        VR_VARYING.  It would take more effort to compute a precise
+        range for such a case.  For example, if we have op0 == 1 and
+        op1 == -1 with their ranges both being ~[0,0], we would have
+        op0 + op1 == 0, so we cannot claim that the sum is in ~[0,0].
+        Note that we are guaranteed to have vr0.type == vr1.type at
+        this point.  */
+      if (code == PLUS_EXPR && vr0.type == VR_ANTI_RANGE)
+       {
+         set_value_range_to_varying (vr);
+         return;
+       }
+
       /* For operations that make the resulting range directly
         proportional to the original ranges, apply the operation to
         the same end of each range.  */
@@ -1123,6 +1136,22 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
       tree val[4];
       size_t i;
 
+      /* If we have an unsigned MULT_EXPR with two VR_ANTI_RANGEs,
+        drop to VR_VARYING.  It would take more effort to compute a
+        precise range for such a case.  For example, if we have
+        op0 == 65536 and op1 == 65536 with their ranges both being
+        ~[0,0] on a 32-bit machine, we would have op0 * op1 == 0, so
+        we cannot claim that the product is in ~[0,0].  Note that we
+        are guaranteed to have vr0.type == vr1.type at this
+        point.  */
+      if (code == MULT_EXPR
+         && vr0.type == VR_ANTI_RANGE
+         && (flag_wrapv || TYPE_UNSIGNED (TREE_TYPE (op0))))
+       {
+         set_value_range_to_varying (vr);
+         return;
+       }
+
       /* Multiplications and divisions are a bit tricky to handle,
         depending on the mix of signs we have in the two ranges, we
         need to operate on different values to get the minimum and
@@ -1188,6 +1217,19 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
     }
   else if (code == MINUS_EXPR)
     {
+      /* If we have a MINUS_EXPR with two VR_ANTI_RANGEs, drop to
+        VR_VARYING.  It would take more effort to compute a precise
+        range for such a case.  For example, if we have op0 == 1 and
+        op1 == 1 with their ranges both being ~[0,0], we would have
+        op0 - op1 == 0, so we cannot claim that the difference is in
+        ~[0,0].  Note that we are guaranteed to have
+        vr0.type == vr1.type at this point.  */
+      if (vr0.type == VR_ANTI_RANGE)
+       {
+         set_value_range_to_varying (vr);
+         return;
+       }
+
       /* For MINUS_EXPR, apply the operation to the opposite ends of
         each range.  */
       min = vrp_int_const_binop (code, vr0.min, vr1.max);