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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
We trigger:
  /* If I2 is a PARALLEL of two SETs of REGs (and perhaps some CLOBBERs),
     make those two SETs separate I1 and I2 insns, and make an I0 that is
     the original I1.  */
  if (!HAVE_cc0 && i0 == 0
      && is_parallel_of_n_reg_sets (PATTERN (i2), 2)
      && can_split_parallel_of_n_reg_sets (i2, 2)
      && !reg_used_between_p (SET_DEST (XVECEXP (PATTERN (i2), 0, 0)), i2, i3)
      && !reg_used_between_p (SET_DEST (XVECEXP (PATTERN (i2), 0, 1)), i2, i3))
    {
      /* If there is no I1, there is no I0 either.  */
      i0 = i1;

      /* We make I1 with the same INSN_UID as I2.  This gives it
         the same DF_INSN_LUID for value tracking.  Our fake I1 will
         never appear in the insn stream so giving it the same INSN_UID
         as I2 will not cause a problem.  */

      i1 = gen_rtx_INSN (VOIDmode, NULL, i2, BLOCK_FOR_INSN (i2),
                         XVECEXP (PATTERN (i2), 0, 0), INSN_LOCATION (i2),
                         -1, NULL_RTX);
      INSN_UID (i1) = INSN_UID (i2);

      SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 1));
    }
and thus i1 really isn't in the insn stream, it only has NEXT_INSN set to i2
(so in the only case where this is passed to can_combine_p succ is that i1 and
succ2 is the i2 right after it).
--- combine.c.jj        2017-03-21 07:57:01.000000000 +0100
+++ combine.c   2017-03-21 09:52:50.564214916 +0100
@@ -1955,7 +1955,7 @@ can_combine_p (rtx_insn *insn, rtx_insn
       || (JUMP_P (i3) && find_reg_note (i3, REG_NON_LOCAL_GOTO, NULL_RTX))
       /* Make sure that DEST is not used after INSN but before SUCC, or
         between SUCC and SUCC2.  */
-      || (succ && reg_used_between_p (dest, insn, succ))
+      || (succ && PREV_INSN (succ) && reg_used_between_p (dest, insn, succ))
       || (succ2 && reg_used_between_p (dest, succ, succ2))
       /* Make sure that DEST is not used after SUCC but before I3.  */
       || (!all_adjacent
fixes the ICE but isn't the right thing.

Reply via email to