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;