summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2016-04-05 22:41:50 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2016-04-05 22:41:50 +0000
commitdde29e2799b82bf76b263eac46acf3a1ae90d206 (patch)
tree3de199ef85cff9089e3b7b882b6b41eaf996948c
parentf8bdd88cd95e5387ad853874fe2db38edfe76c41 (diff)
downloadbcm5719-llvm-dde29e2799b82bf76b263eac46acf3a1ae90d206.tar.gz
bcm5719-llvm-dde29e2799b82bf76b263eac46acf3a1ae90d206.zip
Faster stack-protector for Android/AArch64.
Bionic has a defined thread-local location for the stack protector cookie. Emit a direct load instead of going through __stack_chk_guard. llvm-svn: 265481
-rw-r--r--llvm/include/llvm/Target/TargetLowering.h10
-rw-r--r--llvm/lib/CodeGen/StackProtector.cpp28
-rw-r--r--llvm/lib/Target/AArch64/AArch64ISelLowering.cpp16
-rw-r--r--llvm/lib/Target/AArch64/AArch64ISelLowering.h4
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp13
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.h8
-rw-r--r--llvm/test/CodeGen/AArch64/stack-protector-target.ll19
-rw-r--r--llvm/test/CodeGen/X86/stack-protector-target.ll25
8 files changed, 90 insertions, 33 deletions
diff --git a/llvm/include/llvm/Target/TargetLowering.h b/llvm/include/llvm/Target/TargetLowering.h
index d56b6e6e486..8528d468aa6 100644
--- a/llvm/include/llvm/Target/TargetLowering.h
+++ b/llvm/include/llvm/Target/TargetLowering.h
@@ -1011,12 +1011,10 @@ public:
return PrefLoopAlignment;
}
- /// Return true if the target stores stack protector cookies at a fixed offset
- /// in some non-standard address space, and populates the address space and
- /// offset as appropriate.
- virtual bool getStackCookieLocation(unsigned &/*AddressSpace*/,
- unsigned &/*Offset*/) const {
- return false;
+ /// If the target has a standard location for the stack protector cookie,
+ /// returns the address of that location. Otherwise, returns nullptr.
+ virtual Value *getStackCookieLocation(IRBuilder<> &IRB) const {
+ return nullptr;
}
/// If the target has a standard location for the unsafe stack pointer,
diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp
index db3fef524b3..23ae672944d 100644
--- a/llvm/lib/CodeGen/StackProtector.cpp
+++ b/llvm/lib/CodeGen/StackProtector.cpp
@@ -333,24 +333,20 @@ static bool CreatePrologue(Function *F, Module *M, ReturnInst *RI,
AllocaInst *&AI, Value *&StackGuardVar) {
bool SupportsSelectionDAGSP = false;
PointerType *PtrTy = Type::getInt8PtrTy(RI->getContext());
- unsigned AddressSpace, Offset;
- if (TLI->getStackCookieLocation(AddressSpace, Offset)) {
- Constant *OffsetVal =
- ConstantInt::get(Type::getInt32Ty(RI->getContext()), Offset);
-
- StackGuardVar =
- ConstantExpr::getIntToPtr(OffsetVal, PointerType::get(PtrTy,
- AddressSpace));
- } else if (TT.isOSOpenBSD()) {
- StackGuardVar = M->getOrInsertGlobal("__guard_local", PtrTy);
- cast<GlobalValue>(StackGuardVar)
- ->setVisibility(GlobalValue::HiddenVisibility);
- } else {
- SupportsSelectionDAGSP = true;
- StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy);
+ IRBuilder<> B(&F->getEntryBlock().front());
+
+ StackGuardVar = TLI->getStackCookieLocation(B);
+ if (!StackGuardVar) {
+ if (TT.isOSOpenBSD()) {
+ StackGuardVar = M->getOrInsertGlobal("__guard_local", PtrTy);
+ cast<GlobalValue>(StackGuardVar)
+ ->setVisibility(GlobalValue::HiddenVisibility);
+ } else {
+ SupportsSelectionDAGSP = true;
+ StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy);
+ }
}
- IRBuilder<> B(&F->getEntryBlock().front());
AI = B.CreateAlloca(PtrTy, nullptr, "StackGuardSlot");
LoadInst *LI = B.CreateLoad(StackGuardVar, "StackGuard");
B.CreateCall(Intrinsic::getDeclaration(M, Intrinsic::stackprotector),
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 6d8f3eebff3..2d3ddaa060f 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -10212,6 +10212,22 @@ bool AArch64TargetLowering::shouldNormalizeToSelectSequence(LLVMContext &,
return false;
}
+Value *AArch64TargetLowering::getStackCookieLocation(IRBuilder<> &IRB) const {
+ if (!Subtarget->isTargetAndroid())
+ return TargetLowering::getStackCookieLocation(IRB);
+
+ // Android provides a fixed TLS slot for the stack cookie. See the definition
+ // of TLS_SLOT_STACK_GUARD in
+ // https://android.googlesource.com/platform/bionic/+/master/libc/private/bionic_tls.h
+ const unsigned TlsOffset = 0x28;
+ Module *M = IRB.GetInsertBlock()->getParent()->getParent();
+ Function *ThreadPointerFunc =
+ Intrinsic::getDeclaration(M, Intrinsic::aarch64_thread_pointer);
+ return IRB.CreatePointerCast(
+ IRB.CreateConstGEP1_32(IRB.CreateCall(ThreadPointerFunc), TlsOffset),
+ Type::getInt8PtrTy(IRB.getContext())->getPointerTo(0));
+}
+
Value *AArch64TargetLowering::getSafeStackPointerLocation(IRBuilder<> &IRB) const {
if (!Subtarget->isTargetAndroid())
return TargetLowering::getSafeStackPointerLocation(IRB);
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index 2f5b5f36718..c9be8304a17 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -358,6 +358,10 @@ public:
TargetLoweringBase::LegalizeTypeAction
getPreferredVectorAction(EVT VT) const override;
+ /// If the target has a standard location for the stack protector cookie,
+ /// returns the address of that location. Otherwise, returns nullptr.
+ Value *getStackCookieLocation(IRBuilder<> &IRB) const override;
+
/// If the target has a standard location for the unsafe stack pointer,
/// returns the address of that location. Otherwise, returns nullptr.
Value *getSafeStackPointerLocation(IRBuilder<> &IRB) const override;
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index ea5518ed4c6..f81a3082ed2 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -2193,16 +2193,17 @@ unsigned X86TargetLowering::getAddressSpace() const {
return 256;
}
-bool X86TargetLowering::getStackCookieLocation(unsigned &AddressSpace,
- unsigned &Offset) const {
+Value *X86TargetLowering::getStackCookieLocation(IRBuilder<> &IRB) const {
if (!Subtarget.isTargetLinux())
- return false;
+ return TargetLowering::getStackCookieLocation(IRB);
// %fs:0x28, unless we're using a Kernel code model, in which case it's %gs:
// %gs:0x14 on i386
- Offset = (Subtarget.is64Bit()) ? 0x28 : 0x14;
- AddressSpace = getAddressSpace();
- return true;
+ unsigned Offset = (Subtarget.is64Bit()) ? 0x28 : 0x14;
+ unsigned AddressSpace = getAddressSpace();
+ return ConstantExpr::getIntToPtr(
+ ConstantInt::get(Type::getInt32Ty(IRB.getContext()), Offset),
+ Type::getInt8PtrTy(IRB.getContext())->getPointerTo(AddressSpace));
}
Value *X86TargetLowering::getSafeStackPointerLocation(IRBuilder<> &IRB) const {
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index 664eadd000a..7007782ccf4 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -960,11 +960,9 @@ namespace llvm {
FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
const TargetLibraryInfo *libInfo) const override;
- /// Return true if the target stores stack protector cookies at a fixed
- /// offset in some non-standard address space, and populates the address
- /// space and offset as appropriate.
- bool getStackCookieLocation(unsigned &AddressSpace,
- unsigned &Offset) const override;
+ /// If the target has a standard location for the stack protector cookie,
+ /// returns the address of that location. Otherwise, returns nullptr.
+ Value *getStackCookieLocation(IRBuilder<> &IRB) const override;
/// Return true if the target stores SafeStack pointer at a fixed offset in
/// some non-standard address space, and populates the address space and
diff --git a/llvm/test/CodeGen/AArch64/stack-protector-target.ll b/llvm/test/CodeGen/AArch64/stack-protector-target.ll
new file mode 100644
index 00000000000..d4d806289bf
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/stack-protector-target.ll
@@ -0,0 +1,19 @@
+; Test target-specific stack cookie location.
+; RUN: llc -mtriple=aarch64-linux-android < %s -o - | FileCheck --check-prefix=ANDROID-AARCH64 %s
+
+define void @_Z1fv() sspreq {
+entry:
+ %x = alloca i32, align 4
+ %0 = bitcast i32* %x to i8*
+ call void @_Z7CapturePi(i32* nonnull %x)
+ ret void
+}
+
+declare void @_Z7CapturePi(i32*)
+
+; ANDROID-AARCH64: mrs [[A:.*]], TPIDR_EL0
+; ANDROID-AARCH64: ldr [[B:.*]], {{\[}}[[A]], #40]
+; ANDROID-AARCH64: str [[B]], [sp,
+; ANDROID-AARCH64: ldr [[C:.*]], {{\[}}[[A]], #40]
+; ANDROID-AARCH64: ldr [[D:.*]], [sp,
+; ANDROID-AARCH64: cmp [[C]], [[D]]
diff --git a/llvm/test/CodeGen/X86/stack-protector-target.ll b/llvm/test/CodeGen/X86/stack-protector-target.ll
new file mode 100644
index 00000000000..3f69bfd7e7b
--- /dev/null
+++ b/llvm/test/CodeGen/X86/stack-protector-target.ll
@@ -0,0 +1,25 @@
+; Test target-specific stack cookie location.
+; RUN: llc -mtriple=i386-linux < %s -o - | FileCheck --check-prefix=LINUX-I386 %s
+; RUN: llc -mtriple=x86_64-linux < %s -o - | FileCheck --check-prefix=LINUX-X64 %s
+; RUN: llc -mtriple=i386-linux-android < %s -o - | FileCheck --check-prefix=LINUX-I386 %s
+; RUN: llc -mtriple=x86_64-linux-android < %s -o - | FileCheck --check-prefix=LINUX-X64 %s
+
+define void @_Z1fv() sspreq {
+entry:
+ %x = alloca i32, align 4
+ %0 = bitcast i32* %x to i8*
+ call void @_Z7CapturePi(i32* nonnull %x)
+ ret void
+}
+
+declare void @_Z7CapturePi(i32*)
+
+; LINUX-X64: movq %fs:40, %[[B:.*]]
+; LINUX-X64: movq %[[B]], 16(%rsp)
+; LINUX-X64: movq %fs:40, %[[C:.*]]
+; LINUX-X64: cmpq 16(%rsp), %[[C]]
+
+; LINUX-I386: movl %gs:20, %[[B:.*]]
+; LINUX-I386: movl %[[B]], 8(%esp)
+; LINUX-I386: movl %gs:20, %[[C:.*]]
+; LINUX-I386: cmpl 8(%esp), %[[C]]
OpenPOWER on IntegriCloud