https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124809
Andrew Macleod <amacleod at redhat dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
Assignee|unassigned at gcc dot gnu.org |amacleod at redhat dot
com
Status|NEW |ASSIGNED
--- Comment #11 from Andrew Macleod <amacleod at redhat dot com> ---
Created attachment 64196
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=64196&action=edit
proopsed patch
DOM rewrites a statement using valid local equivalences, but ranger does not
understans that this is replacing an existing equivalence rather than adding a
new one.
Given:
c = a;
if (a == b)
d = c;
...
if (c == b)
Ranger infers {a, c, d} as an equivalence class. Since c and b are unrelated,
the final condition is not foldable.
DOM rewrites:
d = c;
to:
d = b;
based on a == b and c == a, producing:
c = a;
if (a == b)
d = b;
...
if (c == b)
This transformation is valid, but DOM then re-runs Ranger on the updated
statement. Ranger sees d = b and adds a new equivalence, expanding the set to
{a, b, c, d}.
This is incorrect. The original equivalence from d = c was not removed, so d
now incorrectly bridges the two sets. As a result, Ranger folds if (c == b) to
true.
The core issue is that equivalences are only added, never removed. After
rewriting, the old equivalence must no longer apply, but there is currently no
mechanism to retract it.
This problem does not exist in VRP or other places because they either
a) do no revisit the statement once it is rewritten
b) save all the rewrites until the end.
I have a Fix which tracks whether an SSA name on the LHS has already had an
equivalence registered *as a LHS*, and only allows this once per stmt. This is
cheap and prevents the second equivalence from being registered. It does not
affect other equivalences being registered against the SSA_NAME from other
locations.
This is conservative but ensures this situation does not happen.
Currently running through the testsuite.