aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/AliasAnalysis.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2022-09-01 16:51:00 +0200
committerNikita Popov <npopov@redhat.com>2022-09-22 11:15:20 +0200
commitab25ea6d357e0446bc53cbc6a7372fc79f24740d (patch)
treeba89fb5749099348377421cb8ff1cda5861e33f8 /llvm/lib/Analysis/AliasAnalysis.cpp
parentcc61c822e05c51e494c50d1e72f963750116ef08 (diff)
downloadllvm-ab25ea6d357e0446bc53cbc6a7372fc79f24740d.zip
llvm-ab25ea6d357e0446bc53cbc6a7372fc79f24740d.tar.gz
llvm-ab25ea6d357e0446bc53cbc6a7372fc79f24740d.tar.bz2
[AA] Model operand bundles more precisely
Based on D130896, we can model operand bundles more precisely. In addition to the baseline ModRefBehavior, a reading/clobbering operand bundle may also read/write all locations. For example, a memcpy with deopt bundle can read any memory, but only write argument memory. This means that getModRefInfo() for memcpy with a pointer that does not alias the arguments results in Ref, rather than ModRef, without the need to implement any special handling. Differential Revision: https://reviews.llvm.org/D130980
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))