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 ...