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

--- Comment #18 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So, I've hacked up assembly version which contained 2 versions of this function
(good and bad) plus a wrapper function:
void *
vn_reference_lookup_2b (ao_ref *op, tree vuse, unsigned int cnt, void *vr_);
void *
vn_reference_lookup_2c (ao_ref *op, tree vuse, unsigned int cnt, void *vr_);

void *
vn_reference_lookup_2a (ao_ref *op, tree vuse, unsigned int cnt, void *vr_)
{
  vn_reference_t vr = (vn_reference_t)vr_;
  vn_reference_s a = *vr;
  void *r1 = vn_reference_lookup_2a (op, vuse, cnt, vr_);
  vn_reference_s b = *vr;
  *vr = a;
  void *r2 = vn_reference_lookup_2b (op, vuse, cnt, vr_);
  if (r1 != r2 || __builtin_memcmp (vr, &b, sizeof (b)))
    fancy_abort (__FILE__, __LINE__, __FUNCTION__);
  return r1;
}

adjusted in the assembly, so that it is actually that vn_reference_lookup_2
that calls the good and bad versions.
This ICEs on the second call to vn_reference_lookup_2.
vuse is .MEM_59, so is vr->vuse on entry and vr->hashcode is 0xd16d45ea.
The
  if (vr->vuse)
    vr->hashcode = vr->hashcode - (vr->vuse)->base.u.version;
is performed correctly in both, changing vr->hashcode to 0xd16d45af (i.e.
subtracting 59), next vr->vuse is updated to .MEM_48.
The problem is with the
  if (vr->vuse)
    vr->hashcode = vr->hashcode + (vr->vuse)->base.u.version;
in the good version it does what the source tells it to do, adds 48, making
vr->hashcode 0xd16d45df and calling find_slot_with_hash with that value.
But in the bad version, we actually store 0xd16d45ea again.

Reply via email to