aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/StackProtector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/StackProtector.cpp')
-rw-r--r--llvm/lib/CodeGen/StackProtector.cpp24
1 files changed, 20 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp
index 7a3688b..ff6ff6d 100644
--- a/llvm/lib/CodeGen/StackProtector.cpp
+++ b/llvm/lib/CodeGen/StackProtector.cpp
@@ -471,21 +471,36 @@ bool StackProtector::InsertStackProtectors() {
// instrumentation has already been generated.
HasIRCheck = true;
+ // If we're instrumenting a block with a musttail call, the check has to be
+ // inserted before the call rather than between it and the return. The
+ // verifier guarantees that a musttail call is either directly before the
+ // return or with a single correct bitcast of the return value in between so
+ // we don't need to worry about many situations here.
+ Instruction *CheckLoc = RI;
+ Instruction *Prev = RI->getPrevNonDebugInstruction();
+ if (Prev && isa<CallInst>(Prev) && cast<CallInst>(Prev)->isMustTailCall())
+ CheckLoc = Prev;
+ else if (Prev) {
+ Prev = Prev->getPrevNonDebugInstruction();
+ if (Prev && isa<CallInst>(Prev) && cast<CallInst>(Prev)->isMustTailCall())
+ CheckLoc = Prev;
+ }
+
// Generate epilogue instrumentation. The epilogue intrumentation can be
// function-based or inlined depending on which mechanism the target is
// providing.
if (Function *GuardCheck = TLI->getSSPStackGuardCheck(*M)) {
// Generate the function-based epilogue instrumentation.
// The target provides a guard check function, generate a call to it.
- IRBuilder<> B(RI);
+ IRBuilder<> B(CheckLoc);
LoadInst *Guard = B.CreateLoad(B.getInt8PtrTy(), AI, true, "Guard");
CallInst *Call = B.CreateCall(GuardCheck, {Guard});
Call->setAttributes(GuardCheck->getAttributes());
Call->setCallingConv(GuardCheck->getCallingConv());
} else {
// Generate the epilogue with inline instrumentation.
- // If we do not support SelectionDAG based tail calls, generate IR level
- // tail calls.
+ // If we do not support SelectionDAG based calls, generate IR level
+ // calls.
//
// For each block with a return instruction, convert this:
//
@@ -515,7 +530,8 @@ bool StackProtector::InsertStackProtectors() {
BasicBlock *FailBB = CreateFailBB();
// Split the basic block before the return instruction.
- BasicBlock *NewBB = BB->splitBasicBlock(RI->getIterator(), "SP_return");
+ BasicBlock *NewBB =
+ BB->splitBasicBlock(CheckLoc->getIterator(), "SP_return");
// Update the dominator tree if we need to.
if (DT && DT->isReachableFromEntry(BB)) {