This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix forward_propagate_addr_expr_1 (PR middle-end/38140)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 17 Nov 2008 11:14:45 +0100
- Subject: [PATCH] Fix forward_propagate_addr_expr_1 (PR middle-end/38140)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
As converting (almost) any pointer to void * is considered useless
conversion, x = &a forward propagation into *x = b can create
invalid GIMPLE, if conversion from b's type to a's type is not
useless. On the following testcase b's type is void * and
a's type is a function pointer. Fixed by adding the needed NOP_EXPR
if needed, or, if it would need an extra statement, not doing this
optimization at all.
Bootstrapped/regtested on x86_64-linux, ok for trunk?
2008-11-17 Jakub Jelinek <jakub@redhat.com>
PR middle-end/38140
* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): If
propagating x = &a into *x = b, add a cast if not useless
type conversion or don't optimize if another stmt would be
needed.
* gcc.dg/pr38140.c: New test.
--- gcc/tree-ssa-forwprop.c.jj 2008-11-10 10:28:26.000000000 +0100
+++ gcc/tree-ssa-forwprop.c 2008-11-17 09:22:55.000000000 +0100
@@ -721,13 +721,29 @@ forward_propagate_addr_expr_1 (tree name
&& TREE_OPERAND (lhs, 0) == name
&& may_propagate_address_into_dereference (def_rhs, lhs))
{
- *lhsp = unshare_expr (TREE_OPERAND (def_rhs, 0));
- fold_stmt_inplace (use_stmt);
- tidy_after_forward_propagate_addr (use_stmt);
+ bool valid = true;
+ if (lhsp == gimple_assign_lhs_ptr (use_stmt)
+ && !useless_type_conversion_p (TREE_TYPE (TREE_OPERAND (def_rhs, 0)),
+ TREE_TYPE (rhs))
+ && !CONVERT_EXPR_CODE_P (rhs_code))
+ {
+ if (get_gimple_rhs_class (rhs_code) == GIMPLE_SINGLE_RHS
+ && TREE_CODE (rhs) == SSA_NAME)
+ gimple_assign_set_rhs_code (use_stmt, NOP_EXPR);
+ else
+ valid = false;
+ }
+ if (valid)
+ {
+ *lhsp = unshare_expr (TREE_OPERAND (def_rhs, 0));
+ fold_stmt_inplace (use_stmt);
+ tidy_after_forward_propagate_addr (use_stmt);
- /* Continue propagating into the RHS if this was not the only use. */
- if (single_use_p)
- return true;
+ /* Continue propagating into the RHS if this was not the only
+ use. */
+ if (single_use_p)
+ return true;
+ }
}
/* Strip away any outer COMPONENT_REF, ARRAY_REF or ADDR_EXPR
--- gcc/testsuite/gcc.dg/pr38140.c.jj 2008-11-17 09:25:50.000000000 +0100
+++ gcc/testsuite/gcc.dg/pr38140.c 2008-11-17 09:25:05.000000000 +0100
@@ -0,0 +1,10 @@
+/* PR middle-end/38140 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-strict-aliasing" } */
+
+int foo (void *x)
+{
+ int (*fn) (int);
+ *(void **)&fn = x;
+ return fn (6);
+}
Jakub