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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |ASSIGNED
   Last reconfirmed|                            |2019-07-18
                 CC|                            |jakub at gcc dot gnu.org
           Assignee|unassigned at gcc dot gnu.org      |jakub at gcc dot gnu.org
   Target Milestone|---                         |10.0
            Summary|ICE on valid code: in       |[10 Regression] ICE on
                   |hashtab_chk_error, at       |valid code: in
                   |hash-table.c:137            |hashtab_chk_error, at
                   |                            |hash-table.c:137
     Ever confirmed|0                           |1

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The bug is that offset_address etc. do:
  update_temp_slot_address (XEXP (memref, 0), new_rtx);
  new_rtx = change_address_1 (memref, VOIDmode, new_rtx, 1, false);
where the first call inserts new_rtx
(plus:DI (reg/f:DI 77 virtual-stack-vars)
    (const_int 1599999999999999984 [0x16345785d89ffff0]))
into a hash table but then change_address_1 modifies that in place when trying
to legitimize that address into:
(plus:DI (reg/f:DI 77 virtual-stack-vars)
    (reg:DI 134))
and as that is a different rtx, it has a different hash value, but nothing
removes it from the hash table and reinserts with a new hash, so when we later
try to add that new expression into the hash table with the correct hash, we
run into the hash checking, because there is something equal to it with
different hash.

The following seems to fix it, not sure we can do something better:

--- gcc/function.c.jj   2019-07-10 15:52:56.785588326 +0200
+++ gcc/function.c      2019-07-18 09:40:40.172869182 +0200
@@ -704,7 +704,7 @@ static void
 insert_temp_slot_address (rtx address, class temp_slot *temp_slot)
 {
   struct temp_slot_address_entry *t = ggc_alloc<temp_slot_address_entry> ();
-  t->address = address;
+  t->address = copy_rtx (address);
   t->temp_slot = temp_slot;
   t->hash = temp_slot_address_compute_hash (t);
   *temp_slot_address_table->find_slot_with_hash (t, t->hash, INSERT) = t;

Reply via email to