This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] tree-ssa-ccp.c: Propagate ADDR_EXPRs further.
- From: Kazu Hirata <kazu at cs dot umass dot edu>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 27 May 2005 00:17:13 -0400 (EDT)
- Subject: [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" } } */