diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Analysis/AliasSetTracker.cpp | 40 | ||||
| -rw-r--r-- | llvm/lib/Analysis/MemoryLocation.cpp | 7 | 
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)  | 

