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

--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> ---
Created attachment 57549
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=57549&action=edit
prototype fix

This is very similar to PR113831.  We again have two refs looking seemingly
the same:

  _80 = _109 + 1;
  _79 = VIEW_CONVERT_EXPR<unsigned long[8]>(y)[_80];
  _77 = .USUBC (0, _79, _103);

and

  _43 = _109 + 1;
  _42 = VIEW_CONVERT_EXPR<unsigned long[8]>(y)[_43];
  _39 = .USUBC (0, _42, _103);

so they are structurally entered in the same way into the expression hash
table.  But since _80 and _43 have different ranges what
get_ref_base_and_extent will compute differs - in the case of _109 <= 3
it will make the stmt walking hit the __builtin_memset and record a value
number of zero for the expresssion.

As we only after that (by bad luck) visit the other reference we successfully
look up the existing value from the hashtable during the walk.

In the PR113831 the accesses degenerated to a single array element which
allowed the fix to work (adjust the expression we put into the hash).  But
this shows (and I feared that ...) this doesn't work.  We either have to
make all ranges part of the expression (even if they make a difference in
the end) or avoid using ranges alltogether when computing a value for
an expression during the walk, most definitely when we walk to different
context (but that's hard to specify).

Maybe a middle-ground would be to make the get_ref_base_and_extent computed
info part of the expression.  Like the attached.  Lot's of ??? to address
though ...

Reply via email to