diff options
| author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2018-01-23 21:27:07 +0000 |
|---|---|---|
| committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2018-01-23 21:27:07 +0000 |
| commit | d5a6fdbe95943f63d6b003a4d883437d7645ff46 (patch) | |
| tree | b31b76a6b29d48881fd96999593ba29e852c8e40 | |
| parent | c1e2290d373b461f71744ad0792e8306a66f0dee (diff) | |
| download | bcm5719-llvm-d5a6fdbe95943f63d6b003a4d883437d7645ff46.tar.gz bcm5719-llvm-d5a6fdbe95943f63d6b003a4d883437d7645ff46.zip | |
[safestack] Inline safestack pointer access when possible.
Summary:
This adds an -mllvm flag that forces the use of a runtime function call to
get the unsafe stack pointer, the same that is currently used on non-x86, non-aarch64 android.
The call may be inlined.
Reviewers: pcc
Subscribers: aemerson, kristof.beyls, hiraditya, llvm-commits
Differential Revision: https://reviews.llvm.org/D37405
llvm-svn: 323259
| -rw-r--r-- | llvm/lib/CodeGen/SafeStack.cpp | 51 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/safestack.ll | 8 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/safestack_inline.ll | 30 |
3 files changed, 88 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/SafeStack.cpp b/llvm/lib/CodeGen/SafeStack.cpp index 51233be521b..841a5ec000f 100644 --- a/llvm/lib/CodeGen/SafeStack.cpp +++ b/llvm/lib/CodeGen/SafeStack.cpp @@ -24,6 +24,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/BranchProbabilityInfo.h" +#include "llvm/Analysis/InlineCost.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" @@ -61,6 +62,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/Local.h" #include <algorithm> #include <cassert> @@ -88,6 +90,13 @@ STATISTIC(NumUnsafeStackRestorePoints, "Number of setjmps and landingpads"); } // namespace llvm +/// Use __safestack_pointer_address even if the platform has a faster way of +/// access safe stack pointer. +static cl::opt<bool> + SafeStackUsePointerAddress("safestack-use-pointer-address", + cl::init(false), cl::Hidden); + + namespace { /// Rewrite an SCEV expression for a memory access address to an expression that @@ -191,6 +200,9 @@ class SafeStack { bool IsAccessSafe(Value *Addr, uint64_t Size, const Value *AllocaPtr, uint64_t AllocaSize); + bool ShouldInlinePointerAddress(CallSite &CS); + void TryInlinePointerAddress(); + public: SafeStack(Function &F, const TargetLoweringBase &TL, const DataLayout &DL, ScalarEvolution &SE) @@ -695,6 +707,35 @@ void SafeStack::moveDynamicAllocasToUnsafeStack( } } +bool SafeStack::ShouldInlinePointerAddress(CallSite &CS) { + Function *Callee = CS.getCalledFunction(); + if (CS.hasFnAttr(Attribute::AlwaysInline) && isInlineViable(*Callee)) + return true; + if (Callee->isInterposable() || Callee->hasFnAttribute(Attribute::NoInline) || + CS.isNoInline()) + return false; + return true; +} + +void SafeStack::TryInlinePointerAddress() { + if (!isa<CallInst>(UnsafeStackPtr)) + return; + + if(F.hasFnAttribute(Attribute::OptimizeNone)) + return; + + CallSite CS(UnsafeStackPtr); + Function *Callee = CS.getCalledFunction(); + if (!Callee || Callee->isDeclaration()) + return; + + if (!ShouldInlinePointerAddress(CS)) + return; + + InlineFunctionInfo IFI; + InlineFunction(CS, IFI); +} + bool SafeStack::run() { assert(F.hasFnAttribute(Attribute::SafeStack) && "Can't run SafeStack on a function without the attribute"); @@ -731,7 +772,13 @@ bool SafeStack::run() { ++NumUnsafeStackRestorePointsFunctions; IRBuilder<> IRB(&F.front(), F.begin()->getFirstInsertionPt()); - UnsafeStackPtr = TL.getSafeStackPointerLocation(IRB); + if (SafeStackUsePointerAddress) { + Value *Fn = F.getParent()->getOrInsertFunction( + "__safestack_pointer_address", StackPtrTy->getPointerTo(0)); + UnsafeStackPtr = IRB.CreateCall(Fn); + } else { + UnsafeStackPtr = TL.getSafeStackPointerLocation(IRB); + } // Load the current stack pointer (we'll also use it as a base pointer). // FIXME: use a dedicated register for it ? @@ -779,6 +826,8 @@ bool SafeStack::run() { IRB.CreateStore(BasePointer, UnsafeStackPtr); } + TryInlinePointerAddress(); + DEBUG(dbgs() << "[SafeStack] safestack applied\n"); return true; } diff --git a/llvm/test/CodeGen/X86/safestack.ll b/llvm/test/CodeGen/X86/safestack.ll index bd8f57f5e3c..a9d1b32cfcf 100644 --- a/llvm/test/CodeGen/X86/safestack.ll +++ b/llvm/test/CodeGen/X86/safestack.ll @@ -4,6 +4,8 @@ ; RUN: llc -mtriple=x86_64-linux-android < %s -o - | FileCheck --check-prefix=ANDROID-X64 %s ; RUN: llc -mtriple=x86_64-fuchsia < %s -o - | FileCheck --check-prefix=FUCHSIA-X64 %s +; RUN: llc -mtriple=i386-linux -safestack-use-pointer-address < %s -o - | FileCheck --check-prefix=LINUX-I386-PA %s + define void @_Z1fv() safestack { entry: %x = alloca i32, align 4 @@ -35,3 +37,9 @@ declare void @_Z7CapturePi(i32*) ; FUCHSIA-X64: movq %fs:24, %[[A:.*]] ; FUCHSIA-X64: leaq -16(%[[A]]), %[[B:.*]] ; FUCHSIA-X64: movq %[[B]], %fs:24 + +; LINUX-I386-PA: calll __safestack_pointer_address +; LINUX-I386-PA: movl %eax, %[[A:.*]] +; LINUX-I386-PA: movl (%[[A]]), %[[B:.*]] +; LINUX-I386-PA: leal -16(%[[B]]), %[[C:.*]] +; LINUX-I386-PA: movl %[[C]], (%[[A]]) diff --git a/llvm/test/CodeGen/X86/safestack_inline.ll b/llvm/test/CodeGen/X86/safestack_inline.ll new file mode 100644 index 00000000000..ed93c498564 --- /dev/null +++ b/llvm/test/CodeGen/X86/safestack_inline.ll @@ -0,0 +1,30 @@ +; RUN: sed -e "s/ATTR//" %s | llc -mtriple=x86_64-linux -safestack-use-pointer-address | FileCheck --check-prefix=INLINE %s +; RUN: sed -e "s/ATTR/noinline/" %s | llc -mtriple=x86_64-linux -safestack-use-pointer-address | FileCheck --check-prefix=CALL %s + +@p = external thread_local global i8*, align 8 + +define nonnull i8** @__safestack_pointer_address() local_unnamed_addr ATTR { +entry: + ret i8** @p +} + +define void @_Z1fv() safestack { +entry: + %x = alloca i32, align 4 + %0 = bitcast i32* %x to i8* + call void @_Z7CapturePi(i32* nonnull %x) + ret void +} + +declare void @_Z7CapturePi(i32*) + +; INLINE: movq p@GOTTPOFF(%rip), %[[A:.*]] +; INLINE: movq %fs:(%[[A]]), %[[B:.*]] +; INLINE: leaq -16(%[[B]]), %[[C:.*]] +; INLINE: movq %[[C]], %fs:(%[[A]]) + +; CALL: callq __safestack_pointer_address +; CALL: movq %rax, %[[A:.*]] +; CALL: movq (%[[A]]), %[[B:.*]] +; CALL: leaq -16(%[[B]]), %[[C:.*]] +; CALL: movq %[[C]], (%[[A]]) |

