From 285737e76637bb274ec8fafc2b978fb3ccec6fe0 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Tue, 30 Mar 2021 15:03:16 -0700 Subject: [PATCH 1/2] Use musttail in MergeFunctions for swiftasync->swiftasync tail calls. Fixes rdar://76024125. --- llvm/lib/Transforms/IPO/MergeFunctions.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/IPO/MergeFunctions.cpp b/llvm/lib/Transforms/IPO/MergeFunctions.cpp index ec5d86b72a1f9..dbbceb6f8d811 100644 --- a/llvm/lib/Transforms/IPO/MergeFunctions.cpp +++ b/llvm/lib/Transforms/IPO/MergeFunctions.cpp @@ -713,7 +713,11 @@ void MergeFunctions::writeThunk(Function *F, Function *G) { CallInst *CI = Builder.CreateCall(F, Args); ReturnInst *RI = nullptr; - CI->setTailCall(); + bool isSwiftTailCall = + F->getCallingConv() == CallingConv::SwiftTail && + G->getCallingConv() == CallingConv::SwiftTail; + CI->setTailCallKind( + isSwiftTailCall ? llvm::CallInst::TCK_MustTail : llvm::CallInst::TCK_Tail); CI->setCallingConv(F->getCallingConv()); CI->setAttributes(F->getAttributes()); if (H->getReturnType()->isVoidTy()) { From f652e1bfd6a6f031e282fa4796ef6c6e8be94270 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Tue, 30 Mar 2021 15:15:47 -0700 Subject: [PATCH 2/2] Update musttail verification to check all swiftasync->swiftasync tail calls. When -enable-swifttailcc-musttail-check is passed (off by default), we will check that all swiftasync->swiftasync tail calls are marked musttail. Fixes rdar://75899279. --- llvm/lib/IR/Verifier.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index ffec3562371d3..a6cdd65ecf674 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -3316,7 +3316,24 @@ static AttrBuilder getParameterABIAttributes(int I, AttributeList Attrs) { return Copy; } +static cl::opt +EnableSwiftTailCCMustTailCheck("enable-swifttailcc-musttail-check", +cl::init(false), cl::desc("Check that tail calls from swifttailcc functions to" + " swifttailcc functions are marked musttail.")); + void Verifier::verifyMustTailCall(CallInst &CI) { + if (!CI.isMustTailCall()) { + if (EnableSwiftTailCCMustTailCheck && + CI.getCallingConv() == CallingConv::SwiftTail && + CI.getCaller()->getCallingConv() == CallingConv::SwiftTail && + isa_and_nonnull(CI.getNextNode())) { + Assert( + false, "tail call from swifttail->swiftail should be marked musttail", + &CI); + } + return; + } + Assert(!CI.isInlineAsm(), "cannot use musttail call with inline asm", &CI); Function *F = CI.getParent()->getParent(); @@ -3401,9 +3418,7 @@ void Verifier::verifyMustTailCall(CallInst &CI) { void Verifier::visitCallInst(CallInst &CI) { visitCallBase(CI); - - if (CI.isMustTailCall()) - verifyMustTailCall(CI); + verifyMustTailCall(CI); } void Verifier::visitInvokeInst(InvokeInst &II) {