]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/58404 (&noninvariant_address not forwproped into ->handled_co...
authorRichard Biener <rguenther@suse.de>
Thu, 12 Sep 2013 13:20:17 +0000 (13:20 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 12 Sep 2013 13:20:17 +0000 (13:20 +0000)
2013-09-12  Richard Biener  <rguenther@suse.de>

PR tree-optimization/58404
* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Also
propagate non-invariant addresses into dereferences wrapped
in component references.

* g++.dg/tree-ssa/pr58404.C: New testcase.

From-SVN: r202525

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/tree-ssa/pr58404.C [new file with mode: 0644]
gcc/tree-ssa-forwprop.c

index ec525e50ea712785a64015aacd6b91b6c5e5404d..7a0d375fc33832ffb5daeea8b53b010a75f45ec4 100644 (file)
@@ -1,3 +1,10 @@
+2013-09-12  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/58404
+       * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Also
+       propagate non-invariant addresses into dereferences wrapped
+       in component references.
+
 2013-09-12  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/58402
index 576d56d0873966c410859a049dc8ec1bb3fbb86b..75110d9021d388276d6d64ba8d854df8c1cb0ee5 100644 (file)
@@ -1,3 +1,8 @@
+2013-09-12  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/58404
+       * g++.dg/tree-ssa/pr58404.C: New testcase.
+
 2013-09-12  Martin Jambor  <mjambor@suse.cz>
 
        PR ipa/58371
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr58404.C b/gcc/testsuite/g++.dg/tree-ssa/pr58404.C
new file mode 100644 (file)
index 0000000..aa8fb79
--- /dev/null
@@ -0,0 +1,20 @@
+// { dg-do compile }
+// { dg-options "-O -fdump-tree-cddce1" }
+
+struct S { int s; };
+S a[1024];
+
+void
+foo ()
+{
+  for (int i = 0; i < 1024; i++)
+    {
+      S &r = a[i];
+      r.s++;
+    }
+}
+
+// We should propagate the reference into both memory accesses
+// during the first forwprop pass
+// { dg-final { scan-tree-dump-times "= &a" 0 "cddce1" } }
+// { dg-final { cleanup-tree-dump "cddce1" } }
index 977aebdff5157d5ff98d45f542159a2e22bc176f..f1a407774fb6d3bb1d4f2777d5adee33d0e14c30 100644 (file)
@@ -786,9 +786,10 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
 
   /* Now strip away any outer COMPONENT_REF/ARRAY_REF nodes from the LHS.
      ADDR_EXPR will not appear on the LHS.  */
-  lhs = gimple_assign_lhs (use_stmt);
-  while (handled_component_p (lhs))
-    lhs = TREE_OPERAND (lhs, 0);
+  tree *lhsp = gimple_assign_lhs_ptr (use_stmt);
+  while (handled_component_p (*lhsp))
+    lhsp = &TREE_OPERAND (*lhsp, 0);
+  lhs = *lhsp;
 
   /* Now see if the LHS node is a MEM_REF using NAME.  If so,
      propagate the ADDR_EXPR into the use of NAME and fold the result.  */
@@ -822,11 +823,13 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
       /* If the LHS is a plain dereference and the value type is the same as
          that of the pointed-to type of the address we can put the
         dereferenced address on the LHS preserving the original alias-type.  */
-      else if (gimple_assign_lhs (use_stmt) == lhs
-              && integer_zerop (TREE_OPERAND (lhs, 1))
-              && useless_type_conversion_p
-                   (TREE_TYPE (TREE_OPERAND (def_rhs, 0)),
-                    TREE_TYPE (gimple_assign_rhs1 (use_stmt)))
+      else if (integer_zerop (TREE_OPERAND (lhs, 1))
+              && ((gimple_assign_lhs (use_stmt) == lhs
+                   && useless_type_conversion_p
+                        (TREE_TYPE (TREE_OPERAND (def_rhs, 0)),
+                         TREE_TYPE (gimple_assign_rhs1 (use_stmt))))
+                  || types_compatible_p (TREE_TYPE (lhs),
+                                         TREE_TYPE (TREE_OPERAND (def_rhs, 0))))
               /* Don't forward anything into clobber stmts if it would result
                  in the lhs no longer being a MEM_REF.  */
               && (!gimple_clobber_p (use_stmt)
@@ -854,7 +857,7 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
          TREE_SIDE_EFFECTS (*def_rhs_basep) = TREE_SIDE_EFFECTS (lhs);
          TREE_THIS_NOTRAP (*def_rhs_basep) = TREE_THIS_NOTRAP (lhs);
          new_lhs = unshare_expr (TREE_OPERAND (def_rhs, 0));
-         gimple_assign_set_lhs (use_stmt, new_lhs);
+         *lhsp = new_lhs;
          TREE_THIS_VOLATILE (new_lhs) = TREE_THIS_VOLATILE (lhs);
          TREE_SIDE_EFFECTS (new_lhs) = TREE_SIDE_EFFECTS (lhs);
          *def_rhs_basep = saved;
@@ -873,11 +876,12 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
 
   /* Strip away any outer COMPONENT_REF, ARRAY_REF or ADDR_EXPR
      nodes from the RHS.  */
-  rhs = gimple_assign_rhs1 (use_stmt);
-  if (TREE_CODE (rhs) == ADDR_EXPR)
-    rhs = TREE_OPERAND (rhs, 0);
-  while (handled_component_p (rhs))
-    rhs = TREE_OPERAND (rhs, 0);
+  tree *rhsp = gimple_assign_rhs1_ptr (use_stmt);
+  if (TREE_CODE (*rhsp) == ADDR_EXPR)
+    rhsp = &TREE_OPERAND (*rhsp, 0);
+  while (handled_component_p (*rhsp))
+    rhsp = &TREE_OPERAND (*rhsp, 0);
+  rhs = *rhsp;
 
   /* Now see if the RHS node is a MEM_REF using NAME.  If so,
      propagate the ADDR_EXPR into the use of NAME and fold the result.  */
@@ -909,11 +913,13 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
       /* If the RHS is a plain dereference and the value type is the same as
          that of the pointed-to type of the address we can put the
         dereferenced address on the RHS preserving the original alias-type.  */
-      else if (gimple_assign_rhs1 (use_stmt) == rhs
-              && integer_zerop (TREE_OPERAND (rhs, 1))
-              && useless_type_conversion_p
-                   (TREE_TYPE (gimple_assign_lhs (use_stmt)),
-                    TREE_TYPE (TREE_OPERAND (def_rhs, 0))))
+      else if (integer_zerop (TREE_OPERAND (rhs, 1))
+              && ((gimple_assign_rhs1 (use_stmt) == rhs
+                   && useless_type_conversion_p
+                        (TREE_TYPE (gimple_assign_lhs (use_stmt)),
+                         TREE_TYPE (TREE_OPERAND (def_rhs, 0))))
+                  || types_compatible_p (TREE_TYPE (rhs),
+                                         TREE_TYPE (TREE_OPERAND (def_rhs, 0)))))
        {
          tree *def_rhs_basep = &TREE_OPERAND (def_rhs, 0);
          tree new_offset, new_base, saved, new_rhs;
@@ -937,7 +943,7 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
          TREE_SIDE_EFFECTS (*def_rhs_basep) = TREE_SIDE_EFFECTS (rhs);
          TREE_THIS_NOTRAP (*def_rhs_basep) = TREE_THIS_NOTRAP (rhs);
          new_rhs = unshare_expr (TREE_OPERAND (def_rhs, 0));
-         gimple_assign_set_rhs1 (use_stmt, new_rhs);
+         *rhsp = new_rhs;
          TREE_THIS_VOLATILE (new_rhs) = TREE_THIS_VOLATILE (rhs);
          TREE_SIDE_EFFECTS (new_rhs) = TREE_SIDE_EFFECTS (rhs);
          *def_rhs_basep = saved;