[llvm] r318235 - [asan] Prevent rematerialization of &__asan_shadow.
Evgeniy Stepanov via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 14 16:11:51 PST 2017
Author: eugenis
Date: Tue Nov 14 16:11:51 2017
New Revision: 318235
URL: http://llvm.org/viewvc/llvm-project?rev=318235&view=rev
Log:
[asan] Prevent rematerialization of &__asan_shadow.
Summary:
In the mode when ASan shadow base is computed as the address of an
external global (__asan_shadow, currently on android/arm32 only),
regalloc prefers to rematerialize this value to save register spills.
Even in -Os. On arm32 it is rather expensive (2 loads + 1 constant
pool entry).
This changes adds an inline asm in the function prologue to suppress
this behavior. It reduces AsanTest binary size by 7%.
Reviewers: pcc, vitalybuka
Subscribers: aemerson, kristof.beyls, hiraditya, llvm-commits
Differential Revision: https://reviews.llvm.org/D40048
Modified:
llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
llvm/trunk/test/Instrumentation/AddressSanitizer/with-ifunc.ll
Modified: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp?rev=318235&r1=318234&r2=318235&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp Tue Nov 14 16:11:51 2017
@@ -211,7 +211,13 @@ static cl::opt<bool>
ClWithIfunc("asan-with-ifunc",
cl::desc("Access dynamic shadow through an ifunc global on "
"platforms that support this"),
- cl::Hidden, cl::init(false));
+ cl::Hidden, cl::init(true));
+
+static cl::opt<bool> ClWithIfuncSuppressRemat(
+ "asan-with-ifunc-suppress-remat",
+ cl::desc("Suppress rematerialization of dynamic shadow address by passing "
+ "it through inline asm in prologue."),
+ cl::Hidden, cl::init(true));
// This flag limits the number of instructions to be instrumented
// in any given BB. Normally, this should be set to unlimited (INT_MAX),
@@ -988,8 +994,9 @@ struct FunctionStackPoisoner : public In
void visitCallSite(CallSite CS) {
Instruction *I = CS.getInstruction();
if (CallInst *CI = dyn_cast<CallInst>(I)) {
- HasNonEmptyInlineAsm |=
- CI->isInlineAsm() && !CI->isIdenticalTo(EmptyInlineAsm.get());
+ HasNonEmptyInlineAsm |= CI->isInlineAsm() &&
+ !CI->isIdenticalTo(EmptyInlineAsm.get()) &&
+ I != ASan.LocalDynamicShadow;
HasReturnsTwiceCall |= CI->canReturnTwice();
}
}
@@ -1121,11 +1128,6 @@ Value *AddressSanitizer::memToShadow(Val
if (Mapping.Offset == 0) return Shadow;
// (Shadow >> scale) | offset
Value *ShadowBase;
- if (Mapping.InGlobal)
- return IRB.CreatePtrToInt(
- IRB.CreateGEP(AsanShadowGlobal,
- {ConstantInt::get(IntptrTy, 0), Shadow}),
- IntptrTy);
if (LocalDynamicShadow)
ShadowBase = LocalDynamicShadow;
else
@@ -2343,13 +2345,29 @@ bool AddressSanitizer::maybeInsertAsanIn
void AddressSanitizer::maybeInsertDynamicShadowAtFunctionEntry(Function &F) {
// Generate code only when dynamic addressing is needed.
- if (Mapping.Offset != kDynamicShadowSentinel || Mapping.InGlobal)
+ if (Mapping.Offset != kDynamicShadowSentinel)
return;
IRBuilder<> IRB(&F.front().front());
- Value *GlobalDynamicAddress = F.getParent()->getOrInsertGlobal(
- kAsanShadowMemoryDynamicAddress, IntptrTy);
- LocalDynamicShadow = IRB.CreateLoad(GlobalDynamicAddress);
+ if (Mapping.InGlobal) {
+ if (ClWithIfuncSuppressRemat) {
+ // An empty inline asm with input reg == output reg.
+ // An opaque pointer-to-int cast, basically.
+ InlineAsm *Asm = InlineAsm::get(
+ FunctionType::get(IntptrTy, {AsanShadowGlobal->getType()}, false),
+ StringRef(""), StringRef("=r,0"),
+ /*hasSideEffects=*/false);
+ LocalDynamicShadow =
+ IRB.CreateCall(Asm, {AsanShadowGlobal}, ".asan.shadow");
+ } else {
+ LocalDynamicShadow =
+ IRB.CreatePointerCast(AsanShadowGlobal, IntptrTy, ".asan.shadow");
+ }
+ } else {
+ Value *GlobalDynamicAddress = F.getParent()->getOrInsertGlobal(
+ kAsanShadowMemoryDynamicAddress, IntptrTy);
+ LocalDynamicShadow = IRB.CreateLoad(GlobalDynamicAddress);
+ }
}
void AddressSanitizer::markEscapedLocalAllocas(Function &F) {
Modified: llvm/trunk/test/Instrumentation/AddressSanitizer/with-ifunc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/AddressSanitizer/with-ifunc.ll?rev=318235&r1=318234&r2=318235&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/AddressSanitizer/with-ifunc.ll (original)
+++ llvm/trunk/test/Instrumentation/AddressSanitizer/with-ifunc.ll Tue Nov 14 16:11:51 2017
@@ -1,7 +1,11 @@
-; Test -asan-force-dynamic-shadow flag.
+; Test -asan-with-ifunc flag.
;
-; RUN: opt -asan -asan-module -S -asan-with-ifunc=1 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-IFUNC
-; RUN: opt -asan -asan-module -S -asan-with-ifunc=0 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-NOIFUNC
+; RUN: opt -asan -asan-module -S -asan-with-ifunc=0 < %s | \
+; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-NOIFUNC
+; RUN: opt -asan -asan-module -S -asan-with-ifunc=1 -asan-with-ifunc-suppress-remat=0 < %s | \
+; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-IFUNC
+; RUN: opt -asan -asan-module -S -asan-with-ifunc=1 -asan-with-ifunc-suppress-remat=1 < %s | \
+; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-IFUNC-NOREMAT
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
target triple = "armv7--linux-android"
@@ -17,7 +21,12 @@ define i32 @test_load(i32* %a) sanitize_
; CHECK-IFUNC-NEXT: %[[A:[^ ]*]] = ptrtoint i32* %a to i32
; CHECK-IFUNC-NEXT: %[[B:[^ ]*]] = lshr i32 %[[A]], 3
-; CHECK-IFUNC-NEXT: %[[C:[^ ]*]] = getelementptr [0 x i8], [0 x i8]* @__asan_shadow, i32 0, i32 %[[B]]
+; CHECK-IFUNC-NEXT: %[[C:[^ ]*]] = add i32 %[[B]], ptrtoint ([0 x i8]* @__asan_shadow to i32)
+
+; CHECK-IFUNC-NOREMAT-NEXT: %[[S:[^ ]*]] = call i32 asm "", "=r,0"([0 x i8]* @__asan_shadow)
+; CHECK-IFUNC-NOREMAT-NEXT: %[[A:[^ ]*]] = ptrtoint i32* %a to i32
+; CHECK-IFUNC-NOREMAT-NEXT: %[[B:[^ ]*]] = lshr i32 %[[A]], 3
+; CHECK-IFUNC-NOREMAT-NEXT: %[[C:[^ ]*]] = add i32 %[[B]], %[[S]]
; CHECK-NOIFUNC-NEXT: %[[SHADOW:[^ ]*]] = load i32, i32* @__asan_shadow_memory_dynamic_address
; CHECK-NOIFUNC-NEXT: %[[A:[^ ]*]] = ptrtoint i32* %a to i32
More information about the llvm-commits
mailing list