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.