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-ssa-ccp.c: Propagate ADDR_EXPRs further.


Hi,

Attached is a patch to propagate ADDR_EXPRs further.

Consider

void
f (void)
{
  int a[10];
  int *p = &a[5];
  int *q = p - 1;
  if (q != &a[4])
    link_error ();
}

Note that "p - 1" can be folded to &a[4] because p is known to be
&a[4].  However, CCP doesn't do so despite Richard Guenther's recent
improvement to try_move_mult_to_index in fold-const.c.  To be precise,
the propagator does not do the folding in question.  fold_stmt does
fold "p - 1", so we end up with

  q = &a[4];
  if (q != &a[4])

Notice that we leave the "if" statement there.

The problem is that fold_binary_to_constant is a bit too restrictive.
Recall that fold_binary_to_constant calls fold_binary as a subroutine.
fold_binary does fold "&a[5] - 1" to &a[4] as desired, but
fold_binary_to_constant rejects the result because TREE_CONSTANT isn't
set.  I guess TREE_CONSTANT is for compile-time and maybe link-time
constants, but regardless, that's not exactly what
is_gimple_min_invariant accepts.  AFAIK, is_gimple_min_invariant also
accepts ADDR_EXPRs like &a[4], where 'a' is some array.

The patch fixes the problem by simply changing fold_binary_to_constant
to fold_binary in ccp_fold.  Note that ccp_fold calls
is_gimple_min_invariant like so

  if (retval && ! is_gimple_min_invariant (retval))
    return NULL;

so we won't propagate something that does not satisfy
is_gimple_min_invariant.

Since ccp_fold calls fold_unary_to_constant, I changed that to
fold_unary as well.  We call is_gimple_min_invariant there, too, so we
don't have to worry about propagating something that does not satisfy
is_gimple_min_invariant.

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

Kazu Hirata

2005-05-27  Kazu Hirata  <kazu@cs.umass.edu>

	PR tree-optimization/21658
	* tree-ssa-ccp.c (ccp_fold): Call fold_binary instead of
	fold_binary_to_constant.  Likewise, call fold_unary instead of
	fold_unary_to_constant.

2005-05-27  Kazu Hirata  <kazu@cs.umass.edu>

	PR tree-optimization/21658
	* gcc.dg/tree-ssa/pr21658.c: New.

Index: tree-ssa-ccp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-ccp.c,v
retrieving revision 2.72
diff -u -d -p -r2.72 tree-ssa-ccp.c
--- tree-ssa-ccp.c	17 May 2005 19:55:52 -0000	2.72
+++ tree-ssa-ccp.c	19 May 2005 00:30:08 -0000
@@ -849,7 +849,7 @@ ccp_fold (tree stmt)
 	    op0 = get_value (op0, true)->value;
 	}
 
-      retval = fold_unary_to_constant (code, TREE_TYPE (rhs), op0);
+      retval = fold_unary (code, TREE_TYPE (rhs), op0);
 
       /* If we folded, but did not create an invariant, then we can not
 	 use this expression.  */
@@ -900,7 +900,7 @@ ccp_fold (tree stmt)
 	    op1 = val->value;
 	}
 
-      retval = fold_binary_to_constant (code, TREE_TYPE (rhs), op0, op1);
+      retval = fold_binary (code, TREE_TYPE (rhs), op0, op1);
 
       /* If we folded, but did not create an invariant, then we can not
 	 use this expression.  */
--- /dev/null	2005-05-05 09:22:29.000000000 -0400
+++ testsuite/gcc.dg/tree-ssa/pr21658.c	2005-05-18 20:27:11.000000000 -0400
@@ -0,0 +1,21 @@
+/* PR tree-optimization/21658
+   CCP did not propagate an ADDR_EXPR far enough, preventing the "if"
+   statement below from being folded.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-dominator-opts -fdump-tree-ccp-details" } */
+
+void link_error (void);
+
+void
+f (void)
+{
+  int a[10];
+  int *p = &a[5];
+  int *q = p - 1;
+  if (q != &a[4])
+    link_error ();
+}
+
+/* { dg-final { scan-tree-dump-times "with if \\(0\\)" 1 "ccp"} } */
+/* { dg-final { cleanup-tree-dump "ccp" } } */


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