aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/BasicAliasAnalysis.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2022-10-17 13:09:32 +0200
committerNikita Popov <npopov@redhat.com>2022-10-27 10:29:41 +0200
commit6c269a3f89edde33a472d53ed017c1adfb62afcb (patch)
tree3aae05f58aaef79ed3b65975bae98af30cb436af /llvm/lib/Analysis/BasicAliasAnalysis.cpp
parent17059753f1337209fb4cb06098c1bc65418775e9 (diff)
downloadllvm-6c269a3f89edde33a472d53ed017c1adfb62afcb.zip
llvm-6c269a3f89edde33a472d53ed017c1adfb62afcb.tar.gz
llvm-6c269a3f89edde33a472d53ed017c1adfb62afcb.tar.bz2
[BasicAA] Replace VisitedPhiBBs with a single flag
When looking through phis, BasicAA has to guard against the possibility that values from two separate cycle iterations are being compared -- in this case, even though the SSA values may be the same, they cannot be considered as equal. This is currently done by keeping a set of VisitedPhiBBs for any phis we looked through, and then checking whether the relevant instruction is reachable from one of the phis. This patch replaces this set with a single flag. If the flag is set, then we will not assume equality for any instruction part of a cycle. While this is nominally less accurate, it makes essentially no difference in practice. Here are the AA stats for test-suite: aa.NumMayAlias | 3072005 | 3072016 aa.NumMustAlias | 337858 | 337854 aa.NumNoAlias | 13255345 | 13255349 The motivation for the change is to expose the MayBeCrossIteration flag to AA users, which will allow fixing miscompiles related to incorrect handling of cross-iteration AA queries. Differential Revision: https://reviews.llvm.org/D136174
Diffstat (limited to 'llvm/lib/Analysis/BasicAliasAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/BasicAliasAnalysis.cpp51
1 files changed, 21 insertions, 30 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index cca5394..19ff4ba 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -54,6 +54,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/KnownBits.h"
+#include "llvm/Support/SaveAndRestore.h"
#include <cassert>
#include <cstdint>
#include <cstdlib>
@@ -1252,12 +1253,12 @@ AliasResult BasicAAResult::aliasGEP(
} else if (DecompGEP1.VarIndices.size() == 2) {
// VarIndex = Scale*V0 + (-Scale)*V1.
// If V0 != V1 then abs(VarIndex) >= abs(Scale).
- // Check that VisitedPhiBBs is empty, to avoid reasoning about
+ // Check that MayBeCrossIteration is false, to avoid reasoning about
// inequality of values across loop iterations.
const VariableGEPIndex &Var0 = DecompGEP1.VarIndices[0];
const VariableGEPIndex &Var1 = DecompGEP1.VarIndices[1];
if (Var0.Scale == -Var1.Scale && Var0.Val.TruncBits == 0 &&
- Var0.Val.hasSameCastsAs(Var1.Val) && VisitedPhiBBs.empty() &&
+ Var0.Val.hasSameCastsAs(Var1.Val) && !MayBeCrossIteration &&
isKnownNonEqual(Var0.Val.V, Var1.Val.V, DL, &AC, /* CxtI */ nullptr,
DT))
MinAbsVarIndex = Var0.Scale.abs();
@@ -1432,19 +1433,14 @@ AliasResult BasicAAResult::aliasPHI(const PHINode *PN, LocationSize PNSize,
PNSize = LocationSize::beforeOrAfterPointer();
// In the recursive alias queries below, we may compare values from two
- // different loop iterations. Keep track of visited phi blocks, which will
- // be used when determining value equivalence.
- bool BlockInserted = VisitedPhiBBs.insert(PN->getParent()).second;
- auto _ = make_scope_exit([&]() {
- if (BlockInserted)
- VisitedPhiBBs.erase(PN->getParent());
- });
-
- // If we inserted a block into VisitedPhiBBs, alias analysis results that
+ // different loop iterations.
+ SaveAndRestore<bool> SavedMayBeCrossIteration(MayBeCrossIteration, true);
+
+ // If we enabled the MayBeCrossIteration flag, alias analysis results that
// have been cached earlier may no longer be valid. Perform recursive queries
// with a new AAQueryInfo.
AAQueryInfo NewAAQI = AAQI.withEmptyCache();
- AAQueryInfo *UseAAQI = BlockInserted ? &NewAAQI : &AAQI;
+ AAQueryInfo *UseAAQI = !SavedMayBeCrossIteration.get() ? &NewAAQI : &AAQI;
AliasResult Alias = AAQI.AAR.alias(MemoryLocation(V1Srcs[0], PNSize),
MemoryLocation(V2, V2Size), *UseAAQI);
@@ -1690,34 +1686,29 @@ AliasResult BasicAAResult::aliasCheckRecursive(
/// Check whether two Values can be considered equivalent.
///
-/// In addition to pointer equivalence of \p V1 and \p V2 this checks whether
-/// they can not be part of a cycle in the value graph by looking at all
-/// visited phi nodes an making sure that the phis cannot reach the value. We
-/// have to do this because we are looking through phi nodes (That is we say
+/// If the values may come from different cycle iterations, this will also
+/// check that the values are not part of cycle. We have to do this because we
+/// are looking through phi nodes, that is we say
/// noalias(V, phi(VA, VB)) if noalias(V, VA) and noalias(V, VB).
bool BasicAAResult::isValueEqualInPotentialCycles(const Value *V,
const Value *V2) {
if (V != V2)
return false;
- const Instruction *Inst = dyn_cast<Instruction>(V);
- if (!Inst)
+ if (!MayBeCrossIteration)
return true;
- if (VisitedPhiBBs.empty())
+ // Non-instructions and instructions in the entry block cannot be part of
+ // a loop.
+ const Instruction *Inst = dyn_cast<Instruction>(V);
+ if (!Inst || Inst->getParent()->isEntryBlock())
return true;
- if (VisitedPhiBBs.size() > MaxNumPhiBBsValueReachabilityCheck)
- return false;
-
- // 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 (const auto *P : VisitedPhiBBs)
- if (isPotentiallyReachable(&P->front(), Inst, nullptr, DT))
- return false;
-
- return true;
+ // Check whether the instruction is part of a cycle, by checking whether the
+ // block can (non-trivially) reach itself.
+ BasicBlock *BB = const_cast<BasicBlock *>(Inst->getParent());
+ SmallVector<BasicBlock *> Succs(successors(BB));
+ return !isPotentiallyReachableFromMany(Succs, BB, nullptr, DT);
}
/// Computes the symbolic difference between two de-composed GEPs.