Hi, this patch fixes the testcasein PR63186. Here a forced label is used and fnsplit decides to split its use from definition that does not work. There is code that is supposed to prevent this. It however works on non-ssa declarations in general and it has an optimization - it allows the non-ssa declarations to be split when their liveranes do not overlap by skipping all the definitions in header parts that do not lead to function call. This doesn't work for labels: we really want to consider all label definitions in this case.
I also added minor optimization skipping all non-forced labels to save non-ssa verficiation pass when there are no non-ssa vars involved (the common case) Bootstrapped/regtested x86_64-linux, will commit it tomorrow if there are no complains. Honza PR tree-optimization/63186 * gcc.dg/pr63186.c: New testcase. * ipa-split.c (test_nonssa_use): Skip non-forced labels. (verify_non_ssa_vars): Verify blocks not leading to the call for label definitions. (mark_nonssa_use): Skip non-forced labels. Index: testsuite/gcc.dg/pr63186.c =================================================================== --- testsuite/gcc.dg/pr63186.c (revision 0) +++ testsuite/gcc.dg/pr63186.c (revision 0) @@ -0,0 +1,30 @@ +/* { dg-do link } */ +/* { dg-options "-O2" } */ +void *a; +int b, c, d; + +void +bar () +{ + switch (c) + { + case 0: + lab: + __asm__ (""); + return; + default: + break; + } + b = 0; + d = 0; + a = &&lab; +} + +void +foo () +{ + bar (); +} +main() +{ +} Index: ipa-split.c =================================================================== --- ipa-split.c (revision 215104) +++ ipa-split.c (working copy) @@ -167,7 +167,11 @@ test_nonssa_use (gimple, tree t, tree, v || (TREE_CODE (t) == VAR_DECL && auto_var_in_fn_p (t, current_function_decl)) || TREE_CODE (t) == RESULT_DECL - || TREE_CODE (t) == LABEL_DECL) + /* Normal labels are part of CFG and will be handled gratefuly. + Forced labels however can be used directly by statements and + need to stay in one partition along with their uses. */ + || (TREE_CODE (t) == LABEL_DECL + && FORCED_LABEL (t))) return bitmap_bit_p ((bitmap)data, DECL_UID (t)); /* For DECL_BY_REFERENCE, the return value is actually a pointer. We want @@ -213,6 +217,7 @@ verify_non_ssa_vars (struct split_point edge e; edge_iterator ei; bool ok = true; + basic_block bb; FOR_EACH_EDGE (e, ei, current->entry_bb->preds) if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun) @@ -225,8 +230,8 @@ verify_non_ssa_vars (struct split_point while (!worklist.is_empty ()) { gimple_stmt_iterator bsi; - basic_block bb = worklist.pop (); + bb = worklist.pop (); FOR_EACH_EDGE (e, ei, bb->preds) if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun) && bitmap_set_bit (seen, e->src->index)) @@ -250,10 +255,10 @@ verify_non_ssa_vars (struct split_point if (gimple_code (stmt) == GIMPLE_LABEL && test_nonssa_use (stmt, gimple_label_label (stmt), NULL_TREE, non_ssa_vars)) - { - ok = false; - goto done; - } + { + ok = false; + goto done; + } } for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi)) { @@ -286,6 +291,27 @@ verify_non_ssa_vars (struct split_point } } } + + /* Verify that the rest of function does not define any label + used by the split part. */ + FOR_EACH_BB_FN (bb, cfun) + if (!bitmap_bit_p (current->split_bbs, bb->index) + && !bitmap_bit_p (seen, bb->index)) + { + gimple_stmt_iterator bsi; + for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) + if (gimple_code (gsi_stmt (bsi)) == GIMPLE_LABEL + && test_nonssa_use (gsi_stmt (bsi), + gimple_label_label (gsi_stmt (bsi)), + NULL_TREE, non_ssa_vars)) + { + ok = false; + goto done; + } + else if (gimple_code (gsi_stmt (bsi)) != GIMPLE_LABEL) + break; + } + done: BITMAP_FREE (seen); worklist.release (); @@ -735,7 +761,8 @@ mark_nonssa_use (gimple, tree t, tree, v if ((TREE_CODE (t) == VAR_DECL && auto_var_in_fn_p (t, current_function_decl)) || TREE_CODE (t) == RESULT_DECL - || TREE_CODE (t) == LABEL_DECL) + || (TREE_CODE (t) == LABEL_DECL + && FORCED_LABEL (t))) bitmap_set_bit ((bitmap)data, DECL_UID (t)); /* For DECL_BY_REFERENCE, the return value is actually a pointer. We want