Created attachment 29916 [details] C source code I just tried to compile the package hplip-3.13.4-1 on gcc-4.9 trunk dated 20130421 on an AMD x86_64 box. The compiler said ip/xjpg_dec.c:2612:32: internal compiler error: in update_ssa_across_abnormal_edges, at tree-inline.c:1852 memset (g->out_rows_ap[comp][row], ycc_white[comp], row_len); ^ 0x94304d update_ssa_across_abnormal_edges ../../src/trunk/gcc/tree-inline.c:1852 0x94304d copy_edges_for_bb ../../src/trunk/gcc/tree-inline.c:1958 0x94304d copy_cfg_body ../../src/trunk/gcc/tree-inline.c:2276 0x94304d copy_body ../../src/trunk/gcc/tree-inline.c:2460 0x946ef3 expand_call_inline ../../src/trunk/gcc/tree-inline.c:4060 0x946ef3 gimple_expand_calls_inline ../../src/trunk/gcc/tree-inline.c:4167 0x946ef3 optimize_inline_calls(tree_node*) ../../src/trunk/gcc/tree-inline.c:4321 0xd37356 early_inliner ../../src/trunk/gcc/ipa-inline.c:2038 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <http://gcc.gnu.org/bugs.html> for instructions. Preprocessed source code attached. Flag -O2 required.
I will have a look.
Reduced testcase: extern void g (void); extern __inline __attribute__ ((__always_inline__,__leaf__)) f () { g (); } struct __jmp_buf_tag *b; int jpgDecode_convert (unsigned i) { if (i != 0) f (); read_buf_open (); return _setjmp (b); } marking 'g' leaf as well fixes the ICE. The inliner doesn't handle new abnormal edges appearing this way from a 'leaf' function which isn't considered as possibly causing abnormal goto edges. I suppose all these setjmp ICEs are latent with carefully constructed non-local goto testcases.
Closest equivalent non-local goto testcase that ICEs: int j_; int jpgDecode_convert (unsigned i) { __label__ label; int j; inline void __attribute__((always_inline,leaf)) f(void) { g(); } void __attribute__((noinline)) read_buf_open (void) { goto label; } if (i != 0) f (); j = j_; read_buf_open (); label: return j; } > ./cc1 -quiet -O0 t.i t.i: In function 'jpgDecode_convert': t.i:23:1: error: definition in block 4 does not dominate use in block 7 } ^ for SSA_NAME: j_2 in statement: _3 = j_2; t.i:23:1: internal compiler error: verify_ssa failed same underlying issue I believe.
Either don't inline into functions receiving non-local gotos or remove the ECF_LEAF handling from the call-may-do-longjmp predicate.
One idea was to mark calls with whether they may induce abnormal control flow and when inlining, do not make abnormal edges off any calls in the function. We still have to copy existing abnormal edges as within the callee there can be abnormal control flow, too. So there will be no way to later verify CFG correctness because we lose "scoping" information of abnormal control flow. Thus, the following simple patch is probably as good as we can get here ... (in testing). @@ -1866,7 +1870,8 @@ update_ssa_across_abnormal_edges (basic_ debug stmts are left after a statement that must end the basic block. */ static bool -copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb) +copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb, + bool can_make_abnormal_goto) { basic_block new_bb = (basic_block) bb->aux; edge_iterator ei; @@ -1921,7 +1926,11 @@ copy_edges_for_bb (basic_block bb, gcov_ into a COMPONENT_REF which doesn't. If the copy can throw, the original could also throw. */ can_throw = stmt_can_throw_internal (copy_stmt); - nonlocal_goto = stmt_can_make_abnormal_goto (copy_stmt); + /* If the call we inline cannot make abnormal goto do not add + additional abnormal edges but only retain those already present + in the original function body. */ + nonlocal_goto + = can_make_abnormal_goto && stmt_can_make_abnormal_goto (copy_stmt); if (can_throw || nonlocal_goto) { @@ -2270,10 +2279,12 @@ copy_cfg_body (copy_body_data * id, gcov last = last_basic_block; /* Now that we've duplicated the blocks, duplicate their edges. */ + bool can_make_abormal_goto = stmt_can_make_abnormal_goto (id->gimple_call); FOR_ALL_BB_FN (bb, cfun_to_copy) if (!blocks_to_copy || (bb->index > 0 && bitmap_bit_p (blocks_to_copy, bb->index))) - need_debug_cleanup |= copy_edges_for_bb (bb, count_scale, exit_block_map); + need_debug_cleanup |= copy_edges_for_bb (bb, count_scale, exit_block_map, + can_make_abormal_goto); if (new_entry) {
Author: rguenth Date: Tue Apr 23 14:36:02 2013 New Revision: 198192 URL: http://gcc.gnu.org/viewcvs?rev=198192&root=gcc&view=rev Log: 2013-04-23 Richard Biener <rguenther@suse.de> PR middle-end/57036 * tree-inline.c (copy_edges_for_bb): Add can_make_abnormal_goto parameter, only add abnormal goto edges from the copied body if the call could perform abnormal gotos. (copy_cfg_body): Adjust. * gcc.dg/torture/pr57036-1.c: New testcase. * gcc.dg/torture/pr57036-2.c: Likewise. Added: trunk/gcc/testsuite/gcc.dg/torture/pr57036-1.c trunk/gcc/testsuite/gcc.dg/torture/pr57036-2.c Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/tree-inline.c