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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ebotcazou at gcc dot gnu.org,
                   |                            |law at gcc dot gnu.org

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So, what I see that happens is that when processing that insn 97, insert_regs
calls make_regs_eqv (135, 131) and as pseudo 131 is live at the end of the bb
while pseudo 135 is not, 131 is selected as the canonical register for the
equivalence.
5968            elt = insert (dest, sets[i].src_elt,
5969                          sets[i].dest_hash, GET_MODE (dest));
afterwards stores the table entry, but under the pseudo 135, such as
lookup_for_remove (reg_135, HASH (reg_135), E_VOIDmode) is non-NULL and
contains
in ->exp reg_135 and in ->first_same_value->exp reg_131, while
lookup_for_remove (reg_131, HASH (reg_131), E_VOIDmode) is NULL.
Later on we process the 131 = 135 assignment, canonicalize_insn canonicalizes
that into 131 = 131 assignment (i.e. noop).
Later we invalidate_reg (reg_131) as the destination, which undoes the reg
equivalency, but as lookup_for_remove (reg_131, HASH (reg_131), E_VOIDmode)
used to be NULL, nothing is removed from the table.  And then insert_regs is
called again, and ICEs, because
1128                      gcc_assert (REGNO_QTY_VALID_P (c_regno));
I'd think that invalidate_reg really should remove the traces of that pseudo
from the tables, wonder e.g. if the remove_pseudo_from_table call in
invalidate_reg couldn't be done before delete_reg_equiv and lookup_for_remove
use exp_equiv_p.  It does use it already for the !REG_P case, but I believe it
is never called with non-REG.

Reply via email to