diff options
| author | Kuba Brecka <kuba.brecka@gmail.com> | 2015-07-22 10:25:38 +0000 | 
|---|---|---|
| committer | Kuba Brecka <kuba.brecka@gmail.com> | 2015-07-22 10:25:38 +0000 | 
| commit | 8ec94ead7d1cfa2afb907b465a5f9d960713e98f (patch) | |
| tree | c64fbbb7a36c2aac9fedf762d70abc6437655f2a /llvm | |
| parent | 96ada25bf3af06ff3ef27eaade066d84b2668263 (diff) | |
| download | bcm5719-llvm-8ec94ead7d1cfa2afb907b465a5f9d960713e98f.tar.gz bcm5719-llvm-8ec94ead7d1cfa2afb907b465a5f9d960713e98f.zip  | |
[asan] Improve moving of non-instrumented allocas
In r242510, non-instrumented allocas are now moved into the first basic block.  This patch limits that to only move allocas that are present *after* the first instrumented one (i.e. only move allocas up).  A testcase was updated to show behavior in these two cases.  Without the patch, an alloca could be moved down, and could cause an invalid IR.
Differential Revision: http://reviews.llvm.org/D11339
llvm-svn: 242883
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp | 18 | ||||
| -rw-r--r-- | llvm/test/Instrumentation/AddressSanitizer/debug_info_noninstrumented_alloca.ll | 25 | 
2 files changed, 31 insertions, 12 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index ed2de44e6ae..c7f3cfb8a48 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -18,6 +18,7 @@  #include "llvm/ADT/DenseMap.h"  #include "llvm/ADT/DenseSet.h"  #include "llvm/ADT/DepthFirstIterator.h" +#include "llvm/ADT/SetVector.h"  #include "llvm/ADT/SmallSet.h"  #include "llvm/ADT/SmallString.h"  #include "llvm/ADT/SmallVector.h" @@ -538,7 +539,7 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> {    ShadowMapping Mapping;    SmallVector<AllocaInst *, 16> AllocaVec; -  SmallVector<AllocaInst *, 16> NonInstrumentedStaticAllocaVec; +  SmallSetVector<AllocaInst *, 16> NonInstrumentedStaticAllocaVec;    SmallVector<Instruction *, 8> RetVec;    unsigned StackAlignment; @@ -641,7 +642,7 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> {    /// \brief Collect Alloca instructions we want (and can) handle.    void visitAllocaInst(AllocaInst &AI) {      if (!ASan.isInterestingAlloca(AI)) { -      if (AI.isStaticAlloca()) NonInstrumentedStaticAllocaVec.push_back(&AI); +      if (AI.isStaticAlloca()) NonInstrumentedStaticAllocaVec.insert(&AI);        return;      } @@ -1787,10 +1788,15 @@ void FunctionStackPoisoner::poisonStack() {    IRBuilder<> IRB(InsBefore);    IRB.SetCurrentDebugLocation(EntryDebugLocation); -  // Make sure non-instrumented allocas stay in the first basic block. -  // Otherwise, debug info is broken, because only first-basic-block allocas are -  // treated as regular stack slots. -  for (auto *AI : NonInstrumentedStaticAllocaVec) AI->moveBefore(InsBefore); +  // Make sure non-instrumented allocas stay in the entry block. Otherwise, +  // debug info is broken, because only entry-block allocas are treated as +  // regular stack slots. +  auto InsBeforeB = InsBefore->getParent(); +  assert(InsBeforeB == &F.getEntryBlock()); +  for (BasicBlock::iterator I = InsBefore; I != InsBeforeB->end(); ++I) +    if (auto *AI = dyn_cast_or_null<AllocaInst>(I)) +      if (NonInstrumentedStaticAllocaVec.count(AI) > 0) +        AI->moveBefore(InsBefore);    // If we have a call to llvm.localescape, keep it in the entry block.    if (LocalEscapeCall) LocalEscapeCall->moveBefore(InsBefore); diff --git a/llvm/test/Instrumentation/AddressSanitizer/debug_info_noninstrumented_alloca.ll b/llvm/test/Instrumentation/AddressSanitizer/debug_info_noninstrumented_alloca.ll index 7c38729ff43..844da79f708 100644 --- a/llvm/test/Instrumentation/AddressSanitizer/debug_info_noninstrumented_alloca.ll +++ b/llvm/test/Instrumentation/AddressSanitizer/debug_info_noninstrumented_alloca.ll @@ -9,18 +9,31 @@ target triple = "x86_64-apple-macosx10.10.0"  define i32 @foo() sanitize_address {  entry: +  ; Won't be instrumented because of asan-skip-promotable-allocas. +  %non_instrumented1 = alloca i32, align 4 +    ; Regular alloca, will get instrumented (forced by the ptrtoint below).    %instrumented = alloca i32, align 4    ; Won't be instrumented because of asan-skip-promotable-allocas. -  %non_instrumented = alloca i32, align 4 -  store i32 0, i32* %non_instrumented, align 4 -  %value = load i32, i32* %non_instrumented, align 4 +  %non_instrumented2 = alloca i32, align 4 + +  br label %bb0 + +bb0: +  ; Won't be instrumented because of asan-skip-promotable-allocas. +  %non_instrumented3 = alloca i32, align 4 + +  %ptr = ptrtoint i32* %instrumented to i32 +  br label %bb1 -  %ptr = ptrtoint i32* %instrumented to i64 -  ret i32 %value +bb1: +  ret i32 %ptr  }  ; CHECK: entry: -; CHECK: %non_instrumented = alloca i32, align 4 +; CHECK: %non_instrumented1 = alloca i32, align 4 +; CHECK: %non_instrumented2 = alloca i32, align 4  ; CHECK: load i32, i32* @__asan_option_detect_stack_use_after_return +; CHECK: bb0: +; CHECK: %non_instrumented3 = alloca i32, align 4  | 

