From bac40cecbab715c81a188e185edd267e90f223da Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Wed, 17 Jun 2009 12:03:08 +0000 Subject: [PATCH] re PR c++/40389 (optimizer bug (possibly)) 2009-06-17 Richard Guenther 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 | 8 +++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/g++.dg/torture/pr40389.C | 84 ++++++++++++++++++++++++++ gcc/tree-scalar-evolution.c | 4 +- gcc/tree-ssa-operands.c | 11 ++++ 5 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr40389.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d4402d07d516..c3bd2c36bd1c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2009-06-17 Richard Guenther + + 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 PR middle-end/40460 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cb1d8a0fb7c3..842164faa782 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-06-17 Richard Guenther + + PR middle-end/40389 + * g++.dg/torture/pr40389.C: New testcase. + 2009-06-17 Richard Guenther 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 index 000000000000..e3ceb1238b6b --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr40389.C @@ -0,0 +1,84 @@ +/* { dg-do run } */ + +template 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 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; +} + diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index e7563784742c..a3067ed97c5d 100644 --- a/gcc/tree-scalar-evolution.c +++ b/gcc/tree-scalar-evolution.c @@ -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); } } diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index e4eb27c96a42..4eef41ea185b 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -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); + } } -- 2.47.2