diff --git a/llvm/include/llvm/Analysis/AliasAnalysis.h b/llvm/include/llvm/Analysis/AliasAnalysis.h --- a/llvm/include/llvm/Analysis/AliasAnalysis.h +++ b/llvm/include/llvm/Analysis/AliasAnalysis.h @@ -63,6 +63,7 @@ class PreservedAnalyses; class TargetLibraryInfo; class Value; +template class SmallPtrSetImpl; /// The possible results of an alias query. /// @@ -412,8 +413,12 @@ /// This is used for cache invalidation purposes. DenseMap> Inst2Obj; + const SmallPtrSetImpl &EphValues; + public: - EarliestEscapeInfo(DominatorTree &DT, const LoopInfo &LI) : DT(DT), LI(LI) {} + EarliestEscapeInfo(DominatorTree &DT, const LoopInfo &LI, + const SmallPtrSetImpl &EphValues) + : DT(DT), LI(LI), EphValues(EphValues) {} bool isNotCapturedBeforeOrAt(const Value *Object, const Instruction *I) override; diff --git a/llvm/include/llvm/Analysis/CaptureTracking.h b/llvm/include/llvm/Analysis/CaptureTracking.h --- a/llvm/include/llvm/Analysis/CaptureTracking.h +++ b/llvm/include/llvm/Analysis/CaptureTracking.h @@ -80,10 +80,11 @@ // nullptr is returned. Note that the caller of the function has to ensure // that the instruction the result value is compared against is not in a // cycle. - Instruction *FindEarliestCapture(const Value *V, Function &F, - bool ReturnCaptures, bool StoreCaptures, - const DominatorTree &DT, - unsigned MaxUsesToExplore = 0); + Instruction * + FindEarliestCapture(const Value *V, Function &F, bool ReturnCaptures, + bool StoreCaptures, const DominatorTree &DT, + const SmallPtrSetImpl &EphValues, + unsigned MaxUsesToExplore = 0); /// This callback is used in conjunction with PointerMayBeCaptured. In /// addition to the interface here, you'll need to provide your own getters diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -232,7 +232,7 @@ if (Iter.second) { Instruction *EarliestCapture = FindEarliestCapture( Object, *const_cast(I->getFunction()), - /*ReturnCaptures=*/false, /*StoreCaptures=*/true, DT); + /*ReturnCaptures=*/false, /*StoreCaptures=*/true, DT, EphValues); if (EarliestCapture) { auto Ins = Inst2Obj.insert({EarliestCapture, {}}); Ins.first->second.push_back(Object); diff --git a/llvm/lib/Analysis/CaptureTracking.cpp b/llvm/lib/Analysis/CaptureTracking.cpp --- a/llvm/lib/Analysis/CaptureTracking.cpp +++ b/llvm/lib/Analysis/CaptureTracking.cpp @@ -162,8 +162,9 @@ // escape are not in a cycle. struct EarliestCaptures : public CaptureTracker { - EarliestCaptures(bool ReturnCaptures, Function &F, const DominatorTree &DT) - : DT(DT), ReturnCaptures(ReturnCaptures), F(F) {} + EarliestCaptures(bool ReturnCaptures, Function &F, const DominatorTree &DT, + const SmallPtrSetImpl &EphValues) + : EphValues(EphValues), DT(DT), ReturnCaptures(ReturnCaptures), F(F) {} void tooManyUses() override { Captured = true; @@ -175,6 +176,9 @@ if (isa(I) && !ReturnCaptures) return false; + if (EphValues.contains(I)) + return false; + if (!EarliestCapture) { EarliestCapture = I; } else if (EarliestCapture->getParent() == I->getParent()) { @@ -201,6 +205,8 @@ return false; } + const SmallPtrSetImpl &EphValues; + Instruction *EarliestCapture = nullptr; const DominatorTree &DT; @@ -284,14 +290,16 @@ return CB.Captured; } -Instruction *llvm::FindEarliestCapture(const Value *V, Function &F, - bool ReturnCaptures, bool StoreCaptures, - const DominatorTree &DT, - unsigned MaxUsesToExplore) { +Instruction * +llvm::FindEarliestCapture(const Value *V, Function &F, bool ReturnCaptures, + bool StoreCaptures, const DominatorTree &DT, + + const SmallPtrSetImpl &EphValues, + unsigned MaxUsesToExplore) { assert(!isa(V) && "It doesn't make sense to ask whether a global is captured."); - EarliestCaptures CB(ReturnCaptures, F, DT); + EarliestCaptures CB(ReturnCaptures, F, DT, EphValues); PointerMayBeCaptured(V, &CB, MaxUsesToExplore); if (CB.Captured) ++NumCapturedBefore; diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -783,8 +783,8 @@ DSEState(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, DominatorTree &DT, PostDominatorTree &PDT, AssumptionCache &AC, const TargetLibraryInfo &TLI, const LoopInfo &LI) - : F(F), AA(AA), EI(DT, LI), BatchAA(AA, &EI), MSSA(MSSA), DT(DT), - PDT(PDT), TLI(TLI), DL(F.getParent()->getDataLayout()), LI(LI) { + : F(F), AA(AA), EI(DT, LI, EphValues), BatchAA(AA, &EI), MSSA(MSSA), + DT(DT), PDT(PDT), TLI(TLI), DL(F.getParent()->getDataLayout()), LI(LI) { // Collect blocks with throwing instructions not modeled in MemorySSA and // alloc-like objects. unsigned PO = 0; diff --git a/llvm/test/Transforms/DeadStoreElimination/assume.ll b/llvm/test/Transforms/DeadStoreElimination/assume.ll --- a/llvm/test/Transforms/DeadStoreElimination/assume.ll +++ b/llvm/test/Transforms/DeadStoreElimination/assume.ll @@ -22,7 +22,6 @@ ; CHECK-NEXT: [[TMP1:%.*]] = call noalias i8* @_Znwm(i64 32) ; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i8* [[TMP1]], @global ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP2]]) -; CHECK-NEXT: store i8 0, i8* [[TMP1]], align 1 ; CHECK-NEXT: call void @quux(i8* @global) ; CHECK-NEXT: ret void ;