diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp index e823df3186a54..eb07e5d2bae4b 100644 --- a/llvm/lib/CodeGen/StackProtector.cpp +++ b/llvm/lib/CodeGen/StackProtector.cpp @@ -20,6 +20,7 @@ #include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/MemoryLocation.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" +#include "llvm/CodeGen/Analysis.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/TargetLowering.h" #include "llvm/CodeGen/TargetPassConfig.h" @@ -625,18 +626,11 @@ bool InsertStackProtectors(const TargetMachine *TM, Function *F, HasIRCheck = true; // If we're instrumenting a block with a tail call, the check has to be - // inserted before the call rather than between it and the return. The - // verifier guarantees that a tail 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. + // inserted before the call rather than between it and the return. Instruction *Prev = CheckLoc->getPrevNonDebugInstruction(); - if (Prev && isa(Prev) && cast(Prev)->isTailCall()) - CheckLoc = Prev; - else if (Prev) { - Prev = Prev->getPrevNonDebugInstruction(); - if (Prev && isa(Prev) && cast(Prev)->isTailCall()) + if (auto *CI = dyn_cast_if_present(Prev)) + if (CI->isTailCall() && isInTailCallPosition(*CI, *TM)) CheckLoc = Prev; - } // Generate epilogue instrumentation. The epilogue intrumentation can be // function-based or inlined depending on which mechanism the target is diff --git a/llvm/test/CodeGen/X86/tailcc-ssp.ll b/llvm/test/CodeGen/X86/tailcc-ssp.ll index 914af1466147a..5211e4fe9eef9 100644 --- a/llvm/test/CodeGen/X86/tailcc-ssp.ll +++ b/llvm/test/CodeGen/X86/tailcc-ssp.ll @@ -101,3 +101,24 @@ define void @tailcall_unrelated_frame() sspreq { tail call void @bar() ret void } + +declare void @callee() +define void @caller() sspreq { +; WINDOWS-LABEL: caller: +; WINDOWS: callq callee +; WINDOWS: callq callee +; WINDOWS: cmpq __security_cookie(%rip), %rcx +; WINDOWS: jne +; WINDOWS: callq __security_check_cookie + +; LINUX-LABEL: caller: +; LINUX: callq callee@PLT +; LINUX: callq callee@PLT +; LINUX: cmpq +; LINUX: jne +; LINUX: callq __stack_chk_fail@PLT + + tail call void @callee() + call void @callee() + ret void +}