OSDN Git Service

2011-01-20 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 20 Jan 2011 14:42:20 +0000 (14:42 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 20 Jan 2011 14:42:20 +0000 (14:42 +0000)
PR middle-end/47370
* tree-inline.c (remap_gimple_op_r): Recurse manually for
the pointer operand of MEM_REFs.

* gcc.dg/torture/pr47370.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@169055 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr47370.c [new file with mode: 0644]
gcc/tree-inline.c

index 466579a..d7d4eb4 100644 (file)
@@ -1,3 +1,9 @@
+2011-01-20  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/47370
+       * tree-inline.c (remap_gimple_op_r): Recurse manually for
+       the pointer operand of MEM_REFs.
+
 2011-01-20  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/46130
index c488050..336d1e5 100644 (file)
@@ -1,3 +1,8 @@
+2011-01-20  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/47370
+       * gcc.dg/torture/pr47370.c: New testcase.
+
 2011-01-20  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/46130
diff --git a/gcc/testsuite/gcc.dg/torture/pr47370.c b/gcc/testsuite/gcc.dg/torture/pr47370.c
new file mode 100644 (file)
index 0000000..ff71f09
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+
+struct S { int s; };
+
+void
+foo (void)
+{
+  for (;;)
+    ;
+}
+
+struct S
+bar (void)
+{
+  struct S s = { 99 };
+  return s;
+}
+
+void
+baz (int i)
+{
+  struct S s[1];
+  s[0] = bar ();
+  bar ();
+  foo ();
+}
+
index c5ab4ca..24a6dd0 100644 (file)
@@ -811,57 +811,47 @@ remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data)
         knows not to copy VAR_DECLs, etc., so this is safe.  */
       if (TREE_CODE (*tp) == MEM_REF)
        {
-         /* We need to re-canonicalize MEM_REFs from inline substitutions
-            that can happen when a pointer argument is an ADDR_EXPR.  */
-         tree decl = TREE_OPERAND (*tp, 0);
-         tree *n;
-
-          /* See remap_ssa_name.  */
-          if (TREE_CODE (decl) == SSA_NAME
-              && TREE_CODE (SSA_NAME_VAR (decl)) == RESULT_DECL
-              && id->transform_return_to_modify)
-            decl = SSA_NAME_VAR (decl);
+         tree ptr = TREE_OPERAND (*tp, 0);
+         tree old = *tp;
+         tree tem;
 
-         n = (tree *) pointer_map_contains (id->decl_map, decl);
-         if (n)
+         /* We need to re-canonicalize MEM_REFs from inline substitutions
+            that can happen when a pointer argument is an ADDR_EXPR.
+            Recurse here manually to allow that.  */
+         walk_tree (&ptr, remap_gimple_op_r, data, NULL);
+         if ((tem = maybe_fold_offset_to_reference (EXPR_LOCATION (*tp),
+                                                    ptr,
+                                                    TREE_OPERAND (*tp, 1),
+                                                    TREE_TYPE (*tp)))
+             && TREE_THIS_VOLATILE (tem) == TREE_THIS_VOLATILE (old))
            {
-             tree old = *tp;
-             tree ptr = unshare_expr (*n);
-             tree tem;
-             if ((tem = maybe_fold_offset_to_reference (EXPR_LOCATION (*tp),
-                                                        ptr,
-                                                        TREE_OPERAND (*tp, 1),
-                                                        TREE_TYPE (*tp)))
-                 && TREE_THIS_VOLATILE (tem) == TREE_THIS_VOLATILE (old))
-               {
-                 tree *tem_basep = &tem;
-                 while (handled_component_p (*tem_basep))
-                   tem_basep = &TREE_OPERAND (*tem_basep, 0);
-                 if (TREE_CODE (*tem_basep) == MEM_REF)
-                   *tem_basep
-                     = build2 (MEM_REF, TREE_TYPE (*tem_basep),
-                               TREE_OPERAND (*tem_basep, 0),
-                               fold_convert (TREE_TYPE (TREE_OPERAND (*tp, 1)),
-                                             TREE_OPERAND (*tem_basep, 1)));
-                 else
-                   *tem_basep
-                     = build2 (MEM_REF, TREE_TYPE (*tem_basep),
-                               build_fold_addr_expr (*tem_basep),
-                               build_int_cst
-                                 (TREE_TYPE (TREE_OPERAND (*tp, 1)), 0));
-                 *tp = tem;
-               }
+             tree *tem_basep = &tem;
+             while (handled_component_p (*tem_basep))
+               tem_basep = &TREE_OPERAND (*tem_basep, 0);
+             if (TREE_CODE (*tem_basep) == MEM_REF)
+               *tem_basep
+                   = build2 (MEM_REF, TREE_TYPE (*tem_basep),
+                             TREE_OPERAND (*tem_basep, 0),
+                             fold_convert (TREE_TYPE (TREE_OPERAND (*tp, 1)),
+                                           TREE_OPERAND (*tem_basep, 1)));
              else
-               {
-                 *tp = fold_build2 (MEM_REF, TREE_TYPE (*tp),
-                                    ptr, TREE_OPERAND (*tp, 1));
-                 TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
-                 TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old);
-               }
-             TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
-             *walk_subtrees = 0;
-             return NULL;
+               *tem_basep
+                   = build2 (MEM_REF, TREE_TYPE (*tem_basep),
+                             build_fold_addr_expr (*tem_basep),
+                             build_int_cst
+                             (TREE_TYPE (TREE_OPERAND (*tp, 1)), 0));
+             *tp = tem;
            }
+         else
+           {
+             *tp = fold_build2 (MEM_REF, TREE_TYPE (*tp),
+                                ptr, TREE_OPERAND (*tp, 1));
+             TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
+             TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old);
+           }
+         TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
+         *walk_subtrees = 0;
+         return NULL;
        }
 
       /* Here is the "usual case".  Copy this tree node, and then