Index: llvm/include/llvm/Analysis/ValueTracking.h =================================================================== --- llvm/include/llvm/Analysis/ValueTracking.h +++ llvm/include/llvm/Analysis/ValueTracking.h @@ -334,12 +334,15 @@ /// the specified value, returning the original object being addressed. Note /// that the returned value has pointer type if the specified value does. If /// the MaxLookup value is non-zero, it limits the number of instructions to - /// be stripped off. + /// be stripped off. If a NoAlias vector is provided, it is filled with any + /// llvm.noalias intrinsics looked through to find the underlying object. Value *GetUnderlyingObject(Value *V, const DataLayout &DL, - unsigned MaxLookup = 6); - inline const Value *GetUnderlyingObject(const Value *V, const DataLayout &DL, - unsigned MaxLookup = 6) { - return GetUnderlyingObject(const_cast(V), DL, MaxLookup); + unsigned MaxLookup = 6, + SmallVectorImpl *NoAlias = nullptr); + inline const Value *GetUnderlyingObject(const Value *V, + const DataLayout &DL, unsigned MaxLookup = 6, + SmallVectorImpl *NoAlias = nullptr) { + return GetUnderlyingObject(const_cast(V), DL, MaxLookup, NoAlias); } /// This method is similar to GetUnderlyingObject except that it can @@ -369,11 +372,14 @@ /// /// Since A[i] and A[i-1] are independent pointers, getUnderlyingObjects /// should not assume that Curr and Prev share the same underlying object thus - /// it shouldn't look through the phi above. + /// it shouldn't look through the phi above. If a NoAlias vector is provided, + /// it is filled with any llvm.noalias intrinsics looked through to find the + /// underlying objects. void GetUnderlyingObjects(const Value *V, SmallVectorImpl &Objects, const DataLayout &DL, LoopInfo *LI = nullptr, - unsigned MaxLookup = 6); + unsigned MaxLookup = 6, + SmallVectorImpl *NoAlias = nullptr); /// This is a wrapper around GetUnderlyingObjects and adds support for basic /// ptrtoint+arithmetic+inttoptr sequences. Index: llvm/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/lib/Analysis/ValueTracking.cpp +++ llvm/lib/Analysis/ValueTracking.cpp @@ -3713,7 +3713,8 @@ } Value *llvm::GetUnderlyingObject(Value *V, const DataLayout &DL, - unsigned MaxLookup) { + unsigned MaxLookup, + SmallVectorImpl *NoAlias) { if (!V->getType()->isPointerTy()) return V; for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) { @@ -3731,6 +3732,9 @@ return V; } else { if (auto *Call = dyn_cast(V)) { + if (NoAlias && Call->getIntrinsicID() == Intrinsic::noalias) + NoAlias->push_back(Call); + // CaptureTracking can know about special capturing properties of some // intrinsics like launder.invariant.group, that can't be expressed with // the attributes, but have properties like returning aliasing pointer. @@ -3764,13 +3768,14 @@ void llvm::GetUnderlyingObjects(const Value *V, SmallVectorImpl &Objects, const DataLayout &DL, LoopInfo *LI, - unsigned MaxLookup) { + unsigned MaxLookup, + SmallVectorImpl *NoAlias) { SmallPtrSet Visited; SmallVector Worklist; Worklist.push_back(V); do { const Value *P = Worklist.pop_back_val(); - P = GetUnderlyingObject(P, DL, MaxLookup); + P = GetUnderlyingObject(P, DL, MaxLookup, NoAlias); if (!Visited.insert(P).second) continue;