diff --git a/llvm/lib/Analysis/StackSafetyAnalysis.cpp b/llvm/lib/Analysis/StackSafetyAnalysis.cpp --- a/llvm/lib/Analysis/StackSafetyAnalysis.cpp +++ b/llvm/lib/Analysis/StackSafetyAnalysis.cpp @@ -59,6 +59,9 @@ STATISTIC(NumIndexCalleeMultipleExternal, "Number of index callee non-unique external."); +static cl::opt StackSafetyMaxAllocas("stack-safety-max-allocas", + cl::init(250), cl::Hidden); + static cl::opt StackSafetyMaxIterations("stack-safety-max-iterations", cl::init(20), cl::Hidden); @@ -527,8 +530,15 @@ SmallVector Allocas; for (auto &I : instructions(F)) - if (auto *AI = dyn_cast(&I)) + if (auto *AI = dyn_cast(&I)) { Allocas.push_back(AI); + // Skip stack safety analysis if there are too many allocas. + if (Allocas.size() > StackSafetyMaxAllocas) { + LLVM_DEBUG(dbgs() << "\n[StackSafety] skipped\n"); + return Info; + } + } + StackLifetime SL(F, Allocas, StackLifetime::LivenessType::Must); SL.run(); diff --git a/llvm/test/Analysis/StackSafetyAnalysis/stack-safety-max-allocas.ll b/llvm/test/Analysis/StackSafetyAnalysis/stack-safety-max-allocas.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Analysis/StackSafetyAnalysis/stack-safety-max-allocas.ll @@ -0,0 +1,13 @@ +; REQUIRES: x86-registered-target + +; RUN: opt < %s -S -asan-instrumentation-with-call-threshold=0 -passes='asan-pipeline' -asan-use-stack-safety=1 \ +; RUN: -stack-safety-max-allocas=0 -o - | FileCheck %s --check-prefixes=ALLOCAS + +; ALLOCAS-LABEL: define i32 @f +define i32 @f() sanitize_address { + %buf = alloca [10 x i8], align 1 + ; ALLOCAS: call i64 @__asan_stack_malloc + %arrayidx = getelementptr inbounds [10 x i8], [10 x i8]* %buf, i64 0, i64 0 + %1 = load i8, i8* %arrayidx, align 1 + ret i32 0 +}