From 5babbcc0fceb0aa66547feb61124ff548929cbfc Mon Sep 17 00:00:00 2001
From: Richard Guenther <rguenther@suse.de>
Date: Sun, 29 Mar 2009 17:54:04 +0000
Subject: [PATCH] tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Properly
 propagate addresses of array references.

2009-03-29  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Properly
	propagate addresses of array references.

	* gcc.dg/tree-ssa/forwprop-11.c: New testcase.

From-SVN: r145250
---
 gcc/ChangeLog                               |  5 +++++
 gcc/testsuite/ChangeLog                     |  4 ++++
 gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c | 19 +++++++++++++++++++
 gcc/tree-ssa-forwprop.c                     | 12 +++++++-----
 4 files changed, 35 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5f9b9c14a404..4766e21c994c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2009-03-29  Richard Guenther  <rguenther@suse.de>
+
+	* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Properly
+	propagate addresses of array references.
+
 2009-03-29  Steven Bosscher  <steven@gcc.gnu.org>
 
 	* regmove.c (perhaps_ends_bb_p): Remove.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f264b33f301a..0807892c7439 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2009-03-29  Richard Guenther  <rguenther@suse.de>
+
+	* gcc.dg/tree-ssa/forwprop-11.c: New testcase.
+
 2009-03-29  Daniel Kraft  <d@domob.eu>
 
 	PR fortran/37423
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c
new file mode 100644
index 000000000000..eaaa6dd4e240
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-forwprop1" } */
+
+int f(int *p, int n)
+{
+  int (*a)[n] = (int (*)[n])p;
+  int *q = &(*a)[0];
+  return q[1];
+}
+
+int g(int *p, int n)
+{
+  int (*a)[n] = (int (*)[n])p;
+  int *q = &(*a)[2];
+  return q[-1];
+}
+
+/* { dg-final { scan-tree-dump-times "= \\\(\\\*a_..\\\)\\\[1\\\];" 2 "forwprop1" } } */
+/* { dg-final { cleanup-tree-dump "forwprop1" } } */
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index fb29f91bbf19..859d6fe61726 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -828,19 +828,20 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
   array_ref = TREE_OPERAND (def_rhs, 0);
   if (TREE_CODE (array_ref) != ARRAY_REF
       || TREE_CODE (TREE_TYPE (TREE_OPERAND (array_ref, 0))) != ARRAY_TYPE
-      || !integer_zerop (TREE_OPERAND (array_ref, 1)))
+      || TREE_CODE (TREE_OPERAND (array_ref, 1)) != INTEGER_CST)
     return false;
 
   rhs2 = gimple_assign_rhs2 (use_stmt);
-  /* Try to optimize &x[0] p+ C where C is a multiple of the size
-     of the elements in X into &x[C/element size].  */
+  /* Try to optimize &x[C1] p+ C2 where C2 is a multiple of the size
+     of the elements in X into &x[C1 + C2/element size].  */
   if (TREE_CODE (rhs2) == INTEGER_CST)
     {
       tree new_rhs = maybe_fold_stmt_addition (gimple_expr_type (use_stmt),
-					       array_ref, rhs2);
+					       def_rhs, rhs2);
       if (new_rhs)
 	{
-	  gimple_assign_set_rhs_from_tree (use_stmt_gsi, new_rhs);
+	  gimple_assign_set_rhs_from_tree (use_stmt_gsi,
+					   unshare_expr (new_rhs));
 	  use_stmt = gsi_stmt (*use_stmt_gsi);
 	  update_stmt (use_stmt);
 	  tidy_after_forward_propagate_addr (use_stmt);
@@ -853,6 +854,7 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
      array elements, then the result is converted into the proper
      type for the arithmetic.  */
   if (TREE_CODE (rhs2) == SSA_NAME
+      && integer_zerop (TREE_OPERAND (array_ref, 1))
       && useless_type_conversion_p (TREE_TYPE (name), TREE_TYPE (def_rhs))
       /* Avoid problems with IVopts creating PLUS_EXPRs with a
 	 different type than their operands.  */
-- 
GitLab