diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h --- a/llvm/include/llvm/Analysis/ValueTracking.h +++ b/llvm/include/llvm/Analysis/ValueTracking.h @@ -646,9 +646,12 @@ /// 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. -const Value *getUnderlyingObject(const Value *V, unsigned MaxLookup = 6); -inline Value *getUnderlyingObject(Value *V, unsigned MaxLookup = 6) { +/// be stripped off. This will look through llvm.ptrmask unless +/// AllowBitManipulation is false. +const Value *getUnderlyingObject(const Value *V, unsigned MaxLookup = 6, + bool AllowBitManipulation = true); +inline Value *getUnderlyingObject(Value *V, unsigned MaxLookup = 6, + bool AllowBitManipulation = true) { // Force const to avoid infinite recursion. const Value *VConst = V; return const_cast(getUnderlyingObject(VConst, MaxLookup)); @@ -682,9 +685,11 @@ /// 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. +/// void getUnderlyingObjects(const Value *V, SmallVectorImpl &Objects, - LoopInfo *LI = nullptr, unsigned MaxLookup = 6); + LoopInfo *LI = nullptr, unsigned MaxLookup = 6, + bool AllowBitManipulation = true); /// This is a wrapper around getUnderlyingObjects and adds support for basic /// ptrtoint+arithmetic+inttoptr sequences. diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -5712,7 +5712,8 @@ return true; } -const Value *llvm::getUnderlyingObject(const Value *V, unsigned MaxLookup) { +const Value *llvm::getUnderlyingObject(const Value *V, unsigned MaxLookup, + bool AllowBitManipulation) { if (!V->getType()->isPointerTy()) return V; for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) { @@ -5743,8 +5744,11 @@ // be marked with returns attribute), it is crucial to use this function // because it should be in sync with CaptureTracking. Not using it may // cause weird miscompilations where 2 aliasing pointers are assumed to - // noalias. - if (auto *RP = getArgumentAliasingToReturnedPointer(Call, false)) { + // noalias. If bit manipulation is forbidden, then intrinsics that do + // not preserve the null pointer, namely ptrmask, count as a new + // underlying object. + if (auto *RP = getArgumentAliasingToReturnedPointer( + Call, !AllowBitManipulation)) { V = RP; continue; } @@ -5759,13 +5763,14 @@ void llvm::getUnderlyingObjects(const Value *V, SmallVectorImpl &Objects, - LoopInfo *LI, unsigned MaxLookup) { + LoopInfo *LI, unsigned MaxLookup, + bool AllowBitManipulation) { SmallPtrSet Visited; SmallVector Worklist; Worklist.push_back(V); do { const Value *P = Worklist.pop_back_val(); - P = getUnderlyingObject(P, MaxLookup); + P = getUnderlyingObject(P, MaxLookup, AllowBitManipulation); if (!Visited.insert(P).second) continue;