]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/40389 (optimizer bug (possibly))
authorRichard Guenther <rguenther@suse.de>
Wed, 17 Jun 2009 12:03:08 +0000 (12:03 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 17 Jun 2009 12:03:08 +0000 (12:03 +0000)
2009-06-17  Richard Guenther  <rguenther@suse.de>

PR middle-end/40389
* tree-ssa-operands.c (get_modify_stmt_operands): Add NRV
results to the addresses taken bitmap.
* tree-scalar-evolution.c (scev_const_prop): Do not insert
incomplete stmts into the instruction stream.

* g++.dg/torture/pr40389.C: New testcase.

From-SVN: r148604

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr40389.C [new file with mode: 0644]
gcc/tree-scalar-evolution.c
gcc/tree-ssa-operands.c

index d4402d07d51610bc06ab23991a2674f87d74ef98..c3bd2c36bd1ca394571e498cdcf053dca8ca0eb3 100644 (file)
@@ -1,3 +1,11 @@
+2009-06-17  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/40389
+       * tree-ssa-operands.c (get_modify_stmt_operands): Add NRV
+       results to the addresses taken bitmap.
+       * tree-scalar-evolution.c (scev_const_prop): Do not insert
+       incomplete stmts into the instruction stream.
+
 2009-06-17  Richard Guenther  <rguenther@suse.de>
 
        PR middle-end/40460
index cb1d8a0fb7c3dc44eabac58706298fd18a79d59c..842164faa78245db3e8d0bfd7399834d757b6fff 100644 (file)
@@ -1,3 +1,8 @@
+2009-06-17  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/40389
+       * g++.dg/torture/pr40389.C: New testcase.
+
 2009-06-17  Richard Guenther  <rguenther@suse.de>
 
        PR middle-end/40460
diff --git a/gcc/testsuite/g++.dg/torture/pr40389.C b/gcc/testsuite/g++.dg/torture/pr40389.C
new file mode 100644 (file)
index 0000000..e3ceb12
--- /dev/null
@@ -0,0 +1,84 @@
+/* { dg-do run } */
+
+template <typename V> struct S
+{
+  V *f, *l;
+  __attribute__ ((noinline)) S (void) { f = 0, l = 0; }
+  void foo (V *x)
+  {
+    if (x->p != 0)
+      x->p->n = x->n;
+    else
+      f = x->n;
+    if (x->n != 0)
+      x->n->p = x->p;
+    else
+      l = x->p;
+  }
+  __attribute__ ((noinline)) void bar (V *x)
+  {
+    x->n = 0;
+    x->p = l;
+    if (l != 0)
+      l->n = x;
+    else
+      f = x;
+    l = x;
+  }
+};
+
+struct H;
+
+struct A
+{
+  S <H> k;
+};
+
+struct H
+{
+  A *a;
+  H *p, *n;
+  __attribute__ ((noinline)) H (void) { p = 0, n = 0, a = 0; }
+  __attribute__ ((noinline)) H (A *b) : a (b)
+  {
+    p = 0;
+    n = 0;
+    if (a != 0)
+      a->k.bar (this);
+  }
+  __attribute__ ((noinline)) H (const H &h) : a (h.a)
+  {
+    p = 0;
+    n = 0;
+    if (a != 0)
+      a->k.bar (this);
+  }
+  ~H (void) { if (a != 0) a->k.foo (this); }
+  H &operator= (const H &o)
+  {
+    if (a != 0 || &o == this)
+      __builtin_abort ();
+    a = o.a;
+    if (a != 0)
+      a->k.bar (this);
+    return *this;
+  }
+};
+
+__attribute__ ((noinline))
+H baz (void)
+{
+  return H (new A);
+}
+
+H g;
+
+int
+main (void)
+{
+  g = baz ();
+  if (g.a->k.f != &g)
+    __builtin_abort ();
+  return 0;
+}
+
index e7563784742cb0746d9a2f3aa5a7b6b4c931ce4f..a3067ed97c5dbefe571e4a6575d50eaf69359e9c 100644 (file)
@@ -2894,11 +2894,11 @@ scev_const_prop (void)
          SSA_NAME_DEF_STMT (rslt) = ass;
          {
            block_stmt_iterator dest = bsi;
-           bsi_insert_before (&dest, ass, BSI_NEW_STMT);
            def = force_gimple_operand_bsi (&dest, def, false, NULL_TREE,
                                            true, BSI_SAME_STMT);
+           GIMPLE_STMT_OPERAND (ass, 1) = def;
+           bsi_insert_before (&dest, ass, BSI_NEW_STMT);
          }
-         GIMPLE_STMT_OPERAND (ass, 1) = def;
          update_stmt (ass);
        }
     }
index e4eb27c96a421e9fbd1823e843608b54f34e7d29..4eef41ea185b747905448a59334989ff2cf7974b 100644 (file)
@@ -2060,6 +2060,17 @@ get_modify_stmt_operands (tree stmt, tree expr)
      We used to distinguish between preserving and killing definitions.
      We always emit preserving definitions now.  */
   get_expr_operands (stmt, &GIMPLE_STMT_OPERAND (expr, 0), opf_def);
+
+  /* Make sure the return value is addressable in case of NRV.  */
+  if (TREE_CODE (GIMPLE_STMT_OPERAND (expr, 1)) == CALL_EXPR
+      && CALL_EXPR_RETURN_SLOT_OPT (GIMPLE_STMT_OPERAND (expr, 1))
+      && TREE_ADDRESSABLE (TREE_TYPE (GIMPLE_STMT_OPERAND (expr, 0))))
+    {
+      tree t = get_base_address (GIMPLE_STMT_OPERAND (expr, 0));
+      stmt_ann_t s_ann = stmt_ann (stmt);
+      if (t && DECL_P (t) && s_ann)
+       add_to_addressable_set (t, &s_ann->addresses_taken);
+    }
 }