From 7b645b3fb535557eb31d9dcef35517c164333f74 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Sat, 18 Sep 2010 18:53:53 +0000 Subject: [PATCH] re PR tree-optimization/45709 (internal compiler error: in add_phi_arg, at tree-phinodes.c:395) 2010-09-18 Richard Guenther PR tree-optimization/45709 * tree-inline.c (copy_phis_for_bb): Delay commit of edge insertions until after all PHI nodes of the block are processed. * g++.dg/torture/pr45709.C: New testcase. * g++.dg/torture/pr45709-2.C: Likewise. From-SVN: r164400 --- gcc/ChangeLog | 6 ++++++ gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/g++.dg/torture/pr45709-2.C | 20 ++++++++++++++++++++ gcc/testsuite/g++.dg/torture/pr45709.C | 19 +++++++++++++++++++ gcc/tree-inline.c | 11 +++++++++-- 5 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr45709-2.C create mode 100644 gcc/testsuite/g++.dg/torture/pr45709.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 77ccff35dbd6..01389454afa1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-09-18 Richard Guenther + + PR tree-optimization/45709 + * tree-inline.c (copy_phis_for_bb): Delay commit of edge + insertions until after all PHI nodes of the block are processed. + 2010-09-01 Eric Botcazou * gimplify.c (gimplify_init_constructor): Do not create a temporary for diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3394b20a873a..8ab1e45fcb28 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2010-09-18 Richard Guenther + + PR tree-optimization/45709 + * g++.dg/torture/pr45709.C: New testcase. + * g++.dg/torture/pr45709-2.C: Likewise. + 2010-08-11 Richard Guenther PR c/44555 diff --git a/gcc/testsuite/g++.dg/torture/pr45709-2.C b/gcc/testsuite/g++.dg/torture/pr45709-2.C new file mode 100644 index 000000000000..1f6a2344f04f --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr45709-2.C @@ -0,0 +1,20 @@ +// { dg-do compile } + +struct Region { + int storage[4]; + int count; +}; +static inline Region subtract(int lhs) +{ + Region reg; + int* storage = reg.storage; + int* storage2 = reg.storage; + if (lhs > 0) + storage++, storage2--; + reg.count = storage - reg.storage + storage2 - reg.storage; + return reg; +} +void bar(int a) +{ + const Region copyBack(subtract(a)); +} diff --git a/gcc/testsuite/g++.dg/torture/pr45709.C b/gcc/testsuite/g++.dg/torture/pr45709.C new file mode 100644 index 000000000000..1584ec76a997 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr45709.C @@ -0,0 +1,19 @@ +// { dg-do compile } + +struct Region { + int storage[4]; + int count; +}; +static inline Region subtract(int lhs) +{ + Region reg; + int* storage = reg.storage; + if (lhs > 0) + storage++; + reg.count = storage - reg.storage; + return reg; +} +void bar(int a) +{ + const Region copyBack(subtract(a)); +} diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 4da4a09ec1b3..94f08dee9d80 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1204,13 +1204,14 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id) basic_block new_bb = bb->aux; edge_iterator ei; tree phi; + edge new_edge; + bool inserted = false; for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) { tree res = PHI_RESULT (phi); tree new_res = res; tree new_phi; - edge new_edge; if (is_gimple_reg (res)) { @@ -1234,12 +1235,18 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id) tree stmts = NULL_TREE; new_arg = force_gimple_operand (new_arg, &stmts, true, NULL); - bsi_insert_on_edge_immediate (new_edge, stmts); + bsi_insert_on_edge (new_edge, stmts); + inserted = true; } add_phi_arg (new_phi, new_arg, new_edge); } } } + + /* Commit the delayed edge insertions. */ + if (inserted) + FOR_EACH_EDGE (new_edge, ei, new_bb->preds) + bsi_commit_one_edge_insert (new_edge, NULL); } /* Wrapper for remap_decl so it can be used as a callback. */ -- 2.47.2