summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/AliasSetTracker.cpp40
-rw-r--r--llvm/lib/Analysis/MemoryLocation.cpp7
2 files changed, 44 insertions, 3 deletions
diff --git a/llvm/lib/Analysis/AliasSetTracker.cpp b/llvm/lib/Analysis/AliasSetTracker.cpp
index 45d1b0d3e1c..d0997932260 100644
--- a/llvm/lib/Analysis/AliasSetTracker.cpp
+++ b/llvm/lib/Analysis/AliasSetTracker.cpp
@@ -452,6 +452,46 @@ void AliasSetTracker::add(Instruction *I) {
return add(MSI);
if (AnyMemTransferInst *MTI = dyn_cast<AnyMemTransferInst>(I))
return add(MTI);
+
+ // Handle all calls with known mod/ref sets genericall
+ CallSite CS(I);
+ if (CS && CS.onlyAccessesArgMemory()) {
+ auto getAccessFromModRef = [](ModRefInfo MRI) {
+ if (isRefSet(MRI) && isModSet(MRI))
+ return AliasSet::ModRefAccess;
+ else if (isModSet(MRI))
+ return AliasSet::ModAccess;
+ else if (isRefSet(MRI))
+ return AliasSet::RefAccess;
+ else
+ return AliasSet::NoAccess;
+
+ };
+
+ ModRefInfo CallMask = createModRefInfo(AA.getModRefBehavior(CS));
+
+ // Some intrinsics are marked as modifying memory for control flow
+ // modelling purposes, but don't actually modify any specific memory
+ // location.
+ using namespace PatternMatch;
+ if (I->use_empty() && match(I, m_Intrinsic<Intrinsic::invariant_start>()))
+ CallMask = clearMod(CallMask);
+
+ for (auto AI = CS.arg_begin(), AE = CS.arg_end(); AI != AE; ++AI) {
+ const Value *Arg = *AI;
+ if (!Arg->getType()->isPointerTy())
+ continue;
+ unsigned ArgIdx = std::distance(CS.arg_begin(), AI);
+ MemoryLocation ArgLoc = MemoryLocation::getForArgument(CS, ArgIdx,
+ nullptr);
+ ModRefInfo ArgMask = AA.getArgModRefInfo(CS, ArgIdx);
+ ArgMask = intersectModRef(CallMask, ArgMask);
+ if (!isNoModRef(ArgMask))
+ addPointer(ArgLoc, getAccessFromModRef(ArgMask));
+ }
+ return;
+ }
+
return addUnknown(I);
}
diff --git a/llvm/lib/Analysis/MemoryLocation.cpp b/llvm/lib/Analysis/MemoryLocation.cpp
index 43cebcd7a30..326944f2964 100644
--- a/llvm/lib/Analysis/MemoryLocation.cpp
+++ b/llvm/lib/Analysis/MemoryLocation.cpp
@@ -108,7 +108,7 @@ MemoryLocation MemoryLocation::getForDest(const AnyMemIntrinsic *MI) {
MemoryLocation MemoryLocation::getForArgument(ImmutableCallSite CS,
unsigned ArgIdx,
- const TargetLibraryInfo &TLI) {
+ const TargetLibraryInfo *TLI) {
AAMDNodes AATags;
CS->getAAMetadata(AATags);
const Value *Arg = CS.getArgument(ArgIdx);
@@ -163,8 +163,9 @@ MemoryLocation MemoryLocation::getForArgument(ImmutableCallSite CS,
// LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16
// whenever possible.
LibFunc F;
- if (CS.getCalledFunction() && TLI.getLibFunc(*CS.getCalledFunction(), F) &&
- F == LibFunc_memset_pattern16 && TLI.has(F)) {
+ if (TLI && CS.getCalledFunction() &&
+ TLI->getLibFunc(*CS.getCalledFunction(), F) &&
+ F == LibFunc_memset_pattern16 && TLI->has(F)) {
assert((ArgIdx == 0 || ArgIdx == 1) &&
"Invalid argument index for memset_pattern16");
if (ArgIdx == 1)
OpenPOWER on IntegriCloud