summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/StackProtector.cpp
diff options
context:
space:
mode:
authorPetr Pavlu <petr.pavlu@arm.com>2018-11-29 13:22:53 +0000
committerPetr Pavlu <petr.pavlu@arm.com>2018-11-29 13:22:53 +0000
commit6bb80512db29c02ea149f63512d05be0939aaae7 (patch)
treed60751159856f0c12f0cc6dbd4283f0f2e7abe15 /llvm/lib/CodeGen/StackProtector.cpp
parente6406d568c550dc27999d96d174f8fe354ab545a (diff)
downloadbcm5719-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.cpp31
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.
OpenPOWER on IntegriCloud