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] Fix forward_propagate_addr_expr_1 (PR middle-end/38140)


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


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