diff --git a/lib/Analysis/StackSafetyAnalysis.cpp b/lib/Analysis/StackSafetyAnalysis.cpp index 28d39b3ea3a..88aa5ce065a 100644 --- a/lib/Analysis/StackSafetyAnalysis.cpp +++ b/lib/Analysis/StackSafetyAnalysis.cpp @@ -11,9 +11,11 @@ #include "llvm/Analysis/StackSafetyAnalysis.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/ModuleSummaryAnalysis.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" +#include "llvm/Analysis/StackLifetime.h" #include "llvm/IR/ConstantRange.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/GlobalValue.h" @@ -205,7 +207,8 @@ class StackSafetyLocalAnalysis { ConstantRange getMemIntrinsicAccessRange(const MemIntrinsic *MI, const Use &U, Value *Base); - bool analyzeAllUses(Value *Ptr, UseInfo &AS); + bool analyzeAllUses(Value *Ptr, UseInfo &AS, + const StackLifetime &SL); public: StackSafetyLocalAnalysis(Function &F, ScalarEvolution &SE) @@ -289,7 +292,8 @@ ConstantRange StackSafetyLocalAnalysis::getMemIntrinsicAccessRange( /// The function analyzes all local uses of Ptr (alloca or argument) and /// calculates local access range and all function calls where it was used. bool StackSafetyLocalAnalysis::analyzeAllUses(Value *Ptr, - UseInfo &US) { + UseInfo &US, + const StackLifetime &SL) { SmallPtrSet Visited; SmallVector WorkList; WorkList.push_back(Ptr); @@ -298,7 +302,10 @@ bool StackSafetyLocalAnalysis::analyzeAllUses(Value *Ptr, while (!WorkList.empty()) { const Value *V = WorkList.pop_back_val(); for (const Use &UI : V->uses()) { - const auto *I = cast(UI.getUser()); + const auto *I = cast(UI.getUser()); + if (!SL.isReachable(I)) + continue; + assert(V == UI.get()); switch (I->getOpcode()) { @@ -384,11 +391,16 @@ FunctionInfo StackSafetyLocalAnalysis::run() { LLVM_DEBUG(dbgs() << "[StackSafety] " << F.getName() << "\n"); - for (auto &I : instructions(F)) { - if (auto *AI = dyn_cast(&I)) { - auto &UI = Info.Allocas.emplace(AI, PointerSize).first->second; - analyzeAllUses(AI, UI); - } + SmallVector Allocas; + for (auto &I : instructions(F)) + if (auto *AI = dyn_cast(&I)) + Allocas.push_back(AI); + StackLifetime SL(F, Allocas, StackLifetime::LivenessType::Must); + SL.run(); + + for (auto *AI : Allocas) { + auto &UI = Info.Allocas.emplace(AI, PointerSize).first->second; + analyzeAllUses(AI, UI, SL); } for (Argument &A : make_range(F.arg_begin(), F.arg_end())) { @@ -396,7 +408,7 @@ FunctionInfo StackSafetyLocalAnalysis::run() { // processing. if (A.getType()->isPointerTy() && !A.hasByValAttr()) { auto &UI = Info.Params.emplace(A.getArgNo(), PointerSize).first->second; - analyzeAllUses(&A, UI); + analyzeAllUses(&A, UI, SL); } } diff --git a/test/Analysis/StackSafetyAnalysis/local.ll b/test/Analysis/StackSafetyAnalysis/local.ll index e0f450a975a..ad4745c7bef 100644 --- a/test/Analysis/StackSafetyAnalysis/local.ll +++ b/test/Analysis/StackSafetyAnalysis/local.ll @@ -484,4 +484,24 @@ entry: %x2 = getelementptr i8, i8* %x, i64 -9223372036854775808 %v = call i8 @LoadMinInt64(i8* %x2) ret void +} + +define void @DeadBlock(i64* %p) { +; CHECK-LABEL: @DeadBlock dso_preemptable{{$}} +; CHECK-NEXT: args uses: +; CHECK-NEXT: p[]: empty-set{{$}} +; CHECK-NEXT: allocas uses: +; CHECK: x[1]: empty-set{{$}} +; CHECK-NOT: ]: +entry: + %x = alloca i8, align 4 + br label %end + +dead: + store i8 5, i8* %x + store i64 -5, i64* %p + br label %end + +end: + ret void } \ No newline at end of file