From 8ec94ead7d1cfa2afb907b465a5f9d960713e98f Mon Sep 17 00:00:00 2001 From: Kuba Brecka Date: Wed, 22 Jul 2015 10:25:38 +0000 Subject: [PATCH] [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 --- .../Instrumentation/AddressSanitizer.cpp | 18 ++++++++++------ .../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 ed2de44..c7f3cfb 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 { ShadowMapping Mapping; SmallVector AllocaVec; - SmallVector NonInstrumentedStaticAllocaVec; + SmallSetVector NonInstrumentedStaticAllocaVec; SmallVector RetVec; unsigned StackAlignment; @@ -641,7 +642,7 @@ struct FunctionStackPoisoner : public InstVisitor { /// \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(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 7c38729f..844da79 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 -- 2.7.4