diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp index faa936e63c91..a757db100984 100644 --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -2045,29 +2045,28 @@ struct DSEState { !isRemovable(Def->getMemoryInst())) continue; - // TODO: Consider doing the underlying object check first, if it is - // beneficial compile-time wise. - if (isWriteAtEndOfFunction(Def)) { - Instruction *DefI = Def->getMemoryInst(); - // See through pointer-to-pointer bitcasts - SmallVector Pointers; - getUnderlyingObjects(getLocForWriteEx(DefI)->Ptr, Pointers); + Instruction *DefI = Def->getMemoryInst(); + SmallVector Pointers; + auto DefLoc = getLocForWriteEx(DefI); + if (!DefLoc) + continue; + getUnderlyingObjects(DefLoc->Ptr, Pointers); + bool CanKill = true; + for (const Value *Pointer : Pointers) { + if (!InvisibleToCallerAfterRet.count(Pointer)) { + CanKill = false; + break; + } + } + + if (CanKill && isWriteAtEndOfFunction(Def)) { + // See through pointer-to-pointer bitcasts LLVM_DEBUG(dbgs() << " ... MemoryDef is not accessed until the end " "of the function\n"); - bool CanKill = true; - for (const Value *Pointer : Pointers) { - if (!InvisibleToCallerAfterRet.count(Pointer)) { - CanKill = false; - break; - } - } - - if (CanKill) { - deleteDeadInstruction(DefI); - ++NumFastStores; - MadeChange = true; - } + deleteDeadInstruction(DefI); + ++NumFastStores; + MadeChange = true; } } return MadeChange;