This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug rtl-optimization/79150] ICE: in commit_one_edge_insertion, at cfgrtl.c:2077 for the gcc.dg/pr77834.c test


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 ?

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]