Index: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp =================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ llvm/trunk/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 @@ ShadowMapping Mapping; SmallVector AllocaVec; - SmallVector NonInstrumentedStaticAllocaVec; + SmallSetVector NonInstrumentedStaticAllocaVec; SmallVector RetVec; unsigned StackAlignment; @@ -641,7 +642,7 @@ /// \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 @@ 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(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); Index: llvm/trunk/test/Instrumentation/AddressSanitizer/debug_info_noninstrumented_alloca.ll =================================================================== --- llvm/trunk/test/Instrumentation/AddressSanitizer/debug_info_noninstrumented_alloca.ll +++ llvm/trunk/test/Instrumentation/AddressSanitizer/debug_info_noninstrumented_alloca.ll @@ -9,18 +9,31 @@ 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