diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a5975f55d6c..810b8a55288 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2013-08-16 Jakub Jelinek + + PR tree-optimization/58165 + * tree-call-cdce.c (shrink_wrap_one_built_in_call): If + bi_call must be the last stmt in a bb, don't split_block, instead + use fallthru edge from it and give up if there is none. + Release conds vector when returning early. + 2013-08-14 Xinliang David Li * config/i386/i386.c (ix86_option_override_internal): diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9b115a48df3..84679bbbb65 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-08-16 Jakub Jelinek + + PR tree-optimization/58165 + * g++.dg/opt/pr58165.C: New test. + 2013-08-14 Paolo Carlini PR c++/51912 diff --git a/gcc/testsuite/g++.dg/opt/pr58165.C b/gcc/testsuite/g++.dg/opt/pr58165.C new file mode 100644 index 00000000000..d758e370050 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr58165.C @@ -0,0 +1,14 @@ +// PR tree-optimization/58165 +// { dg-do compile } +// { dg-options "-O2" } + +extern "C" float sqrtf (float); + +struct A { A (); ~A (); }; + +void +foo (double d) +{ + A a; + sqrtf (d); +} diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c index 8edcad93b8b..1396388676b 100644 --- a/gcc/tree-call-cdce.c +++ b/gcc/tree-call-cdce.c @@ -726,15 +726,28 @@ shrink_wrap_one_built_in_call (gimple bi_call) return false and do not do any transformation for the call. */ if (nconds == 0) - return false; + { + conds.release (); + return false; + } bi_call_bb = gimple_bb (bi_call); - /* Now find the join target bb -- split - bi_call_bb if needed. */ - bi_call_bsi = gsi_for_stmt (bi_call); + /* Now find the join target bb -- split bi_call_bb if needed. */ + if (stmt_ends_bb_p (bi_call)) + { + /* If the call must be the last in the bb, don't split the block, + it could e.g. have EH edges. */ + join_tgt_in_edge_from_call = find_fallthru_edge (bi_call_bb->succs); + if (join_tgt_in_edge_from_call == NULL) + { + conds.release (); + return false; + } + } + else + join_tgt_in_edge_from_call = split_block (bi_call_bb, bi_call); - join_tgt_in_edge_from_call = split_block (bi_call_bb, bi_call); bi_call_bsi = gsi_for_stmt (bi_call); join_tgt_bb = join_tgt_in_edge_from_call->dest;