Hi! On the following testcase we ICE because the builtin fn prototype doesn't have throw () on it (glibc headers provide it, but some other C libraries apparently don't) and thus we can have EH edges out of the builtin, and call-cdce unconditionally split the block, leaving EH edge from an empty bb and the required EH edge missing from the call.
In that case there is no point in splitting the block though, so fixed thusly (not looking for last stmt, because that might be problematic with -fcompare-debug). Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/4.8? 2013-08-15 Jakub Jelinek <[email protected]> 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. * g++.dg/opt/pr58165.C: New test. --- gcc/tree-call-cdce.c.jj 2013-08-13 12:20:33.000000000 +0200 +++ gcc/tree-call-cdce.c 2013-08-15 14:54:28.328435719 +0200 @@ -726,15 +726,28 @@ shrink_wrap_one_built_in_call (gimple bi 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; --- gcc/testsuite/g++.dg/opt/pr58165.C.jj 2013-08-15 14:39:20.492586499 +0200 +++ gcc/testsuite/g++.dg/opt/pr58165.C 2013-08-15 14:38:43.000000000 +0200 @@ -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); +} Jakub
