diff --git a/llvm/include/llvm/Analysis/MemoryLocation.h b/llvm/include/llvm/Analysis/MemoryLocation.h index 3b188d763ef282..833fce1b172650 100644 --- a/llvm/include/llvm/Analysis/MemoryLocation.h +++ b/llvm/include/llvm/Analysis/MemoryLocation.h @@ -253,6 +253,8 @@ class MemoryLocation { static MemoryLocation getForDest(const MemIntrinsic *MI); static MemoryLocation getForDest(const AtomicMemIntrinsic *MI); static MemoryLocation getForDest(const AnyMemIntrinsic *MI); + static Optional getForDest(const CallBase *CI, + const TargetLibraryInfo &TLI); /// Return a location representing a particular argument of a call. static MemoryLocation getForArgument(const CallBase *Call, unsigned ArgIdx, diff --git a/llvm/lib/Analysis/MemoryLocation.cpp b/llvm/lib/Analysis/MemoryLocation.cpp index baf70565e9c419..1ff3a295ead087 100644 --- a/llvm/lib/Analysis/MemoryLocation.cpp +++ b/llvm/lib/Analysis/MemoryLocation.cpp @@ -128,6 +128,27 @@ MemoryLocation MemoryLocation::getForDest(const AnyMemIntrinsic *MI) { return MemoryLocation(MI->getRawDest(), Size, MI->getAAMetadata()); } +Optional +MemoryLocation::getForDest(const CallBase *CB, const TargetLibraryInfo &TLI) { + if (auto *MemInst = dyn_cast(CB)) + return getForDest(MemInst); + + LibFunc LF; + if (TLI.getLibFunc(*CB, LF) && TLI.has(LF)) { + switch (LF) { + case LibFunc_strncpy: + case LibFunc_strcpy: + case LibFunc_strcat: + case LibFunc_strncat: + return getForArgument(CB, 0, &TLI); + default: + break; + } + } + + return {}; +} + MemoryLocation MemoryLocation::getForArgument(const CallBase *Call, unsigned ArgIdx, const TargetLibraryInfo *TLI) { diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp index e0d3a6accadd24..497d327e25f05b 100644 --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -1026,32 +1026,12 @@ struct DSEState { if (!I->mayWriteToMemory()) return None; - if (auto *MTI = dyn_cast(I)) - return {MemoryLocation::getForDest(MTI)}; - if (auto *CB = dyn_cast(I)) { // If the functions may write to memory we do not know about, bail out. if (!CB->onlyAccessesArgMemory() && !CB->onlyAccessesInaccessibleMemOrArgMem()) return None; - LibFunc LF; - if (TLI.getLibFunc(*CB, LF) && TLI.has(LF)) { - switch (LF) { - case LibFunc_strncpy: - if (const auto *Len = dyn_cast(CB->getArgOperand(2))) - return MemoryLocation(CB->getArgOperand(0), - LocationSize::precise(Len->getZExtValue()), - CB->getAAMetadata()); - LLVM_FALLTHROUGH; - case LibFunc_strcpy: - case LibFunc_strcat: - case LibFunc_strncat: - return {MemoryLocation::getAfter(CB->getArgOperand(0))}; - default: - break; - } - } switch (CB->getIntrinsicID()) { case Intrinsic::init_trampoline: return {MemoryLocation::getAfter(CB->getArgOperand(0))}; @@ -1060,7 +1040,8 @@ struct DSEState { default: break; } - return None; + + return MemoryLocation::getForDest(CB, TLI); } return MemoryLocation::getOrNone(I);