summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-ccp.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2008-11-05 12:17:10 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2008-11-05 12:17:10 +0000
commitfb8ed03fa605f7ccb18283a22a90c6cae7a8340c (patch)
treec33b55ff21ac34fcc6846d0faa6ad347ae2c4bde /gcc/tree-ssa-ccp.c
parentacd4810591d645ed34cbc20766fd71bad74166f1 (diff)
downloadgcc-fb8ed03fa605f7ccb18283a22a90c6cae7a8340c.tar.gz
2008-11-05 Richard Guenther <rguenther@suse.de>
PR middle-end/37742 * tree-ssa.c (useless_type_conversion_p_1): Check different restrict qualified pointer conversion before stripping qualifiers. * gimplify.c (create_tmp_from_val): Use correctly qualified type. * tree-flow.h (may_propagate_address_into_dereference): Declare. * tree-ssa-ccp.c (may_propagate_address_into_dereference): New function. (ccp_fold): Use it. * tree-ssa-forwprop.c (rhs_to_tree): Remove useless conversions, properly canonicalize binary ops. (forward_propagate_addr_expr_1): Use may_propagate_address_into_dereference. cp/ * decl.c (start_preparsed_function): Use the correct type for building the RESULT_DECL. * gcc.c-torture/compile/pr37742.c: New testcase. * g++.dg/pr37742.C: Likewise. * gcc.dg/tree-ssa/forwprop-7.c: Check for two volatile loads. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@141606 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-ccp.c')
-rw-r--r--gcc/tree-ssa-ccp.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 0365697fc85..a7d5be32e31 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -851,6 +851,31 @@ ccp_visit_phi_node (gimple phi)
return SSA_PROP_NOT_INTERESTING;
}
+/* Return true if we may propagate the address expression ADDR into the
+ dereference DEREF and cancel them. */
+
+bool
+may_propagate_address_into_dereference (tree addr, tree deref)
+{
+ gcc_assert (INDIRECT_REF_P (deref)
+ && TREE_CODE (addr) == ADDR_EXPR);
+
+ /* If the address is invariant then we do not need to preserve restrict
+ qualifications. But we do need to preserve volatile qualifiers until
+ we can annotate the folded dereference itself properly. */
+ if (is_gimple_min_invariant (addr)
+ && (!TREE_THIS_VOLATILE (deref)
+ || TYPE_VOLATILE (TREE_TYPE (addr))))
+ return useless_type_conversion_p (TREE_TYPE (deref),
+ TREE_TYPE (TREE_OPERAND (addr, 0)));
+
+ /* Else both the address substitution and the folding must result in
+ a valid useless type conversion sequence. */
+ return (useless_type_conversion_p (TREE_TYPE (TREE_OPERAND (deref, 0)),
+ TREE_TYPE (addr))
+ && useless_type_conversion_p (TREE_TYPE (deref),
+ TREE_TYPE (TREE_OPERAND (addr, 0))));
+}
/* CCP specific front-end to the non-destructive constant folding
routines.
@@ -897,12 +922,8 @@ ccp_fold (gimple stmt)
prop_value_t *val = get_value (TREE_OPERAND (*base, 0));
if (val->lattice_val == CONSTANT
&& TREE_CODE (val->value) == ADDR_EXPR
- && useless_type_conversion_p
- (TREE_TYPE (TREE_OPERAND (*base, 0)),
- TREE_TYPE (val->value))
- && useless_type_conversion_p
- (TREE_TYPE (*base),
- TREE_TYPE (TREE_OPERAND (val->value, 0))))
+ && may_propagate_address_into_dereference
+ (val->value, *base))
{
/* We need to return a new tree, not modify the IL
or share parts of it. So play some tricks to