[Bug rtl-optimization/86108] [8/9 Regression] crash during unwinding with -O2
rguenth at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Fri Jun 15 12:47:00 GMT 2018
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?
More information about the Gcc-bugs
mailing list