Index: include/llvm/Analysis/ValueTracking.h =================================================================== --- include/llvm/Analysis/ValueTracking.h +++ include/llvm/Analysis/ValueTracking.h @@ -271,13 +271,16 @@ /// 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); - static 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); + static inline + const Value *GetUnderlyingObject(const Value *V, + const DataLayout &DL, unsigned MaxLookup = 6, + SmallVectorImpl *NoAlias = nullptr) { + return GetUnderlyingObject(const_cast(V), DL, MaxLookup, NoAlias); } /// \brief This method is similar to GetUnderlyingObject except that it can @@ -307,10 +310,13 @@ /// /// 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(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: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -3158,7 +3158,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) { @@ -3175,11 +3176,15 @@ // An alloca can't be further simplified. return V; } else { - if (auto CS = CallSite(V)) + if (auto CS = CallSite(V)) { + if (NoAlias && CS.getIntrinsicID() == Intrinsic::noalias) + NoAlias->push_back(CS.getInstruction()); + if (Value *RV = CS.getReturnedArgOperand()) { V = RV; continue; } + } // See if InstructionSimplify knows any relevant tricks. if (Instruction *I = dyn_cast(V)) @@ -3198,13 +3203,14 @@ void llvm::GetUnderlyingObjects(Value *V, SmallVectorImpl &Objects, const DataLayout &DL, LoopInfo *LI, - unsigned MaxLookup) { + unsigned MaxLookup, + SmallVectorImpl *NoAlias) { SmallPtrSet Visited; SmallVector Worklist; Worklist.push_back(V); do { Value *P = Worklist.pop_back_val(); - P = GetUnderlyingObject(P, DL, MaxLookup); + P = GetUnderlyingObject(P, DL, MaxLookup, NoAlias); if (!Visited.insert(P).second) continue;