2009-11-24 Martin Jambor <mjambor@suse.cz>
authorjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 24 Nov 2009 10:56:14 +0000 (10:56 +0000)
committerjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 24 Nov 2009 10:56:14 +0000 (10:56 +0000)
PR tree-optimization/42154
* tree-sra.c (struct access): Added comments.
(sra_modify_expr): Build references to the old aggregate with
build_ref_for_offset instead of reusing access->expr.
(load_assign_lhs_subreplacements): Likewise.

* testsuite/gcc.c-torture/execute/pr42154.c: New test.

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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr42154.c [new file with mode: 0644]
gcc/tree-sra.c

index 8ed02bd..d05e456 100644 (file)
@@ -1,3 +1,11 @@
+2009-11-24  Martin Jambor  <mjambor@suse.cz>
+
+       PR tree-optimization/42154
+       * tree-sra.c (struct access): Added comments.
+       (sra_modify_expr): Build references to the old aggregate with
+       build_ref_for_offset instead of reusing access->expr.
+       (load_assign_lhs_subreplacements): Likewise.
+
 2009-11-24  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386.md (add<mode>3_carry): Change insn pattern
index 50c588c..7ad8ae9 100644 (file)
@@ -1,3 +1,8 @@
+2009-11-24  Martin Jambor  <mjambor@suse.cz>
+
+       PR tree-optimization/42154
+       * gcc.c-torture/execute/pr42154.c: New test.
+
 2009-11-24  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/42045
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr42154.c b/gcc/testsuite/gcc.c-torture/execute/pr42154.c
new file mode 100644 (file)
index 0000000..f78919d
--- /dev/null
@@ -0,0 +1,18 @@
+struct A { char x[1]; };
+extern void abort (void);
+void __attribute__((noinline,noclone))
+foo (struct A a)
+{
+  if (a.x[0] != 'a')
+    abort ();
+}
+int main ()
+{
+  struct A a;
+  int i;
+  for (i = 0; i < 1; ++i)
+    a.x[i] = 'a';
+  foo (a);
+  return 0;
+}
+
index fe82d98..5203685 100644 (file)
@@ -125,7 +125,9 @@ struct access
   HOST_WIDE_INT size;
   tree base;
 
-  /* Expression.  */
+  /* Expression.  It is context dependent so do not use it to create new
+     expressions to access the original aggregate.  See PR 42154 for a
+     testcase.  */
   tree expr;
   /* Type.  */
   tree type;
@@ -2113,10 +2115,17 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write,
         gcc.c-torture/compile/20011217-1.c.  */
       if (!is_gimple_reg_type (type))
        {
-         gimple stmt;
+         tree ref = access->base;
+         bool ok;
+
+         ok = build_ref_for_offset (&ref, TREE_TYPE (ref),
+                                    access->offset, access->type, false);
+         gcc_assert (ok);
+
          if (write)
            {
-             tree ref = unshare_expr (access->expr);
+             gimple stmt;
+
              if (access->grp_partial_lhs)
                ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
                                                 false, GSI_NEW_STMT);
@@ -2125,10 +2134,12 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write,
            }
          else
            {
+             gimple stmt;
+
              if (access->grp_partial_lhs)
                repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
                                                 true, GSI_SAME_STMT);
-             stmt = gimple_build_assign (unshare_expr (access->expr), repl);
+             stmt = gimple_build_assign (ref, repl);
              gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
            }
        }
@@ -2227,8 +2238,6 @@ load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
            }
          else
            {
-             bool repl_found;
-
              /* No suitable access on the right hand side, need to load from
                 the aggregate.  See if we have to update it first... */
              if (*refreshed == SRA_UDH_NONE)
@@ -2236,9 +2245,19 @@ load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
                                                                  lhs, old_gsi);
 
              if (*refreshed == SRA_UDH_LEFT)
-               rhs = unshare_expr (lacc->expr);
+               {
+                 bool repl_found;
+
+                 rhs = lacc->base;
+                 repl_found = build_ref_for_offset (&rhs, TREE_TYPE (rhs),
+                                                    lacc->offset, lacc->type,
+                                                    false);
+                 gcc_assert (repl_found);
+               }
              else
                {
+                 bool repl_found;
+
                  rhs = top_racc->base;
                  repl_found = build_ref_for_offset (&rhs,
                                                     TREE_TYPE (top_racc->base),