This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug rtl-optimization/79150] ICE: in commit_one_edge_insertion, at cfgrtl.c:2077 for the gcc.dg/pr77834.c test
- From: "tomtab at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 24 Feb 2017 16:47:43 +0000
- Subject: [Bug rtl-optimization/79150] ICE: in commit_one_edge_insertion, at cfgrtl.c:2077 for the gcc.dg/pr77834.c test
- Auto-submitted: auto-generated
- References: <bug-79150-4@http.gcc.gnu.org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79150
--- Comment #5 from tomtab at gcc dot gnu.org ---
Here are some more details about this failure:
It is caused by "gcc_assert (!JUMP_P (last))" in
commit_one_edge_insertion (gcc/cfgrtl.c:2077):
if (returnjump_p (last))
{
/* ??? Remove all outgoing edges from BB and add one for EXIT.
This is not currently a problem because this only happens
for the (single) epilogue, which already has a fallthru edge
to EXIT. */
e = single_succ_edge (bb);
gcc_assert (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun)
&& single_succ_p (bb) && (e->flags & EDGE_FALLTHRU));
e->flags &= ~EDGE_FALLTHRU;
emit_barrier_after (last);
if (before)
delete_insn (before);
}
else
gcc_assert (!JUMP_P (last));
The assert is triggered because we're removing an edge which ends on
a conditional jump, which is part of a loop.
The primary reason for the existence of this loop is the fact that the code in
gcc.dg/pr77834.c uses vector extensions.
When compiling code which uses vectors, a looping memcpy is generated if the
vectors are big enough, i.e. >32 bytes for MIPS32 or >64 bytes for MIPS64.
This is done by mips_expand_block_move (gcc/config/mips.c:8103).
Such a memcpy can be generated for a partition copy which is then inserted on
an edge (in insert_partition_copy_on_edge, gcc/tree-outof-ssa.c:239).
This is done during PHI node elimination, which is done by eliminate_phi
(gcc/tree-outof-ssa.c:700), which is called by expand_phi_nodes, as a part of
the expand pass (gcc/cfgexpand.c:6339).
My proposed fix was to update the CFG by calling find_many_sub_basic_blocks
with an all-one block bitmap (which also happens in cfgexpand.c, after edge
removal) whenever an edge contains an insn which satisfies control_flow_insn_p
(see proposed patch in the post above).
However, Segher Boessenkool suggested that we could insert some kind of a nop
whenever the edge ends on a conditional jump, in order to minimize the risk of
breaking the compiler at such a late stage in the development cycle.
So, what would be an appropriate solution for this ?