https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87132
--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
Simplified:
extern void abort (void);
int c, d;
int main()
{
int e[] = {4, 4, 4, 4, 4, 4, 4, 4, 4};
d = 8;
for (; d; d--)
for (int a = 0; a <= 8; a++)
{
c = e[1];
e[d] = 0;
}
if (c != 0)
abort ();
return 0;
}
this one is going to be interesting to fix. The issue is that we either
stop iterating too early or we over-eagerly use values from the previous
iteration when walk_non_aliased_vuses skips over e[d] = 0 when looking
for aliasing defs to e[1]. d still has the previous iteration value of 8
because we didn't yet re-visit the load of it when walking defs across
the backedge.
So this is
static void *
vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
bool *disambiguate_only)
{
...
/* First try to disambiguate after value-replacing in the definitions LHS.
*/
if (is_gimple_assign (def_stmt))
{
...
lhs_ops = valueize_refs_1 (lhs_ops, &valueized_anything, true);
as well as the load from e[1] in the first iteration not needing to
visit e[d] because of the not yet executable backedge and thus the
virtual PHI degenerating to the entry value.
A fix could be somehow tracking memory state changes and iterating once more
or avoiding last-iteration values in valueization (or valueization completely
when performing the walk over backedges). The latter latter is easiest,
testing that for fallout.
Index: gcc/tree-ssa-alias.c
===================================================================
--- gcc/tree-ssa-alias.c (revision 263944)
+++ gcc/tree-ssa-alias.c (working copy)
@@ -2722,7 +2722,14 @@ next:;
if (arg1 == arg0)
;
else if (! maybe_skip_until (phi, arg0, ref, arg1, cnt, visited,
- abort_on_visited, translate, data))
+ abort_on_visited,
+ /* Do not translate when walking over
+ backedges. */
+ dominated_by_p
+ (CDI_DOMINATORS,
+ gimple_bb (SSA_NAME_DEF_STMT (arg1)),
+ phi_bb)
+ ? NULL : translate, data))
return NULL_TREE;
}