This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] tree-vrp.c: Avoid VR_ANTI_RANGE in a binary expression.


Hi,

Attached is a patch to teach VRP to avoid VR_ANTI_RANGE in a binary
expression.

Consider

int
f (int x, int y)
{
  if (x != 0)
    if (y != 0)
      {
        int t = x + y;
        if (t != 0)
          return 1;
      }
  return 0;
}

After passing the first two "if" statements, we know that both x and y
are nonzero.  The problem is that VRP concludes that x + y is also
nonzero.  That is, VRP thinks that

~[0,0] + ~[0,0] = ~[0,0]

which is not always true because we might have x == -1 and y == 1, in
which case x + y == 0.

The patch drops the resulting range to VR_VARYING unless both operands
have VR_RANGE.

In the case of pointers, I want to evaluate ~[0,0] + ~[0,0] to ~[0,0]
because a pointer is assumed not to wrap around, so the patch inserts
an "if" statement after we are done with pointers.  I have another
patch in testing for this.

Testing with cc1-i files show that this patch does not reduce the
number of predicates folded.

Tested on x86_64-pc-linux-gnu.  OK to apply?

Kazu Hirata

2005-06-21  Kazu Hirata  <kazu@codesourcery.com>

	PR tree-optimization/22026
	* tree-vrp.c (extract_range_from_binary_expr): Drop to
	VR_RANGE unless both operands have VR_RANGE.

2005-06-21  Kazu Hirata  <kazu@codesourcery.com>

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

Index: tree-vrp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vrp.c,v
retrieving revision 2.30
diff -u -d -p -r2.30 tree-vrp.c
--- tree-vrp.c	16 Jun 2005 21:25:00 -0000	2.30
+++ tree-vrp.c	19 Jun 2005 05:59:06 -0000
@@ -1124,7 +1124,15 @@ extract_range_from_binary_expr (value_ra
       return;
     }
 
+  /* For simplicity, we only handle cases with two ranges.  Handling
+     cases with an anti-range is not worth the effort.  */
+  if (vr0.type != VR_RANGE || vr1.type != VR_RANGE)
+    {
+      set_value_range_to_varying (vr);
+      return;
+    }
+
   /* For integer ranges, apply the operation to each end of the
      range and see what we end up with.  */
   if (code == TRUTH_ANDIF_EXPR
--- /dev/null	2005-06-10 06:25:05.661816064 -0400
+++ testsuite/gcc.dg/tree-ssa/pr22026.c	2005-06-18 23:53:50.000000000 -0400
@@ -0,0 +1,21 @@
+/* PR tree-optimization/22026
+   VRP used think that ~[0,0] + ~[0,0] = ~[0,0], which is wrong.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp" } */
+
+int
+f (int x, int y)
+{
+  if (x != 0)
+    if (y != 0)
+      {
+        int t = x + y;
+        if (t != 0)
+          return 1;
+      }
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "Folding predicate" 0 "vrp" } } */
+/* { dg-final { cleanup-tree-dump "vrp" } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]