This is an archive of the discontinued LLVM Phabricator instance.

[BasicAA] Check if V is itself a PHI in isValueEqualInPotentialCycles
Needs RevisionPublic

Authored by jholewinski on Mar 29 2022, 10:53 AM.

Details

Reviewers
nikic
Summary

BasicAAResult::isValueEqualInPotentialCycles uses previously visited
PHI nodes to determine if a value is provably equal across cycles.
But it does not consider the case where the value itself is a PHI
node that is reachable from itself, implying a cycle in the CFG. This
change teaches isValueEqualInPotentialCycles to handle this case by
explicitly checking if the incoming value is a PHI and checking if it
is reachable from itself.

Diff Detail

Event Timeline

jholewinski created this revision.Mar 29 2022, 10:53 AM
jholewinski requested review of this revision.Mar 29 2022, 10:53 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 29 2022, 10:53 AM
nikic requested changes to this revision.Mar 29 2022, 12:14 PM
nikic added a subscriber: nikic.

Reporting NoAlias here is correct -- cross-iteration behavior is outside the purview of AA. Consuming code is responsible for interpreting this correctly, see e.g. the loop invariance checks in MemorySSA and DSE.

Can you share what your original problem was? Possibly some transform makes incorrect assumptions about the meaning of AA results.

This revision now requires changes to proceed.Mar 29 2022, 12:14 PM

Reporting NoAlias here is correct -- cross-iteration behavior is outside the purview of AA. Consuming code is responsible for interpreting this correctly, see e.g. the loop invariance checks in MemorySSA and DSE.

Ok, thanks for the information. Is this documented somewhere in the LLVM docs? I looked around before creating this diff but didn't see anything that says either way whether LLVM AA is supposed to return MayAlias if it cannot prove pointers cannot alias across iterations. I was also thrown off by a few comments in BasicAA that seems to imply it does track aliasing across iterations.

[is this not checking whether the value may change across iterations?]

// Make sure that the visited phis cannot reach the Value. This ensures that
// the Values cannot come from different iterations of a potential cycle the
// phi nodes could be involved in.
for (auto *P : VisitedPhiBBs)
  if (isPotentiallyReachable(&P->front(), Inst, nullptr, DT))
    return false;

[reference to skipping a case to prevent needing to handle cross-iteration aliasing]

// VarIndex = Scale*V0 + (-Scale)*V1.
// If V0 != V1 then abs(VarIndex) >= abs(Scale).
// Check that VisitedPhiBBs is empty, to avoid reasoning about
// inequality of values across loop iterations.
const VariableGEPIndex &Var0 = DecompGEP1.VarIndices[0];
const VariableGEPIndex &Var1 = DecompGEP1.VarIndices[1];

[analyzes cross-iteration equality?]

// Are we checking for alias of the same value?
// Because we look 'through' phi nodes, we could look at "Value" pointers from
// different iterations. We must therefore make sure that this is not the
// case. The function isValueEqualInPotentialCycles ensures that this cannot
// happen by looking at the visited phi nodes and making sure they cannot
// reach the value.
if (isValueEqualInPotentialCycles(V1, V2))
  return AliasResult::MustAlias;

Am I just misunderstanding what BasicAA is trying to do here?

Can you share what your original problem was? Possibly some transform makes incorrect assumptions about the meaning of AA results.

The issue is in an out-of-tree pass that we wrote. If BasicAA does not return MayAlias for pointers across loop iterations then we do have an incorrect assumption.

The VisitedPhiBBs handling is related, but handles a different case: Sometimes, BasicAA itself will be looking across loop iterations when recursing into a phi, and VisitedPhiBBs is used to not assume equality relationships when that happens.