Index: include/clang/Basic/Attr.td =================================================================== --- include/clang/Basic/Attr.td +++ include/clang/Basic/Attr.td @@ -891,6 +891,12 @@ let Documentation = [Undocumented]; } +def DisableTailCalls : InheritableAttr { + let Spellings = [GNU<"disable_tail_calls">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [Undocumented]; +} + def NoAlias : InheritableAttr { let Spellings = [Declspec<"noalias">]; let Subjects = SubjectList<[Function]>; Index: lib/CodeGen/CGCall.cpp =================================================================== --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -1474,8 +1474,12 @@ FuncAttrs.addAttribute("no-frame-pointer-elim-non-leaf"); } - FuncAttrs.addAttribute("disable-tail-calls", - llvm::toStringRef(CodeGenOpts.DisableTailCalls)); + if ((TargetDecl && TargetDecl->hasAttr()) || + CodeGenOpts.DisableTailCalls) + FuncAttrs.addAttribute("disable-tail-calls", "true"); + else + FuncAttrs.addAttribute("disable-tail-calls", "false"); + FuncAttrs.addAttribute("less-precise-fpmad", llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD)); FuncAttrs.addAttribute("no-infs-fp-math", Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -4878,6 +4878,9 @@ case AttributeList::AT_ReturnsTwice: handleSimpleAttribute(S, D, Attr); break; + case AttributeList::AT_DisableTailCalls: + handleSimpleAttribute(S, D, Attr); + break; case AttributeList::AT_Used: handleUsedAttr(S, D, Attr); break; Index: test/CodeGen/attr-disable-tail-calls.c =================================================================== --- test/CodeGen/attr-disable-tail-calls.c +++ test/CodeGen/attr-disable-tail-calls.c @@ -1,11 +1,19 @@ -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7.0 %s -emit-llvm -mdisable-tail-calls -o - | FileCheck %s -check-prefix=CHECK -check-prefix=DISABLE -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7.0 %s -emit-llvm -o - | FileCheck %s -check-prefix=CHECK -check-prefix=ENABLE +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7.0 %s -emit-llvm -mdisable-tail-calls -o - | FileCheck %s -check-prefix=DISABLE +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7.0 %s -emit-llvm -o - | FileCheck %s -check-prefix=ENABLE -// CHECK: define i32 @f1() [[ATTR:#[0-9]+]] { +// DISABLE: define i32 @f1() [[ATTRTRUE:#[0-9]+]] { +// DISABLE: define i32 @f2() [[ATTRTRUE]] { +// ENABLE: define i32 @f1() [[ATTRFALSE:#[0-9]+]] { +// ENABLE: define i32 @f2() [[ATTRTRUE:#[0-9]+]] { int f1() { return 0; } -// DISABLE: attributes [[ATTR]] = { {{.*}} "disable-tail-calls"="true" {{.*}} } -// ENABLE: attributes [[ATTR]] = { {{.*}} "disable-tail-calls"="false" {{.*}} } +int f2() __attribute__((disable_tail_calls)) { + return 0; +} + +// DISABLE: attributes [[ATTRTRUE]] = { {{.*}} "disable-tail-calls"="true" {{.*}} } +// ENABLE: attributes [[ATTRFALSE]] = { {{.*}} "disable-tail-calls"="false" {{.*}} } +// ENABLE: attributes [[ATTRTRUE]] = { {{.*}} "disable-tail-calls"="true" {{.*}} }