From: Jakub Jelinek Date: Fri, 12 Feb 2016 11:57:54 +0000 (+0100) Subject: re PR ipa/68672 (g++.dg/torture/pr68470.C: ICE: cannot update SSA form: statement... X-Git-Tag: basepoints/gcc-7~981 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b69539cbf58a1d0c918759dc12cf384922661753;p=thirdparty%2Fgcc.git re PR ipa/68672 (g++.dg/torture/pr68470.C: ICE: cannot update SSA form: statement uses released SSA name) PR ipa/68672 * ipa-split.c (split_function): Don't compute/use main_part_return_p. Compute retval and retbnd early in all cases if split_part_return_p and return_bb is not EXIT. Remove all clobber stmts and reset all debug stmts that refer to SSA_NAMEs defined in split part, except if it is retval, in that case replace the old retval with the lhs of the call to the split part. * g++.dg/ipa/pr68672-1.C: New test. * g++.dg/ipa/pr68672-2.C: New test. * g++.dg/ipa/pr68672-3.C: New test. From-SVN: r233374 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4226287dee8c..3588b15362fe 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2016-02-12 Jakub Jelinek + + PR ipa/68672 + * ipa-split.c (split_function): Don't compute/use main_part_return_p. + Compute retval and retbnd early in all cases if split_part_return_p + and return_bb is not EXIT. Remove all clobber stmts and reset + all debug stmts that refer to SSA_NAMEs defined in split part, + except if it is retval, in that case replace the old retval with the + lhs of the call to the split part. + 2016-02-12 Kugan Vivekanandarajah revert: diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c index 21fd46f50c8a..2528a7965022 100644 --- a/gcc/ipa-split.c +++ b/gcc/ipa-split.c @@ -1244,28 +1244,13 @@ split_function (basic_block return_bb, struct split_point *split_point, args_to_pass.safe_push (arg); } - /* See if the split function or the main part will return. */ - bool main_part_return_p = false; + /* See if the split function will return. */ bool split_part_return_p = false; FOR_EACH_EDGE (e, ei, return_bb->preds) { if (bitmap_bit_p (split_point->split_bbs, e->src->index)) split_part_return_p = true; - else - main_part_return_p = true; } - /* The main part also returns if we split on a fallthru edge - and the split part returns. */ - if (split_part_return_p) - FOR_EACH_EDGE (e, ei, split_point->entry_bb->preds) - { - if (! bitmap_bit_p (split_point->split_bbs, e->src->index) - && single_succ_p (e->src)) - { - main_part_return_p = true; - break; - } - } /* Add return block to what will become the split function. We do not return; no return block is needed. */ @@ -1279,8 +1264,8 @@ split_function (basic_block return_bb, struct split_point *split_point, FIXME: Once we are able to change return type, we should change function to return void instead of just outputting function with undefined return value. For structures this affects quality of codegen. */ - else if (!split_point->split_part_set_retval - && (retval = find_retval (return_bb))) + else if ((retval = find_retval (return_bb)) + && !split_point->split_part_set_retval) { bool redirected = true; basic_block new_return_bb = create_basic_block (NULL, 0, return_bb); @@ -1308,12 +1293,10 @@ split_function (basic_block return_bb, struct split_point *split_point, } /* When we pass around the value, use existing return block. */ else - bitmap_set_bit (split_point->split_bbs, return_bb->index); - - /* If the main part doesn't return pretend the return block wasn't - found for all of the following. */ - if (! main_part_return_p) - return_bb = EXIT_BLOCK_PTR_FOR_FN (cfun); + { + bitmap_set_bit (split_point->split_bbs, return_bb->index); + retbnd = find_retbnd (return_bb); + } /* If RETURN_BB has virtual operand PHIs, they must be removed and the virtual operand marked for renaming as we change the CFG in a way that @@ -1382,6 +1365,44 @@ split_function (basic_block return_bb, struct split_point *split_point, DECL_FUNCTION_CODE (node->decl) = (enum built_in_function) 0; } + /* If return_bb contains any clobbers that refer to SSA_NAMEs + set in the split part, remove them. Also reset debug stmts that + refer to SSA_NAMEs set in the split part. */ + if (return_bb != EXIT_BLOCK_PTR_FOR_FN (cfun)) + { + gimple_stmt_iterator gsi = gsi_start_bb (return_bb); + while (!gsi_end_p (gsi)) + { + tree op; + ssa_op_iter iter; + gimple *stmt = gsi_stmt (gsi); + bool remove = false; + if (gimple_clobber_p (stmt) || is_gimple_debug (stmt)) + FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE) + { + basic_block bb = gimple_bb (SSA_NAME_DEF_STMT (op)); + if (op != retval + && bb + && bb != return_bb + && bitmap_bit_p (split_point->split_bbs, bb->index)) + { + if (is_gimple_debug (stmt)) + { + gimple_debug_bind_reset_value (stmt); + update_stmt (stmt); + } + else + remove = true; + break; + } + } + if (remove) + gsi_remove (&gsi, true); + else + gsi_next (&gsi); + } + } + /* If the original function is instrumented then it's part is also instrumented. */ if (with_bounds) @@ -1499,9 +1520,7 @@ split_function (basic_block return_bb, struct split_point *split_point, return value into and put call just before it. */ if (return_bb != EXIT_BLOCK_PTR_FOR_FN (cfun)) { - real_retval = retval = find_retval (return_bb); - retbnd = find_retbnd (return_bb); - + real_retval = retval; if (real_retval && split_point->split_part_set_retval) { gphi_iterator psi; @@ -1545,6 +1564,28 @@ split_function (basic_block return_bb, struct split_point *split_point, break; } update_stmt (gsi_stmt (bsi)); + /* Also adjust clobbers and debug stmts in return_bb. */ + for (bsi = gsi_start_bb (return_bb); !gsi_end_p (bsi); + gsi_next (&bsi)) + { + gimple *stmt = gsi_stmt (bsi); + if (gimple_clobber_p (stmt) + || is_gimple_debug (stmt)) + { + ssa_op_iter iter; + use_operand_p use_p; + bool update = false; + FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, + SSA_OP_USE) + if (USE_FROM_PTR (use_p) == real_retval) + { + SET_USE (use_p, retval); + update = true; + } + if (update) + update_stmt (stmt); + } + } } /* Replace retbnd with new one. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cd3161fac13f..79f8f5a9e4f8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2016-02-12 Jakub Jelinek + + PR ipa/68672 + * g++.dg/ipa/pr68672-1.C: New test. + * g++.dg/ipa/pr68672-2.C: New test. + * g++.dg/ipa/pr68672-3.C: New test. + 2016-02-12 Bernd Schmidt PR c/69522 diff --git a/gcc/testsuite/g++.dg/ipa/pr68672-1.C b/gcc/testsuite/g++.dg/ipa/pr68672-1.C new file mode 100644 index 000000000000..fddabe17a434 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr68672-1.C @@ -0,0 +1,20 @@ +// PR ipa/68672 +// { dg-do compile } +// { dg-options "-O -finline-small-functions -fpartial-inlining --param=partial-inlining-entry-probability=100" } + +void f2 (void *); +void *a; +struct C { virtual void m1 (); }; +struct D { C *m2 () { if (a) __builtin_abort (); } }; +D f1 (); +struct E { int e; ~E () { if (e) f2 (&e); } }; +E *b; +struct I { virtual void m3 (); }; + +void +I::m3 () +{ + if (a) + f1 ().m2 ()->m1 (); + b->~E (); +} diff --git a/gcc/testsuite/g++.dg/ipa/pr68672-2.C b/gcc/testsuite/g++.dg/ipa/pr68672-2.C new file mode 100644 index 000000000000..f23ae80c7a2a --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr68672-2.C @@ -0,0 +1,54 @@ +// PR ipa/68672 +// { dg-do compile } +// { dg-options "-O3 --param=partial-inlining-entry-probability=100 -g" } + +struct S { ~S () {} }; +S *a; +int *b; +void bar (); +void baz (); +void fn (int *); + +static int +foo () +{ + S *c = a; + if (c) + { + bar (); + if (a) + __builtin_abort (); + baz (); + } + int p = *b; + if (p) + { + fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); + fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); + fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); + fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); + } + c->~S (); + int q = 2 * p; + int r = 3 * q; + S *d = c; + return p; +} + +void +use1 () +{ + foo (); +} + +void +use2 () +{ + foo (); +} + +void +use3 () +{ + foo (); +} diff --git a/gcc/testsuite/g++.dg/ipa/pr68672-3.C b/gcc/testsuite/g++.dg/ipa/pr68672-3.C new file mode 100644 index 000000000000..971ddf6c6b75 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr68672-3.C @@ -0,0 +1,57 @@ +// PR ipa/68672 +// { dg-do compile } +// { dg-options "-O3 --param=partial-inlining-entry-probability=100 -g" } + +struct S { ~S () {} }; +S *a, *e; +int *b; +void bar (); +void baz (); +void fn (int *); +void fn2 (S *); + +static int +foo () +{ + S *c = a; + if (c) + { + bar (); + if (a) + __builtin_abort (); + baz (); + } + int p = *b; + S *f = e; + if (p) + { + fn2 (f); + fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); + fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); + fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); + fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); fn (b); + } + f->~S (); + int q = 2 * p; + int r = 3 * q; + S *d = c; + return p; +} + +void +use1 () +{ + foo (); +} + +void +use2 () +{ + foo (); +} + +void +use3 () +{ + foo (); +}