diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -11657,7 +11657,8 @@ 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: + be correct. This is true even in the presence of attributes like + "disable-tail-calls". 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. diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1139,9 +1139,8 @@ bool IsTailCall = CI->isTailCall(); if (IsTailCall && !isInTailCallPosition(*CI, TM)) IsTailCall = false; - if (IsTailCall && MF->getFunction() - .getFnAttribute("disable-tail-calls") - .getValueAsBool()) + if (IsTailCall && !CI->isMustTailCall() && + MF->getFunction().getFnAttribute("disable-tail-calls").getValueAsBool()) IsTailCall = false; CallLoweringInfo CLI; diff --git a/llvm/test/CodeGen/X86/fast-isel-disable-tail-calls.ll b/llvm/test/CodeGen/X86/fast-isel-disable-tail-calls.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/fast-isel-disable-tail-calls.ll @@ -0,0 +1,9 @@ +; RUN: llc -O0 -fast-isel -mtriple=x86_64-unknown-unknown < %s | FileCheck %s + +; CHECK-NOT: retq +; CHECK: jmpq + +define void @f(ptr %this) "disable-tail-calls"="true" { + musttail call void %this(ptr %this) + ret void +}