diff options
author | Petr Pavlu <petr.pavlu@arm.com> | 2018-11-29 13:22:53 +0000 |
---|---|---|
committer | Petr Pavlu <petr.pavlu@arm.com> | 2018-11-29 13:22:53 +0000 |
commit | 6bb80512db29c02ea149f63512d05be0939aaae7 (patch) | |
tree | d60751159856f0c12f0cc6dbd4283f0f2e7abe15 /llvm/lib/CodeGen/StackProtector.cpp | |
parent | e6406d568c550dc27999d96d174f8fe354ab545a (diff) | |
download | bcm5719-llvm-6bb80512db29c02ea149f63512d05be0939aaae7.tar.gz bcm5719-llvm-6bb80512db29c02ea149f63512d05be0939aaae7.zip |
[GlobalISel] Fix insertion of stack-protector epilogue
* Tell the StackProtector pass to generate the epilogue instrumentation
when GlobalISel is enabled because GISel currently does not implement
the same deferred epilogue insertion as SelectionDAG.
* Update StackProtector::InsertStackProtectors() to find a stack guard
slot by searching for the llvm.stackprotector intrinsic when the
prologue was not created by StackProtector itself but the pass still
needs to generate the epilogue instrumentation. This fixes a problem
when the pass would abort because the stack guard AllocInst pointer
was null when generating the epilogue -- test
CodeGen/AArch64/GlobalISel/arm64-irtranslator-stackprotect.ll.
Differential Revision: https://reviews.llvm.org/D54518
llvm-svn: 347862
Diffstat (limited to 'llvm/lib/CodeGen/StackProtector.cpp')
-rw-r--r-- | llvm/lib/CodeGen/StackProtector.cpp | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp index cb12c7ce6e8..dcf37ca76b2 100644 --- a/llvm/lib/CodeGen/StackProtector.cpp +++ b/llvm/lib/CodeGen/StackProtector.cpp @@ -199,6 +199,18 @@ bool StackProtector::HasAddressTaken(const Instruction *AI) { return false; } +/// Search for the first call to the llvm.stackprotector intrinsic and return it +/// if present. +static const CallInst *findStackProtectorIntrinsic(Function &F) { + 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)) + return CI; + return nullptr; +} + /// Check whether or not this function needs a stack protector based /// upon the stack protector level. /// @@ -215,13 +227,7 @@ bool StackProtector::HasAddressTaken(const Instruction *AI) { 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; + HasPrologue = findStackProtectorIntrinsic(*F); if (F->hasFnAttribute(Attribute::SafeStack)) return false; @@ -379,7 +385,8 @@ bool StackProtector::InsertStackProtectors() { // protection in SDAG. bool SupportsSelectionDAGSP = TLI->useStackGuardXorFP() || - (EnableSelectionDAGSP && !TM->Options.EnableFastISel); + (EnableSelectionDAGSP && !TM->Options.EnableFastISel && + !TM->Options.EnableGlobalISel); AllocaInst *AI = nullptr; // Place on stack that stores the stack guard. for (Function::iterator I = F->begin(), E = F->end(); I != E;) { @@ -399,6 +406,14 @@ bool StackProtector::InsertStackProtectors() { if (SupportsSelectionDAGSP) break; + // Find the stack guard slot if the prologue was not created by this pass + // itself via a previous call to CreatePrologue(). + if (!AI) { + const CallInst *SPCall = findStackProtectorIntrinsic(*F); + assert(SPCall && "Call to llvm.stackprotector is missing"); + AI = cast<AllocaInst>(SPCall->getArgOperand(1)); + } + // Set HasIRCheck to true, so that SelectionDAG will not generate its own // version. SelectionDAG called 'shouldEmitSDCheck' to check whether // instrumentation has already been generated. |