[llvm] r245067 - [sancov] Leave llvm.localescape in the entry block
Justin Bogner via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 14 10:04:37 PDT 2015
Reid Kleckner via llvm-commits <llvm-commits at lists.llvm.org> writes:
> Author: rnk
> Date: Fri Aug 14 11:45:42 2015
> New Revision: 245067
>
> URL: http://llvm.org/viewvc/llvm-project?rev=245067&view=rev
> Log:
> [sancov] Leave llvm.localescape in the entry block
>
> Summary: Similar to the change we applied to ASan. The same test case works.
>
> Reviewers: samsonov
>
> Subscribers: llvm-commits
>
> Differential Revision: http://reviews.llvm.org/D11961
>
> Added:
> llvm/trunk/test/Instrumentation/SanitizerCoverage/localescape.ll
> Modified:
> llvm/trunk/include/llvm/Transforms/Instrumentation.h
> llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp
> llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
>
> Modified: llvm/trunk/include/llvm/Transforms/Instrumentation.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Instrumentation.h?rev=245067&r1=245066&r2=245067&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Transforms/Instrumentation.h (original)
> +++ llvm/trunk/include/llvm/Transforms/Instrumentation.h Fri Aug 14 11:45:42 2015
> @@ -15,6 +15,7 @@
> #define LLVM_TRANSFORMS_INSTRUMENTATION_H
>
> #include "llvm/ADT/StringRef.h"
> +#include "llvm/IR/BasicBlock.h"
> #include <vector>
>
> #if defined(__GNUC__) && defined(__linux__) && !defined(ANDROID)
> @@ -33,6 +34,14 @@ inline void *getDFSanRetValTLSPtrForJIT(
>
> namespace llvm {
>
> +/// Instrumentation passes often insert conditional checks into entry blocks.
> +/// Call this function before splitting the entry block to move instructions
> +/// that must remain in the entry block up before the split point. Static
> +/// allocas and llvm.localescape calls, for example, must remain in the entry
> +/// block.
> +BasicBlock::iterator PrepareToSplitEntryBlock(BasicBlock &BB,
> + BasicBlock::iterator IP);
> +
> class ModulePass;
> class FunctionPass;
>
>
> Modified: llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp?rev=245067&r1=245066&r2=245067&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp (original)
> +++ llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp Fri Aug 14 11:45:42 2015
> @@ -12,12 +12,47 @@
> //
> //===----------------------------------------------------------------------===//
>
> -#include "llvm/InitializePasses.h"
> +#include "llvm/Transforms/Instrumentation.h"
> #include "llvm-c/Initialization.h"
> +#include "llvm/IR/IntrinsicInst.h"
> +#include "llvm/InitializePasses.h"
> #include "llvm/PassRegistry.h"
>
> using namespace llvm;
>
> +/// Moves I before IP. Returns new insert point.
> +static BasicBlock::iterator moveBeforeInsertPoint(BasicBlock::iterator I, BasicBlock::iterator IP) {
> + // If I is IP, move the insert point down.
> + if (I == IP)
> + return ++IP;
> + // Otherwise, move I before IP and return IP.
> + I->moveBefore(IP);
> + return IP;
> +}
> +
> +/// Instrumentation passes often insert conditional checks into entry blocks.
> +/// Call this function before splitting the entry block to move instructions
> +/// that must remain in the entry block up before the split point. Static
> +/// allocas and llvm.localescape calls, for example, must remain in the entry
> +/// block.
> +BasicBlock::iterator llvm::PrepareToSplitEntryBlock(BasicBlock &BB,
> + BasicBlock::iterator IP) {
> + assert(&BB.getParent()->getEntryBlock() == &BB);
> + for (auto I = IP, E = BB.end(); I != E; ++I) {
> + bool KeepInEntry = false;
> + if (auto *AI = dyn_cast<AllocaInst>(I)) {
> + if (AI->isStaticAlloca())
> + KeepInEntry = true;
> + } else if (auto *II = dyn_cast<IntrinsicInst>(I)) {
> + if (II->getIntrinsicID() == llvm::Intrinsic::localescape)
> + KeepInEntry = true;
> + }
> + if (KeepInEntry)
> + IP = moveBeforeInsertPoint(I, IP);
> + }
> + return IP;
> +}
> +
> /// initializeInstrumentation - Initialize all passes in the TransformUtils
> /// library.
> void llvm::initializeInstrumentation(PassRegistry &Registry) {
>
> Modified: llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp?rev=245067&r1=245066&r2=245067&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp (original)
> +++ llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp Fri Aug 14 11:45:42 2015
> @@ -438,20 +438,16 @@ void SanitizerCoverageModule::InjectCove
> if (isa<UnreachableInst>(BB.getTerminator()))
> return;
> BasicBlock::iterator IP = BB.getFirstInsertionPt(), BE = BB.end();
> - // Skip static allocas at the top of the entry block so they don't become
> - // dynamic when we split the block. If we used our optimized stack layout,
> - // then there will only be one alloca and it will come first.
> - for (; IP != BE; ++IP) {
> - AllocaInst *AI = dyn_cast<AllocaInst>(IP);
> - if (!AI || !AI->isStaticAlloca())
> - break;
> - }
This left BE unused, causing a warning for me. I've remove the
declaration of BE in r245072.
>
> bool IsEntryBB = &BB == &F.getEntryBlock();
> DebugLoc EntryLoc;
> if (IsEntryBB) {
> if (auto SP = getDISubprogram(&F))
> EntryLoc = DebugLoc::get(SP->getScopeLine(), 0, SP);
> + // Keep static allocas and llvm.localescape calls in the entry block. Even
> + // if we aren't splitting the block, it's nice for allocas to be before
> + // calls.
> + IP = PrepareToSplitEntryBlock(BB, IP);
> } else {
> EntryLoc = IP->getDebugLoc();
> }
>
> Added: llvm/trunk/test/Instrumentation/SanitizerCoverage/localescape.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/SanitizerCoverage/localescape.ll?rev=245067&view=auto
> ==============================================================================
> --- llvm/trunk/test/Instrumentation/SanitizerCoverage/localescape.ll (added)
> +++ llvm/trunk/test/Instrumentation/SanitizerCoverage/localescape.ll Fri Aug 14 11:45:42 2015
> @@ -0,0 +1,88 @@
> +; RUN: opt < %s -sancov -sanitizer-coverage-level=0 -S | FileCheck %s
> +; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -S | FileCheck %s
> +; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -S | FileCheck %s
> +; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -sanitizer-coverage-block-threshold=0 -S | FileCheck %s
> +
> +target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
> +target triple = "i686-pc-windows-msvc18.0.0"
> +
> +declare i32 @llvm.eh.typeid.for(i8*) #2
> +declare i8* @llvm.frameaddress(i32)
> +declare i8* @llvm.x86.seh.recoverfp(i8*, i8*)
> +declare i8* @llvm.localrecover(i8*, i8*, i32)
> +declare void @llvm.localescape(...) #1
> +
> +declare i32 @_except_handler3(...)
> +declare void @may_throw(i32* %r)
> +
> +define i32 @main() sanitize_address personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) {
> +entry:
> + %r = alloca i32, align 4
> + %__exception_code = alloca i32, align 4
> + call void (...) @llvm.localescape(i32* nonnull %__exception_code)
> + %0 = bitcast i32* %r to i8*
> + store i32 0, i32* %r, align 4
> + invoke void @may_throw(i32* nonnull %r) #4
> + to label %__try.cont unwind label %lpad
> +
> +lpad: ; preds = %entry
> + %1 = landingpad { i8*, i32 }
> + catch i8* bitcast (i32 ()* @"\01?filt$0 at 0@main@@" to i8*)
> + %2 = extractvalue { i8*, i32 } %1, 1
> + %3 = call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ()* @"\01?filt$0 at 0@main@@" to i8*)) #1
> + %matches = icmp eq i32 %2, %3
> + br i1 %matches, label %__except, label %eh.resume
> +
> +__except: ; preds = %lpad
> + store i32 1, i32* %r, align 4
> + br label %__try.cont
> +
> +__try.cont: ; preds = %entry, %__except
> + %4 = load i32, i32* %r, align 4
> + ret i32 %4
> +
> +eh.resume: ; preds = %lpad
> + resume { i8*, i32 } %1
> +}
> +
> +; Check that the alloca remains static and the localescape call remains in the
> +; entry block.
> +
> +; CHECK-LABEL: define i32 @main()
> +; CHECK-NOT: br {{.*}}label
> +; CHECK: %__exception_code = alloca i32, align 4
> +; CHECK-NOT: br {{.*}}label
> +; CHECK: call void (...) @llvm.localescape(i32* nonnull %__exception_code)
> +
> +; Function Attrs: nounwind
> +define internal i32 @"\01?filt$0 at 0@main@@"() #1 {
> +entry:
> + %0 = tail call i8* @llvm.frameaddress(i32 1)
> + %1 = tail call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 ()* @main to i8*), i8* %0)
> + %2 = tail call i8* @llvm.localrecover(i8* bitcast (i32 ()* @main to i8*), i8* %1, i32 0)
> + %__exception_code = bitcast i8* %2 to i32*
> + %3 = getelementptr inbounds i8, i8* %0, i32 -20
> + %4 = bitcast i8* %3 to { i32*, i8* }**
> + %5 = load { i32*, i8* }*, { i32*, i8* }** %4, align 4
> + %6 = getelementptr inbounds { i32*, i8* }, { i32*, i8* }* %5, i32 0, i32 0
> + %7 = load i32*, i32** %6, align 4
> + %8 = load i32, i32* %7, align 4
> + store i32 %8, i32* %__exception_code, align 4
> + ret i32 1
> +}
> +
> +; CHECK-LABEL: define internal i32 @"\01?filt$0 at 0@main@@"()
> +; CHECK: tail call i8* @llvm.localrecover(i8* bitcast (i32 ()* @main to i8*), i8* {{.*}}, i32 0)
> +
> +define void @ScaleFilterCols_SSSE3(i8* %dst_ptr, i8* %src_ptr, i32 %dst_width, i32 %x, i32 %dx) sanitize_address {
> +entry:
> + %dst_width.addr = alloca i32, align 4
> + store i32 %dst_width, i32* %dst_width.addr, align 4
> + %0 = call { i8*, i8*, i32, i32, i32 } asm sideeffect "", "=r,=r,={ax},=r,=r,=*rm,rm,rm,0,1,2,3,4,5,~{memory},~{cc},~{xmm0},~{xmm1},~{xmm2},~{xmm3},~{xmm4},~{xmm5},~{xmm6},~{dirflag},~{fpsr},~{flags}"(i32* nonnull %dst_width.addr, i32 %x, i32 %dx, i8* %dst_ptr, i8* %src_ptr, i32 0, i32 0, i32 0, i32 %dst_width)
> + ret void
> +}
> +
> +define void @ScaleColsUp2_SSE2() sanitize_address {
> +entry:
> + ret void
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list