[llvm] r265851 - [SSP] Remove llvm.stackprotectorcheck.
Tim Shen via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 8 14:26:33 PDT 2016
Author: timshen
Date: Fri Apr 8 16:26:31 2016
New Revision: 265851
URL: http://llvm.org/viewvc/llvm-project?rev=265851&view=rev
Log:
[SSP] Remove llvm.stackprotectorcheck.
This is a cleanup patch for SSP support in LLVM. There is no functional change.
llvm.stackprotectorcheck is not needed, because SelectionDAG isn't
actually lowering it in SelectBasicBlock; rather, it adds check code in
FinishBasicBlock, ignoring the position where the intrinsic is inserted
(See FindSplitPointForStackProtector()).
Modified:
llvm/trunk/docs/LangRef.rst
llvm/trunk/include/llvm/CodeGen/StackProtector.h
llvm/trunk/include/llvm/IR/Intrinsics.td
llvm/trunk/include/llvm/Target/TargetLowering.h
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
llvm/trunk/lib/CodeGen/StackProtector.cpp
llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp
llvm/trunk/lib/IR/AutoUpgrade.cpp
llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
llvm/trunk/lib/Target/X86/X86ISelLowering.h
llvm/trunk/test/Assembler/auto_upgrade_intrinsics.ll
Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=265851&r1=265850&r2=265851&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Fri Apr 8 16:26:31 2016
@@ -11946,44 +11946,6 @@ checked against the original guard by ``
different, then ``llvm.stackprotectorcheck`` causes the program to abort by
calling the ``__stack_chk_fail()`` function.
-'``llvm.stackprotectorcheck``' Intrinsic
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Syntax:
-"""""""
-
-::
-
- declare void @llvm.stackprotectorcheck(i8** <guard>)
-
-Overview:
-"""""""""
-
-The ``llvm.stackprotectorcheck`` intrinsic compares ``guard`` against an already
-created stack protector and if they are not equal calls the
-``__stack_chk_fail()`` function.
-
-Arguments:
-""""""""""
-
-The ``llvm.stackprotectorcheck`` intrinsic requires one pointer argument, the
-the variable ``@__stack_chk_guard``.
-
-Semantics:
-""""""""""
-
-This intrinsic is provided to perform the stack protector check by comparing
-``guard`` with the stack slot created by ``llvm.stackprotector`` and if the
-values do not match call the ``__stack_chk_fail()`` function.
-
-The reason to provide this as an IR level intrinsic instead of implementing it
-via other IR operations is that in order to perform this operation at the IR
-level without an intrinsic, one would need to create additional basic blocks to
-handle the success/failure cases. This makes it difficult to stop the stack
-protector check from disrupting sibling tail calls in Codegen. With this
-intrinsic, we are able to generate the stack protector basic blocks late in
-codegen after the tail call decision has occurred.
-
'``llvm.objectsize``' Intrinsic
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Modified: llvm/trunk/include/llvm/CodeGen/StackProtector.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/StackProtector.h?rev=265851&r1=265850&r2=265851&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/StackProtector.h (original)
+++ llvm/trunk/include/llvm/CodeGen/StackProtector.h Fri Apr 8 16:26:31 2016
@@ -75,6 +75,12 @@ private:
/// times.
SmallPtrSet<const PHINode *, 16> VisitedPHIs;
+ // A prologue is generated.
+ bool HasPrologue = false;
+
+ // IR checking code is generated.
+ bool HasIRCheck = false;
+
/// InsertStackProtectors - Insert code into the prologue and epilogue of
/// the function.
///
@@ -120,6 +126,10 @@ public:
}
SSPLayoutKind getSSPLayout(const AllocaInst *AI) const;
+
+ // Return true if StackProtector is supposed to be handled by SelectionDAG.
+ bool shouldEmitSDCheck(const BasicBlock &BB) const;
+
void adjustForColoring(const AllocaInst *From, const AllocaInst *To);
bool runOnFunction(Function &Fn) override;
Modified: llvm/trunk/include/llvm/IR/Intrinsics.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Intrinsics.td?rev=265851&r1=265850&r2=265851&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Intrinsics.td (original)
+++ llvm/trunk/include/llvm/IR/Intrinsics.td Fri Apr 8 16:26:31 2016
@@ -324,8 +324,6 @@ def int_assume : Intrinsic<[], [l
// Stack Protector Intrinsic - The stackprotector intrinsic writes the stack
// guard to the correct place on the stack frame.
def int_stackprotector : Intrinsic<[], [llvm_ptr_ty, llvm_ptrptr_ty], []>;
-def int_stackprotectorcheck : Intrinsic<[], [llvm_ptrptr_ty],
- [IntrReadWriteArgMem]>;
// A counter increment for instrumentation based profiling.
def int_instrprof_increment : Intrinsic<[],
Modified: llvm/trunk/include/llvm/Target/TargetLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=265851&r1=265850&r2=265851&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetLowering.h (original)
+++ llvm/trunk/include/llvm/Target/TargetLowering.h Fri Apr 8 16:26:31 2016
@@ -1011,11 +1011,18 @@ public:
return PrefLoopAlignment;
}
- /// If the target has a standard location for the stack protector cookie,
+ /// If the target has a standard location for the stack protector guard,
/// returns the address of that location. Otherwise, returns nullptr.
- virtual Value *getStackCookieLocation(IRBuilder<> &IRB) const {
- return nullptr;
- }
+ virtual Value *getIRStackGuard(IRBuilder<> &IRB) const;
+
+ /// Inserts necessary declarations for SSP purpose. Should be used only when
+ /// getIRStackGuard returns nullptr.
+ virtual void insertSSPDeclarations(Module &M) const;
+
+ /// Return the variable that's previously inserted by insertSSPDeclarations,
+ /// if any, otherwise return nullptr. Should be used only when
+ /// getIRStackGuard returns nullptr.
+ virtual Value *getSDStackGuard(const Module &M) const;
/// If the target has a standard location for the unsafe stack pointer,
/// returns the address of that location. Otherwise, returns nullptr.
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=265851&r1=265850&r2=265851&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Fri Apr 8 16:26:31 2016
@@ -2014,7 +2014,10 @@ void SelectionDAGBuilder::visitSPDescrip
MachineFrameInfo *MFI = ParentBB->getParent()->getFrameInfo();
int FI = MFI->getStackProtectorIndex();
- const Value *IRGuard = SPD.getGuard();
+ const Module &M = *ParentBB->getParent()->getFunction()->getParent();
+ const Value *IRGuard = TLI.getSDStackGuard(M);
+ assert(IRGuard && "Currently there must be an IR guard in order to use "
+ "SelectionDAG SSP");
SDValue GuardPtr = getValue(IRGuard);
SDValue StackSlotPtr = DAG.getFrameIndex(FI, PtrTy);
@@ -5517,18 +5520,6 @@ SelectionDAGBuilder::visitIntrinsicCall(
case Intrinsic::invariant_end:
// Discard region information.
return nullptr;
- case Intrinsic::stackprotectorcheck: {
- // Do not actually emit anything for this basic block. Instead we initialize
- // the stack protector descriptor and export the guard variable so we can
- // access it in FinishBasicBlock.
- const BasicBlock *BB = I.getParent();
- SPDescriptor.initialize(BB, FuncInfo.MBBMap[BB], I);
- ExportFromCurrentBlock(SPDescriptor.getGuard());
-
- // Flush our exports since we are going to process a terminator.
- (void)getControlRoot();
- return nullptr;
- }
case Intrinsic::clear_cache:
return TLI.getClearCacheBuiltinName();
case Intrinsic::donothing:
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h?rev=265851&r1=265850&r2=265851&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h Fri Apr 8 16:26:31 2016
@@ -464,29 +464,25 @@ private:
/// the same function, use the same failure basic block).
class StackProtectorDescriptor {
public:
- StackProtectorDescriptor() : ParentMBB(nullptr), SuccessMBB(nullptr),
- FailureMBB(nullptr), Guard(nullptr),
- GuardReg(0) { }
+ StackProtectorDescriptor()
+ : ParentMBB(nullptr), SuccessMBB(nullptr), FailureMBB(nullptr),
+ GuardReg(0) {}
/// Returns true if all fields of the stack protector descriptor are
/// initialized implying that we should/are ready to emit a stack protector.
bool shouldEmitStackProtector() const {
- return ParentMBB && SuccessMBB && FailureMBB && Guard;
+ return ParentMBB && SuccessMBB && FailureMBB;
}
/// Initialize the stack protector descriptor structure for a new basic
/// block.
- void initialize(const BasicBlock *BB,
- MachineBasicBlock *MBB,
- const CallInst &StackProtCheckCall) {
+ void initialize(const BasicBlock *BB, MachineBasicBlock *MBB) {
// Make sure we are not initialized yet.
assert(!shouldEmitStackProtector() && "Stack Protector Descriptor is "
"already initialized!");
ParentMBB = MBB;
SuccessMBB = AddSuccessorMBB(BB, MBB, /* IsLikely */ true);
FailureMBB = AddSuccessorMBB(BB, MBB, /* IsLikely */ false, FailureMBB);
- if (!Guard)
- Guard = StackProtCheckCall.getArgOperand(0);
}
/// Reset state that changes when we handle different basic blocks.
@@ -515,14 +511,12 @@ private:
/// always the same.
void resetPerFunctionState() {
FailureMBB = nullptr;
- Guard = nullptr;
GuardReg = 0;
}
MachineBasicBlock *getParentMBB() { return ParentMBB; }
MachineBasicBlock *getSuccessMBB() { return SuccessMBB; }
MachineBasicBlock *getFailureMBB() { return FailureMBB; }
- const Value *getGuard() { return Guard; }
unsigned getGuardReg() const { return GuardReg; }
void setGuardReg(unsigned R) { GuardReg = R; }
@@ -545,10 +539,6 @@ private:
/// contain a call to __stack_chk_fail().
MachineBasicBlock *FailureMBB;
- /// The guard variable which we will compare against the stored value in the
- /// stack protector stack slot.
- const Value *Guard;
-
/// The virtual register holding the stack guard value.
unsigned GuardReg;
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=265851&r1=265850&r2=265851&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Apr 8 16:26:31 2016
@@ -11,7 +11,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/CodeGen/GCStrategy.h"
+#include "llvm/CodeGen/SelectionDAG.h"
#include "ScheduleDAGSDNodes.h"
#include "SelectionDAGBuilder.h"
#include "llvm/ADT/PostOrderIterator.h"
@@ -25,6 +25,7 @@
#include "llvm/CodeGen/FastISel.h"
#include "llvm/CodeGen/FunctionLoweringInfo.h"
#include "llvm/CodeGen/GCMetadata.h"
+#include "llvm/CodeGen/GCStrategy.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -32,8 +33,8 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
-#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/CodeGen/StackProtector.h"
#include "llvm/CodeGen/WinEHFuncInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfo.h"
@@ -377,6 +378,8 @@ SelectionDAGISel::~SelectionDAGISel() {
void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<AAResultsWrapperPass>();
AU.addRequired<GCModuleInfo>();
+ AU.addRequired<StackProtector>();
+ AU.addPreserved<StackProtector>();
AU.addPreserved<GCModuleInfo>();
AU.addRequired<TargetLibraryInfoWrapperPass>();
if (UseMBPI && OptLevel != CodeGenOpt::None)
@@ -1476,6 +1479,8 @@ void SelectionDAGISel::SelectAllBasicBlo
LowerArguments(Fn);
}
}
+ if (getAnalysis<StackProtector>().shouldEmitSDCheck(*LLVMBB))
+ SDB->SPDescriptor.initialize(LLVMBB, FuncInfo->MBBMap[LLVMBB]);
if (Begin != BI)
++NumDAGBlocks;
Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackProtector.cpp?rev=265851&r1=265850&r2=265851&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/StackProtector.cpp (original)
+++ llvm/trunk/lib/CodeGen/StackProtector.cpp Fri Apr 8 16:26:31 2016
@@ -89,6 +89,8 @@ bool StackProtector::runOnFunction(Funct
getAnalysisIfAvailable<DominatorTreeWrapperPass>();
DT = DTWP ? &DTWP->getDomTree() : nullptr;
TLI = TM->getSubtargetImpl(Fn)->getTargetLowering();
+ HasPrologue = false;
+ HasIRCheck = false;
Attribute Attr = Fn.getFnAttribute("stack-protector-buffer-size");
if (Attr.isStringAttribute() &&
@@ -200,11 +202,21 @@ bool StackProtector::HasAddressTaken(con
bool StackProtector::RequiresStackProtector() {
bool Strong = false;
bool NeedsProtector = false;
+ for (const BasicBlock &BB : *F)
+ for (const Instruction &I : BB)
+ if (const CallInst *CI = dyn_cast<CallInst>(&I))
+ if (CI->getCalledFunction() ==
+ Intrinsic::getDeclaration(F->getParent(),
+ Intrinsic::stackprotector))
+ HasPrologue = true;
+
if (F->hasFnAttribute(Attribute::StackProtectReq)) {
NeedsProtector = true;
Strong = true; // Use the same heuristic as strong to determine SSPLayout
} else if (F->hasFnAttribute(Attribute::StackProtectStrong))
Strong = true;
+ else if (HasPrologue)
+ NeedsProtector = true;
else if (!F->hasFnAttribute(Attribute::StackProtect))
return false;
@@ -256,68 +268,6 @@ bool StackProtector::RequiresStackProtec
return NeedsProtector;
}
-static bool InstructionWillNotHaveChain(const Instruction *I) {
- return !I->mayHaveSideEffects() && !I->mayReadFromMemory() &&
- isSafeToSpeculativelyExecute(I);
-}
-
-/// Identify if RI has a previous instruction in the "Tail Position" and return
-/// it. Otherwise return 0.
-///
-/// This is based off of the code in llvm::isInTailCallPosition. The difference
-/// is that it inverts the first part of llvm::isInTailCallPosition since
-/// isInTailCallPosition is checking if a call is in a tail call position, and
-/// we are searching for an unknown tail call that might be in the tail call
-/// position. Once we find the call though, the code uses the same refactored
-/// code, returnTypeIsEligibleForTailCall.
-static CallInst *FindPotentialTailCall(BasicBlock *BB, ReturnInst *RI,
- const TargetLoweringBase *TLI) {
- // Establish a reasonable upper bound on the maximum amount of instructions we
- // will look through to find a tail call.
- unsigned SearchCounter = 0;
- const unsigned MaxSearch = 4;
- bool NoInterposingChain = true;
-
- for (BasicBlock::reverse_iterator I = std::next(BB->rbegin()), E = BB->rend();
- I != E && SearchCounter < MaxSearch; ++I) {
- Instruction *Inst = &*I;
-
- // Skip over debug intrinsics and do not allow them to affect our MaxSearch
- // counter.
- if (isa<DbgInfoIntrinsic>(Inst))
- continue;
-
- // If we find a call and the following conditions are satisifed, then we
- // have found a tail call that satisfies at least the target independent
- // requirements of a tail call:
- //
- // 1. The call site has the tail marker.
- //
- // 2. The call site either will not cause the creation of a chain or if a
- // chain is necessary there are no instructions in between the callsite and
- // the call which would create an interposing chain.
- //
- // 3. The return type of the function does not impede tail call
- // optimization.
- if (CallInst *CI = dyn_cast<CallInst>(Inst)) {
- if (CI->isTailCall() &&
- (InstructionWillNotHaveChain(CI) || NoInterposingChain) &&
- returnTypeIsEligibleForTailCall(BB->getParent(), CI, RI, *TLI))
- return CI;
- }
-
- // If we did not find a call see if we have an instruction that may create
- // an interposing chain.
- NoInterposingChain =
- NoInterposingChain && InstructionWillNotHaveChain(Inst);
-
- // Increment max search.
- SearchCounter++;
- }
-
- return nullptr;
-}
-
/// Insert code into the entry block that stores the __stack_chk_guard
/// variable onto the stack:
///
@@ -329,29 +279,25 @@ static CallInst *FindPotentialTailCall(B
/// Returns true if the platform/triple supports the stackprotectorcreate pseudo
/// node.
static bool CreatePrologue(Function *F, Module *M, ReturnInst *RI,
- const TargetLoweringBase *TLI, const Triple &TT,
- AllocaInst *&AI, Value *&StackGuardVar) {
+ const TargetLoweringBase *TLI, AllocaInst *&AI,
+ Value *&StackGuardVar) {
bool SupportsSelectionDAGSP = false;
- PointerType *PtrTy = Type::getInt8PtrTy(RI->getContext());
IRBuilder<> B(&F->getEntryBlock().front());
- StackGuardVar = TLI->getStackCookieLocation(B);
+ StackGuardVar = TLI->getIRStackGuard(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);
- }
+ /// Use SelectionDAG SSP handling, since there isn't an IR guard.
+ SupportsSelectionDAGSP = true;
+ TLI->insertSSPDeclarations(*M);
+ StackGuardVar = TLI->getSDStackGuard(*M);
}
+ assert(StackGuardVar && "Must have stack guard available");
+ PointerType *PtrTy = Type::getInt8PtrTy(RI->getContext());
AI = B.CreateAlloca(PtrTy, nullptr, "StackGuardSlot");
LoadInst *LI = B.CreateLoad(StackGuardVar, "StackGuard");
B.CreateCall(Intrinsic::getDeclaration(M, Intrinsic::stackprotector),
{LI, AI});
-
return SupportsSelectionDAGSP;
}
@@ -362,7 +308,6 @@ static bool CreatePrologue(Function *F,
/// - The epilogue checks the value stored in the prologue against the original
/// value. It calls __stack_chk_fail if they differ.
bool StackProtector::InsertStackProtectors() {
- bool HasPrologue = false;
bool SupportsSelectionDAGSP =
EnableSelectionDAGSP && !TM->Options.EnableFastISel;
AllocaInst *AI = nullptr; // Place on stack that stores the stack guard.
@@ -377,27 +322,10 @@ bool StackProtector::InsertStackProtecto
if (!HasPrologue) {
HasPrologue = true;
SupportsSelectionDAGSP &=
- CreatePrologue(F, M, RI, TLI, Trip, AI, StackGuardVar);
+ CreatePrologue(F, M, RI, TLI, AI, StackGuardVar);
}
- if (SupportsSelectionDAGSP) {
- // Since we have a potential tail call, insert the special stack check
- // intrinsic.
- Instruction *InsertionPt = nullptr;
- if (CallInst *CI = FindPotentialTailCall(BB, RI, TLI)) {
- InsertionPt = CI;
- } else {
- InsertionPt = RI;
- // At this point we know that BB has a return statement so it *DOES*
- // have a terminator.
- assert(InsertionPt != nullptr &&
- "BB must have a terminator instruction at this point.");
- }
-
- Function *Intrinsic =
- Intrinsic::getDeclaration(M, Intrinsic::stackprotectorcheck);
- CallInst::Create(Intrinsic, StackGuardVar, "", InsertionPt);
- } else {
+ if (!SupportsSelectionDAGSP) {
// If we do not support SelectionDAG based tail calls, generate IR level
// tail calls.
//
@@ -428,6 +356,10 @@ bool StackProtector::InsertStackProtecto
// fail BB generated by the stack protector pseudo instruction.
BasicBlock *FailBB = CreateFailBB();
+ // Set HasIRCheck to true, so that SelectionDAG will not generate its own
+ // version.
+ HasIRCheck = true;
+
// Split the basic block before the return instruction.
BasicBlock *NewBB = BB->splitBasicBlock(RI->getIterator(), "SP_return");
@@ -487,3 +419,7 @@ BasicBlock *StackProtector::CreateFailBB
B.CreateUnreachable();
return FailBB;
}
+
+bool StackProtector::shouldEmitSDCheck(const BasicBlock &BB) const {
+ return HasPrologue && !HasIRCheck && dyn_cast<ReturnInst>(BB.getTerminator());
+}
Modified: llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp?rev=265851&r1=265850&r2=265851&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp (original)
+++ llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp Fri Apr 8 16:26:31 2016
@@ -1746,3 +1746,32 @@ bool TargetLoweringBase::isLegalAddressi
return true;
}
+
+//===----------------------------------------------------------------------===//
+// Stack Protector
+//===----------------------------------------------------------------------===//
+
+// For OpenBSD return its special guard variable. Otherwise return nullptr,
+// so that SelectionDAG handle SSP.
+Value *TargetLoweringBase::getIRStackGuard(IRBuilder<> &IRB) const {
+ if (getTargetMachine().getTargetTriple().isOSOpenBSD()) {
+ Module &M = *IRB.GetInsertBlock()->getParent()->getParent();
+ PointerType *PtrTy = Type::getInt8PtrTy(M.getContext());
+ auto Guard = cast<GlobalValue>(M.getOrInsertGlobal("__guard_local", PtrTy));
+ Guard->setVisibility(GlobalValue::HiddenVisibility);
+ return Guard;
+ }
+ return nullptr;
+}
+
+// Currently only support "standard" __stack_chk_guard.
+// TODO: add LOAD_STACK_GUARD support.
+void TargetLoweringBase::insertSSPDeclarations(Module &M) const {
+ M.getOrInsertGlobal("__stack_chk_guard", Type::getInt8PtrTy(M.getContext()));
+}
+
+// Currently only support "standard" __stack_chk_guard.
+// TODO: add LOAD_STACK_GUARD support.
+Value *TargetLoweringBase::getSDStackGuard(const Module &M) const {
+ return M.getGlobalVariable("__stack_chk_guard");
+}
Modified: llvm/trunk/lib/IR/AutoUpgrade.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AutoUpgrade.cpp?rev=265851&r1=265850&r2=265851&view=diff
==============================================================================
--- llvm/trunk/lib/IR/AutoUpgrade.cpp (original)
+++ llvm/trunk/lib/IR/AutoUpgrade.cpp Fri Apr 8 16:26:31 2016
@@ -159,6 +159,12 @@ static bool UpgradeIntrinsicFunction1(Fu
}
break;
+ case 's':
+ if (Name == "stackprotectorcheck") {
+ NewFn = nullptr;
+ return true;
+ }
+
case 'x': {
if (Name.startswith("x86.sse2.pcmpeq.") ||
Name.startswith("x86.sse2.pcmpgt.") ||
@@ -645,6 +651,8 @@ void llvm::UpgradeIntrinsicCall(CallInst
Value *UndefV = UndefValue::get(Op0->getType());
Rep = Builder.CreateShuffleVector(Op0, UndefV, ConstantVector::get(Idxs));
+ } else if (Name == "llvm.stackprotectorcheck") {
+ Rep = nullptr;
} else {
bool PD128 = false, PD256 = false, PS128 = false, PS256 = false;
if (Name == "llvm.x86.avx.vpermil.pd.256")
@@ -684,7 +692,8 @@ void llvm::UpgradeIntrinsicCall(CallInst
}
}
- CI->replaceAllUsesWith(Rep);
+ if (Rep)
+ CI->replaceAllUsesWith(Rep);
CI->eraseFromParent();
return;
}
Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=265851&r1=265850&r2=265851&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp Fri Apr 8 16:26:31 2016
@@ -10212,9 +10212,9 @@ bool AArch64TargetLowering::shouldNormal
return false;
}
-Value *AArch64TargetLowering::getStackCookieLocation(IRBuilder<> &IRB) const {
+Value *AArch64TargetLowering::getIRStackGuard(IRBuilder<> &IRB) const {
if (!Subtarget->isTargetAndroid())
- return TargetLowering::getStackCookieLocation(IRB);
+ return TargetLowering::getIRStackGuard(IRB);
// Android provides a fixed TLS slot for the stack cookie. See the definition
// of TLS_SLOT_STACK_GUARD in
Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h?rev=265851&r1=265850&r2=265851&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.h Fri Apr 8 16:26:31 2016
@@ -360,7 +360,7 @@ public:
/// 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;
+ Value *getIRStackGuard(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.
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=265851&r1=265850&r2=265851&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Apr 8 16:26:31 2016
@@ -2193,9 +2193,9 @@ unsigned X86TargetLowering::getAddressSp
return 256;
}
-Value *X86TargetLowering::getStackCookieLocation(IRBuilder<> &IRB) const {
+Value *X86TargetLowering::getIRStackGuard(IRBuilder<> &IRB) const {
if (!Subtarget.isTargetLinux())
- return TargetLowering::getStackCookieLocation(IRB);
+ return TargetLowering::getIRStackGuard(IRB);
// %fs:0x28, unless we're using a Kernel code model, in which case it's %gs:
// %gs:0x14 on i386
@@ -2206,6 +2206,19 @@ Value *X86TargetLowering::getStackCookie
Type::getInt8PtrTy(IRB.getContext())->getPointerTo(AddressSpace));
}
+void X86TargetLowering::insertSSPDeclarations(Module &M) const {
+ if (!Subtarget.isTargetLinux())
+ TargetLowering::insertSSPDeclarations(M);
+ else
+ llvm_unreachable("X86 Linux supports customized IR stack guard load");
+}
+
+Value *X86TargetLowering::getSDStackGuard(const Module &M) const {
+ if (!Subtarget.isTargetLinux())
+ return TargetLowering::getSDStackGuard(M);
+ llvm_unreachable("X86 Linux supports customized IR stack guard load");
+}
+
Value *X86TargetLowering::getSafeStackPointerLocation(IRBuilder<> &IRB) const {
if (!Subtarget.isTargetAndroid())
return TargetLowering::getSafeStackPointerLocation(IRB);
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=265851&r1=265850&r2=265851&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Fri Apr 8 16:26:31 2016
@@ -962,7 +962,11 @@ namespace llvm {
/// 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;
+ Value *getIRStackGuard(IRBuilder<> &IRB) const override;
+
+ void insertSSPDeclarations(Module &M) const override;
+
+ Value *getSDStackGuard(const Module &M) 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
Modified: llvm/trunk/test/Assembler/auto_upgrade_intrinsics.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/auto_upgrade_intrinsics.ll?rev=265851&r1=265850&r2=265851&view=diff
==============================================================================
--- llvm/trunk/test/Assembler/auto_upgrade_intrinsics.ll (original)
+++ llvm/trunk/test/Assembler/auto_upgrade_intrinsics.ll Fri Apr 8 16:26:31 2016
@@ -54,7 +54,20 @@ entry:
define i32 @test.objectsize() {
; CHECK-LABEL: @test.objectsize(
; CHECK: @llvm.objectsize.i32.p0i8
-; CHECK-DAG: declare i32 @llvm.objectsize.i32.p0i8
%s = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false)
ret i32 %s
}
+
+ at __stack_chk_guard = external global i8*
+declare void @llvm.stackprotectorcheck(i8**)
+
+define void @test.stackprotectorcheck() {
+; CHECK-LABEL: @test.stackprotectorcheck(
+; CHECK-NEXT: ret void
+ call void @llvm.stackprotectorcheck(i8** @__stack_chk_guard)
+ ret void
+}
+
+; This is part of @test.objectsize(), since llvm.objectsize declaration gets
+; emitted at the end.
+; CHECK: declare i32 @llvm.objectsize.i32.p0i8
More information about the llvm-commits
mailing list