diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -11320,11 +11320,13 @@ This instruction requires several arguments: -#. The optional ``tail`` and ``musttail`` markers indicate that the optimizers - should perform tail call optimization. The ``tail`` marker is a hint that - `can be ignored `_. The ``musttail`` marker - means that the call must be tail call optimized in order for the program to - be correct. The ``musttail`` marker provides these guarantees: +#. The optional ``tail`` and ``musttail`` markers (with one exception for + mandatory ``musttail`` when using ``swifttailcc``, see below) indicate that + the optimizers should perform tail call optimization. The ``tail`` marker is + a hint that `can be ignored `_. The + ``musttail`` marker means that the call must be tail call optimized in + order for the program to be correct. The ``musttail`` marker provides + these guarantees: #. The call will not cause unbounded stack growth if it is part of a recursive cycle in the call graph. @@ -11354,6 +11356,9 @@ - The callee must be varargs iff the caller is varargs. Bitcasting a non-varargs function to the appropriate varargs type is legal so long as the non-varargs prefixes obey the other rules. + - ``musttail`` is mandatory for calls where both the caller and + the callee use the ``swifttailcc`` convention, and the call is + immediately followed by ``ret``. Tail call optimization for calls marked ``tail`` is guaranteed to occur if the following conditions are met: diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -3419,7 +3419,26 @@ return Copy; } +// FIXME: This flag should eventually be removed and the check should be on by +// default. +static cl::opt DisableSwiftTailCCMustTailCheck( + "disable-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 (!DisableSwiftTailCCMustTailCheck && + CI.getCallingConv() == CallingConv::SwiftTail && + CI.getCaller()->getCallingConv() == CallingConv::SwiftTail && + isa_and_nonnull(CI.getNextNode())) { + Assert(false, + "tail call from swifttail->swifttail should be marked musttail", + &CI); + } + return; + } + Assert(!CI.isInlineAsm(), "cannot use musttail call with inline asm", &CI); // - The caller and callee prototypes must match. Pointer types of @@ -3485,9 +3504,7 @@ void Verifier::visitCallInst(CallInst &CI) { visitCallBase(CI); - - if (CI.isMustTailCall()) - verifyMustTailCall(CI); + verifyMustTailCall(CI); } void Verifier::visitInvokeInst(InvokeInst &II) { diff --git a/llvm/test/Verifier/musttail-missing.ll b/llvm/test/Verifier/musttail-missing.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Verifier/musttail-missing.ll @@ -0,0 +1,9 @@ +; RUN: llvm-as %s -disable-swifttailcc-musttail-check -o /dev/null +; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s + +declare swifttailcc void @swift_callee() +define swifttailcc void @swift_caller() { +; CHECK: tail call from swifttail->swifttail should be marked musttail + call swifttailcc void @swift_callee() + ret void +}