https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86108

--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #5)
> The problem is in cross-jumping, we have a landing pad with one
> EDGE_CROSSING and some EH predecessor edges.  The DF code treats the
> bb_has_eh_pred specially and creates artificial generation of the
> EH_RETURN_DATA_REGNO blocks at the start of those blocks, rather than making
> those regs visible on the in edge.
> 
> I've tried:
> --- gcc/bb-reorder.c.jj       2018-05-31 21:51:18.508292965 +0200
> +++ gcc/bb-reorder.c  2018-06-15 12:57:34.501095317 +0200
> @@ -1507,8 +1507,11 @@ dw2_fix_up_crossing_landing_pad (eh_land
>    new_lp->landing_pad = gen_label_rtx ();
>    LABEL_PRESERVE_P (new_lp->landing_pad) = 1;
>  
> +  e = split_block_after_labels (old_bb);
> +  old_bb = e->src;
> +
>    /* Create the forwarder block.  */
> -  basic_block new_bb = create_forwarder_block (new_lp->landing_pad, old_bb);
> +  basic_block new_bb = create_forwarder_block (new_lp->landing_pad,
> e->dest);
>  
>    /* Fix up the edges.  */
>    for (ei = ei_start (old_bb->preds); (e = ei_safe_edge (ei)) != NULL; )
> to make sure we don't have bbs with both EDGE_CROSSING and EH incoming edges.
> Another possibility is to disallow cross-jumping of the bb_has_eh_pred basic
> blocks, like:
> --- gcc/cfgcleanup.c.jj       2018-04-25 09:41:37.753686037 +0200
> +++ gcc/cfgcleanup.c  2018-06-15 13:18:43.173257421 +0200
> @@ -1976,6 +1976,12 @@ try_crossjump_to_edge (int mode, edge e1
>    if (!outgoing_edges_match (mode, src1, src2))
>      return false;
>  
> +  /* The DF uses magic for EH landing pads where the EH_RETURN_DATA_REGNO
> +     regs are artificially defined at the start.  Avoid cross-jumping in
> +     between the EH landing pads and other bbs.  */
> +  if (bb_has_eh_pred (src1) != bb_has_eh_pred (src2))
> +    return false;
> +
>    /* ... and part the second.  */
>    nmatch = flow_find_cross_jump (src1, src2, &newpos1, &newpos2, &dir);
>  
> Either of the patches fix the testcase, there is some code growth though,
> but maybe it is mainly about adding the missing register moves that are
> incorrectly missing without them.  Without the patches main has 3259 bytes
> and main.cold 1276 bytes, with the first path it is 3337/1371 bytes and with
> the second patch instead 3337/1374 bytes.
> Conceptually, I think the first patch is better, the DF info isn't incorrect
> then (if we have bbs with both crossing and EH predecessors, we don't
> mention the EH regs in lr/live in on the EH pad nor in lr/live out on the EH
> pad in the other partition that just branches to it.

You mean without splitting the block the DF info is incorrect?  If so should
we add sth to verify-flow-info that makes sure we do not have EDGE_CROSSING
and EH incoming edges?  Can't an EH edge be EDGE_CROSSING itself?

Reply via email to