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: Compute a correct range when adding two pointers.


Hi,

Attached is a patch to compute a correct range when adding two pointers.

Consider

void
foo (int *p, int q)
{
  if (p == 0)
    {
      if (q == 0)
	{
	  int *r = &p[q];
	  if (r != 0)
	    link_error ();
	}
    }
}

After passing the first two "if" statements, we know that p and q are
both 0, so r, which is really &p[q], must also be 0.  However, VRP
thinks that an addition of two pointers *always* results in nonnull,
which isn't true.

The patch fixes this problem by examing the value ranges of a
PLUS_EXPR's operands.  If either one is nonnull, the result is
nonnull.  If both are null, the result is obviously null.  Otherwise,
the result is VR_VARYING.

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

Kazu Hirata

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

	PR tree-optimization/22117
	* tree-vrp.c (extract_range_from_binary_expr): Compute a
	correct range when adding two pointers.

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

	PR tree-optimization/22117
	* gcc.dg/tree-ssa/pr22117.c: New.

Index: tree-vrp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vrp.c,v
retrieving revision 2.32
diff -u -d -p -r2.32 tree-vrp.c
--- tree-vrp.c	21 Jun 2005 18:46:19 -0000	2.32
+++ tree-vrp.c	22 Jun 2005 04:06:16 -0000
@@ -1073,8 +1073,15 @@ extract_range_from_binary_expr (value_ra
 	 ivopts is generating expressions with pointer multiplication
 	 in them.  */
       if (code == PLUS_EXPR)
-	set_value_range_to_nonnull (vr, TREE_TYPE (expr));
+	{
+	  if (range_is_nonnull (&vr0) || range_is_nonnull (&vr1))
+	    set_value_range_to_nonnull (vr, TREE_TYPE (expr));
+	  else if (range_is_null (&vr0) && range_is_null (&vr1))
+	    set_value_range_to_null (vr, TREE_TYPE (expr));
+	  else
+	    set_value_range_to_varying (vr);
+	}
       else
 	{
 	  /* Subtracting from a pointer, may yield 0, so just drop the
--- /dev/null	2005-06-10 06:25:05.661816064 -0400
+++ testsuite/gcc.dg/tree-ssa/pr22117.c	2005-06-18 23:51:28.000000000 -0400
@@ -0,0 +1,23 @@
+/* PR tree-optimization/22117
+   VRP used think that &p[q] is nonzero even though p and q are both
+   known to be zero after entering the first two "if" statements.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp" } */
+
+void
+foo (int *p, int q)
+{
+  if (p == 0)
+    {
+      if (q == 0)
+	{
+	  int *r = &p[q];
+	  if (r != 0)
+	    link_error ();
+	}
+    }
+}
+
+/* { dg-final { scan-tree-dump-times "Folding predicate r_.* != 0B to 0" 1 "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]