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

--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> ---
So we have a NULL op, in this case

(gdb) p *vro1
$4 = {opcode = TARGET_MEM_REF, clique = 0, base = 0, reverse = 0, align = 0, 
  off = {coeffs = {-1}}, type = <real_type 0x7ffff7309930 float>, 
  op0 = <tree 0x0>, op1 = <tree 0x0>, op2 = <integer_cst 0x7ffff12cd138>}
(gdb) p *vro2
$5 = {opcode = TARGET_MEM_REF, clique = 0, base = 0, reverse = 0, align = 0, 
  off = {coeffs = {-1}}, type = <real_type 0x7ffff7309930 float>, 
  op0 = <ssa_name 0x7ffff656f120 8261>, op1 = <tree 0x0>, 
  op2 = <integer_cst 0x7ffff6119528>}

I think we're lucky to not hit this more often (good hash!) and unlucky
here (bad hash!).  We used to have

  /* If only one of them is null, they cannot be equal.  */
  if (!e1 || !e2)
    return false;

but r11-4982-g4d6b8d4213376e removed that.  r11-5047-gaaccdb9cec423e fixed
one case where that was previously needed.

Now, for TARGET_MEM_REF a NULL operand is different from an operand
with no effect (a zero) since the addressing mode is different.  So
canonicalization in copy_reference_ops_from_ref is unwanted (we'd use
that representation for PRE insertion for example).

The safest option is to restore the above check.

Reply via email to