diff --git a/llvm/include/llvm/Analysis/Loads.h b/llvm/include/llvm/Analysis/Loads.h --- a/llvm/include/llvm/Analysis/Loads.h +++ b/llvm/include/llvm/Analysis/Loads.h @@ -155,6 +155,14 @@ BasicBlock::iterator &ScanFrom, unsigned MaxInstsToScan, AAResults *AA, bool *IsLoadCSE, unsigned *NumScanedInst); + +/// Returns true if a pointer value \p A can be replace with another pointer +/// value \B if they are deemed equal through some means (e.g. information from +/// conditions). Note that the current implementations is incomplete and +/// unsound. It does not reject all invalid cases yet and will be made stricter +/// in the future. +bool canReplacePointersIfEqual(Value *A, Value *B, const DataLayout &DL, + Instruction *CtxI); } #endif diff --git a/llvm/lib/Analysis/Loads.cpp b/llvm/lib/Analysis/Loads.cpp --- a/llvm/lib/Analysis/Loads.cpp +++ b/llvm/lib/Analysis/Loads.cpp @@ -512,3 +512,17 @@ // block. return nullptr; } + +bool llvm::canReplacePointersIfEqual(Value *A, Value *B, const DataLayout &DL, + Instruction *CtxI) { + Type *Ty = A->getType(); + assert(Ty == B->getType() && Ty->isPointerTy() && + "values must have matching pointer types"); + + if (auto *C = dyn_cast(B)) { + return C->isNullValue() || + isDereferenceablePointer(B, Ty->getPointerElementType(), DL, CtxI); + } + + return true; +}