[llvm] r323259 - [safestack] Inline safestack pointer access when possible.

Evgeniy Stepanov via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 23 13:27:07 PST 2018


Author: eugenis
Date: Tue Jan 23 13:27:07 2018
New Revision: 323259

URL: http://llvm.org/viewvc/llvm-project?rev=323259&view=rev
Log:
[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

Added:
    llvm/trunk/test/CodeGen/X86/safestack_inline.ll
Modified:
    llvm/trunk/lib/CodeGen/SafeStack.cpp
    llvm/trunk/test/CodeGen/X86/safestack.ll

Modified: llvm/trunk/lib/CodeGen/SafeStack.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SafeStack.cpp?rev=323259&r1=323258&r2=323259&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SafeStack.cpp (original)
+++ llvm/trunk/lib/CodeGen/SafeStack.cpp Tue Jan 23 13:27:07 2018
@@ -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, "
 
 } // 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::moveDynamicAllocasToUnsa
   }
 }
 
+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;
 }

Modified: llvm/trunk/test/CodeGen/X86/safestack.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/safestack.ll?rev=323259&r1=323258&r2=323259&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/safestack.ll (original)
+++ llvm/trunk/test/CodeGen/X86/safestack.ll Tue Jan 23 13:27:07 2018
@@ -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]])

Added: llvm/trunk/test/CodeGen/X86/safestack_inline.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/safestack_inline.ll?rev=323259&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/safestack_inline.ll (added)
+++ llvm/trunk/test/CodeGen/X86/safestack_inline.ll Tue Jan 23 13:27:07 2018
@@ -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
+
+ at 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 at 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]])




More information about the llvm-commits mailing list