aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/AliasAnalysis.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/AliasAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/AliasAnalysis.cpp48
1 files changed, 25 insertions, 23 deletions
diff --git a/llvm/lib/Analysis/AliasAnalysis.cpp b/llvm/lib/Analysis/AliasAnalysis.cpp
index 85d17d0..2a2b49f 100644
--- a/llvm/lib/Analysis/AliasAnalysis.cpp
+++ b/llvm/lib/Analysis/AliasAnalysis.cpp
@@ -235,35 +235,37 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call,
// Try to refine the mod-ref info further using other API entry points to the
// aggregate set of AA results.
- auto MRB = getModRefBehavior(Call);
- if (MRB.onlyAccessesInaccessibleMem())
- return ModRefInfo::NoModRef;
- // TODO: Exclude inaccessible memory location here.
- Result &= MRB.getModRef();
+ // We can completely ignore inaccessible memory here, because MemoryLocations
+ // can only reference accessible memory.
+ auto MRB = getModRefBehavior(Call).getWithoutLoc(
+ FunctionModRefBehavior::InaccessibleMem);
+ if (MRB.doesNotAccessMemory())
+ return ModRefInfo::NoModRef;
- if (MRB.onlyAccessesArgPointees() || MRB.onlyAccessesInaccessibleOrArgMem()) {
+ ModRefInfo ArgMR = MRB.getModRef(FunctionModRefBehavior::ArgMem);
+ ModRefInfo OtherMR =
+ MRB.getWithoutLoc(FunctionModRefBehavior::ArgMem).getModRef();
+ if ((ArgMR | OtherMR) != OtherMR) {
+ // Refine the modref info for argument memory. We only bother to do this
+ // if ArgMR is not a subset of OtherMR, otherwise this won't have an impact
+ // on the final result.
ModRefInfo AllArgsMask = ModRefInfo::NoModRef;
- if (MRB.doesAccessArgPointees()) {
- for (const auto &I : llvm::enumerate(Call->args())) {
- const Value *Arg = I.value();
- if (!Arg->getType()->isPointerTy())
- continue;
- unsigned ArgIdx = I.index();
- MemoryLocation ArgLoc =
- MemoryLocation::getForArgument(Call, ArgIdx, TLI);
- AliasResult ArgAlias = alias(ArgLoc, Loc, AAQI);
- if (ArgAlias != AliasResult::NoAlias)
- AllArgsMask |= getArgModRefInfo(Call, ArgIdx);
- }
+ for (const auto &I : llvm::enumerate(Call->args())) {
+ const Value *Arg = I.value();
+ if (!Arg->getType()->isPointerTy())
+ continue;
+ unsigned ArgIdx = I.index();
+ MemoryLocation ArgLoc = MemoryLocation::getForArgument(Call, ArgIdx, TLI);
+ AliasResult ArgAlias = alias(ArgLoc, Loc, AAQI);
+ if (ArgAlias != AliasResult::NoAlias)
+ AllArgsMask |= getArgModRefInfo(Call, ArgIdx);
}
- // Return NoModRef if no alias found with any argument.
- if (isNoModRef(AllArgsMask))
- return ModRefInfo::NoModRef;
- // Logical & between other AA analyses and argument analysis.
- Result &= AllArgsMask;
+ ArgMR &= AllArgsMask;
}
+ Result &= ArgMR | OtherMR;
+
// If Loc is a constant memory location, the call definitely could not
// modify the memory location.
if (isModSet(Result) && pointsToConstantMemory(Loc, AAQI, /*OrLocal*/ false))