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

--- Comment #5 from Eric Botcazou <ebotcazou at gcc dot gnu.org> ---
I think that calling finish_spills before select_reload_regs is incorrect:

static void
select_reload_regs (void)
{
  struct insn_chain *chain;

  /* Try to satisfy the needs for each insn.  */
  for (chain = insns_need_reload; chain != 0;
       chain = chain->next_need_reload)
    find_reload_regs (chain);
}

/* After find_reload_regs has been run for all insn that need reloads,
   and/or spill_hard_regs was called, this function is used to actually
   spill pseudo registers and try to reallocate them.  It also sets up the
   spill_regs array for use by choose_reload_regs.  */

static int
finish_spills (int global)

because finish_spills works globally, in particular:

  /* Retry global register allocation if possible.  */
  if (global && ira_conflicts_p)
    {
      unsigned int n;

      memset (pseudo_forbidden_regs, 0, max_regno * sizeof (HARD_REG_SET));
      /* For every insn that needs reloads, set the registers used as spill
         regs in pseudo_forbidden_regs for every pseudo live across the
         insn.  */
      for (chain = insns_need_reload; chain; chain = chain->next_need_reload)
        {
          EXECUTE_IF_SET_IN_REG_SET
            (&chain->live_throughout, FIRST_PSEUDO_REGISTER, i, rsi)
            {
              IOR_HARD_REG_SET (pseudo_forbidden_regs[i],
                                chain->used_spill_regs);
            }
          EXECUTE_IF_SET_IN_REG_SET
            (&chain->dead_or_set, FIRST_PSEUDO_REGISTER, i, rsi)
            {
              IOR_HARD_REG_SET (pseudo_forbidden_regs[i],
                                chain->used_spill_regs);
            }
        }

i.e. chain->used_spill_regs might be uninitialized for some insns here.

Index: reload1.c
===================================================================
--- reload1.c   (revision 237323)
+++ reload1.c   (working copy)
@@ -498,6 +498,7 @@ new_insn_chain (void)
   c->need_operand_change = 0;
   c->need_reload = 0;
   c->need_elim = 0;
+  CLEAR_HARD_REG_SET (c->used_spill_regs);
   return c;
 }

fixes the comparison failure, but it is still incorrect to access the regsets
at this point as they may not have been computed for some insns yet.

Reply via email to