Hi! As mentioned inthe PR, the switch expansion relies on EDGE_SUCC (bb, 0) from a GIMPLE_SWITCH to be the default edge, but GIMPLE only ensures that default label is the first one.
So, this patch (in expand_case) instead finds the default_edge from the default label and corresponding block. Another issue is emit_case_dispatch_table - this function is called from expand_case as well as sjlj landing pad handling. For the former, it suffers from a similar problem, and additionally we could have removed the default edge already, so even for switches that formerly had a default label we suddenly consider a random different edge as the default. For sjlj, I've just looked at one testcase in cross to hppa2.0w-hp-hpux10.0, and I believe stmt_bb should be just NULL, in any case if it would be non-NULL and there is some edge, it would hardly be the default edge, since the caller is emitting the default label after the switch expansion. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2017-08-04 Jakub Jelinek <ja...@redhat.com> PR middle-end/81698 * stmt.c (emit_case_dispatch_table): Add DEFAULT_EDGE argument, instead of computing it in the function. Formatting fix. (expand_case): Don't rely on default_edge being the first edge, clear it if removing it, pass default_edge to emit_case_dispatch_table. (expand_sjlj_dispatch_table): Pass NULL as DEFAULT_EDGE, formatting fix. --- gcc/stmt.c.jj 2017-07-14 13:04:47.000000000 +0200 +++ gcc/stmt.c 2017-08-04 14:36:28.936447265 +0200 @@ -945,8 +945,8 @@ conditional_probability (profile_probabi static void emit_case_dispatch_table (tree index_expr, tree index_type, struct case_node *case_list, rtx default_label, - tree minval, tree maxval, tree range, - basic_block stmt_bb) + edge default_edge, tree minval, tree maxval, + tree range, basic_block stmt_bb) { int i, ncases; struct case_node *n; @@ -954,7 +954,6 @@ emit_case_dispatch_table (tree index_exp rtx_insn *fallback_label = label_rtx (case_list->code_label); rtx_code_label *table_label = gen_label_rtx (); bool has_gaps = false; - edge default_edge = stmt_bb ? EDGE_SUCC (stmt_bb, 0) : NULL; profile_probability default_prob = default_edge ? default_edge->probability : profile_probability::never (); profile_probability base = get_outgoing_edge_probs (stmt_bb); @@ -1026,9 +1025,8 @@ emit_case_dispatch_table (tree index_exp through the indirect jump or the direct conditional jump before that. Split the probability of reaching the default label among these two jumps. */ - new_default_prob = conditional_probability (default_prob.apply_scale - (1, 2), - base); + new_default_prob + = conditional_probability (default_prob.apply_scale (1, 2), base); default_prob = default_prob.apply_scale (1, 2); base -= default_prob; } @@ -1147,9 +1145,10 @@ expand_case (gswitch *stmt) do_pending_stack_adjust (); /* Find the default case target label. */ - default_label = jump_target_rtx - (CASE_LABEL (gimple_switch_default_label (stmt))); - edge default_edge = EDGE_SUCC (bb, 0); + tree default_lab = CASE_LABEL (gimple_switch_default_label (stmt)); + default_label = jump_target_rtx (default_lab); + basic_block default_bb = label_to_block_fn (cfun, default_lab); + edge default_edge = find_edge (bb, default_bb); profile_probability default_prob = default_edge->probability; /* Get upper and lower bounds of case values. */ @@ -1245,9 +1244,10 @@ expand_case (gswitch *stmt) { default_label = NULL; remove_edge (default_edge); + default_edge = NULL; } emit_case_dispatch_table (index_expr, index_type, - case_list, default_label, + case_list, default_label, default_edge, minval, maxval, range, bb); } @@ -1340,9 +1340,9 @@ expand_sjlj_dispatch_table (rtx dispatch } emit_case_dispatch_table (index_expr, index_type, - case_list, default_label, + case_list, default_label, NULL, minval, maxval, range, - BLOCK_FOR_INSN (before_case)); + BLOCK_FOR_INSN (before_case)); emit_label (default_label); } Jakub