<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">The commit msg here got cut off. It should have been:<div><br></div><div>The builtin attribute is an attribute that can be placed on a call site for a function with the nobuiltin attribute which overrides the nobuiltin attribute.</div><div><br></div><div>Sorry,</div><div>Michael</div><div><br><div><div>On Jun 26, 2013, at 5:25 PM, Michael Gottesman <<a href="mailto:mgottesman@apple.com">mgottesman@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">Author: mgottesman<br>Date: Wed Jun 26 19:25:01 2013<br>New Revision: 185049<br><br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project?rev=185049&view=rev">http://llvm.org/viewvc/llvm-project?rev=185049&view=rev</a><br>Log:<br>Added support for the Builtin attribute.<br><br>The Builtin attribute is an attribute that can be placed on function call site that signal that even though a function is declared as being a builtin,<br><br><a href="rdar://problem/13727199">rdar://problem/13727199</a><br><br>Added:<br>   llvm/trunk/test/Assembler/attribute-builtin.ll<br>Modified:<br>   llvm/trunk/docs/LangRef.rst<br>   llvm/trunk/include/llvm/IR/Attributes.h<br>   llvm/trunk/include/llvm/IR/Instructions.h<br>   llvm/trunk/include/llvm/Support/CallSite.h<br>   llvm/trunk/lib/Analysis/MemoryBuiltins.cpp<br>   llvm/trunk/lib/AsmParser/LLLexer.cpp<br>   llvm/trunk/lib/AsmParser/LLParser.cpp<br>   llvm/trunk/lib/AsmParser/LLParser.h<br>   llvm/trunk/lib/AsmParser/LLToken.h<br>   llvm/trunk/lib/IR/Attributes.cpp<br>   llvm/trunk/lib/IR/Instructions.cpp<br>   llvm/trunk/lib/IR/Verifier.cpp<br>   llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp<br>   llvm/trunk/test/Transforms/InstCombine/simplify-libcalls.ll<br><br>Modified: llvm/trunk/docs/LangRef.rst<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=185049&r1=185048&r2=185049&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=185049&r1=185048&r2=185049&view=diff</a><br>==============================================================================<br>--- llvm/trunk/docs/LangRef.rst (original)<br>+++ llvm/trunk/docs/LangRef.rst Wed Jun 26 19:25:01 2013<br>@@ -822,6 +822,12 @@ example:<br>    computing edge weights, basic blocks post-dominated by a cold<br>    function call are also considered to be cold; and, thus, given low<br>    weight.<br>+``builtin``<br>+    This indicates that the callee function at a call site should be<br>+    recognized as a built-in function, even though the function's declaration<br>+    uses the ``nobuiltin'' attribute. This is only valid at call sites for<br>+    direct calls to functions which are declared with the ``nobuiltin``<br>+    attribute.<br>``nonlazybind``<br>    This attribute suppresses lazy symbol binding for the function. This<br>    may make calls to the function faster, at the cost of extra program<br>@@ -835,11 +841,11 @@ example:<br>    This attribute disables prologue / epilogue emission for the<br>    function. This can have very system-specific consequences.<br>``nobuiltin``<br>-    This indicates that the callee function at a call site is not<br>-    recognized as a built-in function. LLVM will retain the original call<br>-    and not replace it with equivalent code based on the semantics of the<br>-    built-in function. This is only valid at call sites, not on function<br>-    declarations or definitions.<br>+    This indicates that the callee function at a call site is not recognized as<br>+    a built-in function. LLVM will retain the original call and not replace it<br>+    with equivalent code based on the semantics of the built-in function, unless<br>+    the call site uses the ``builtin`` attribute. This is valid at call sites<br>+    and on function declarations and definitions.<br>``noduplicate``<br>    This attribute indicates that calls to the function cannot be<br>    duplicated. A call to a ``noduplicate`` function may be moved<br><br>Modified: llvm/trunk/include/llvm/IR/Attributes.h<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Attributes.h?rev=185049&r1=185048&r2=185049&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Attributes.h?rev=185049&r1=185048&r2=185049&view=diff</a><br>==============================================================================<br>--- llvm/trunk/include/llvm/IR/Attributes.h (original)<br>+++ llvm/trunk/include/llvm/IR/Attributes.h Wed Jun 26 19:25:01 2013<br>@@ -67,6 +67,8 @@ public:<br>                           ///< stored as log2 of alignment with +1 bias<br>                           ///< 0 means unaligned (different from align(1))<br>    AlwaysInline,          ///< inline=always<br>+    Builtin,               ///< Callee is recognized as a builtin, despite<br>+                           ///< nobuiltin attribute on its declaration.<br>    ByVal,                 ///< Pass structure by value<br>    Cold,                  ///< Marks function as being in a cold path.<br>    InlineHint,            ///< Source said inlining was desirable<br><br>Modified: llvm/trunk/include/llvm/IR/Instructions.h<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Instructions.h?rev=185049&r1=185048&r2=185049&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Instructions.h?rev=185049&r1=185048&r2=185049&view=diff</a><br>==============================================================================<br>--- llvm/trunk/include/llvm/IR/Instructions.h (original)<br>+++ llvm/trunk/include/llvm/IR/Instructions.h Wed Jun 26 19:25:01 2013<br>@@ -1278,7 +1278,11 @@ public:<br>  void removeAttribute(unsigned i, Attribute attr);<br><br>  /// \brief Determine whether this call has the given attribute.<br>-  bool hasFnAttr(Attribute::AttrKind A) const;<br>+  bool hasFnAttr(Attribute::AttrKind A) const {<br>+    assert(A != Attribute::NoBuiltin &&<br>+           "Use CallInst::isNoBuiltin() to check for Attribute::NoBuiltin");<br>+    return hasFnAttrImpl(A);<br>+  }<br><br>  /// \brief Determine whether the call or the callee has the given attributes.<br>  bool paramHasAttr(unsigned i, Attribute::AttrKind A) const;<br>@@ -1288,6 +1292,13 @@ public:<br>    return AttributeList.getParamAlignment(i);<br>  }<br><br>+  /// \brief Return true if the call should not be treated as a call to a<br>+  /// builtin.<br>+  bool isNoBuiltin() const {<br>+    return hasFnAttrImpl(Attribute::NoBuiltin) &&<br>+      !hasFnAttrImpl(Attribute::Builtin);<br>+  }<br>+<br>  /// \brief Return true if the call should not be inlined.<br>  bool isNoInline() const { return hasFnAttr(Attribute::NoInline); }<br>  void setIsNoInline() {<br>@@ -1378,6 +1389,9 @@ public:<br>    return isa<Instruction>(V) && classof(cast<Instruction>(V));<br>  }<br>private:<br>+<br>+  bool hasFnAttrImpl(Attribute::AttrKind A) const;<br>+<br>  // Shadow Instruction::setInstructionSubclassData with a private forwarding<br>  // method so that subclasses cannot accidentally use it.<br>  void setInstructionSubclassData(unsigned short D) {<br>@@ -3021,7 +3035,11 @@ public:<br>  void removeAttribute(unsigned i, Attribute attr);<br><br>  /// \brief Determine whether this call has the NoAlias attribute.<br>-  bool hasFnAttr(Attribute::AttrKind A) const;<br>+  bool hasFnAttr(Attribute::AttrKind A) const {<br>+    assert(A != Attribute::NoBuiltin &&<br>+           "Use CallInst::isNoBuiltin() to check for Attribute::NoBuiltin");<br>+    return hasFnAttrImpl(A);<br>+  }<br><br>  /// \brief Determine whether the call or the callee has the given attributes.<br>  bool paramHasAttr(unsigned i, Attribute::AttrKind A) const;<br>@@ -3031,6 +3049,15 @@ public:<br>    return AttributeList.getParamAlignment(i);<br>  }<br><br>+  /// \brief Return true if the call should not be treated as a call to a<br>+  /// builtin.<br>+  bool isNoBuiltin() const {<br>+    // We assert in hasFnAttr if one passes in Attribute::NoBuiltin, so we have<br>+    // to check it by hand.<br>+    return hasFnAttrImpl(Attribute::NoBuiltin) &&<br>+      !hasFnAttrImpl(Attribute::Builtin);<br>+  }<br>+<br>  /// \brief Return true if the call should not be inlined.<br>  bool isNoInline() const { return hasFnAttr(Attribute::NoInline); }<br>  void setIsNoInline() {<br>@@ -3137,6 +3164,8 @@ private:<br>  virtual unsigned getNumSuccessorsV() const;<br>  virtual void setSuccessorV(unsigned idx, BasicBlock *B);<br><br>+  bool hasFnAttrImpl(Attribute::AttrKind A) const;<br>+<br>  // Shadow Instruction::setInstructionSubclassData with a private forwarding<br>  // method so that subclasses cannot accidentally use it.<br>  void setInstructionSubclassData(unsigned short D) {<br><br>Modified: llvm/trunk/include/llvm/Support/CallSite.h<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CallSite.h?rev=185049&r1=185048&r2=185049&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CallSite.h?rev=185049&r1=185048&r2=185049&view=diff</a><br>==============================================================================<br>--- llvm/trunk/include/llvm/Support/CallSite.h (original)<br>+++ llvm/trunk/include/llvm/Support/CallSite.h Wed Jun 26 19:25:01 2013<br>@@ -198,6 +198,12 @@ public:<br>    CALLSITE_DELEGATE_GETTER(getParamAlignment(i));<br>  }<br><br>+  /// \brief Return true if the call should not be treated as a call to a<br>+  /// builtin.<br>+  bool isNoBuiltin() const {<br>+    CALLSITE_DELEGATE_GETTER(isNoBuiltin());<br>+  }<br>+<br>  /// @brief Return true if the call should not be inlined.<br>  bool isNoInline() const {<br>    CALLSITE_DELEGATE_GETTER(isNoInline());<br><br>Modified: llvm/trunk/lib/Analysis/MemoryBuiltins.cpp<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryBuiltins.cpp?rev=185049&r1=185048&r2=185049&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryBuiltins.cpp?rev=185049&r1=185048&r2=185049&view=diff</a><br>==============================================================================<br>--- llvm/trunk/lib/Analysis/MemoryBuiltins.cpp (original)<br>+++ llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Wed Jun 26 19:25:01 2013<br>@@ -77,7 +77,7 @@ static Function *getCalledFunction(const<br>  if (!CS.getInstruction())<br>    return 0;<br><br>-  if (CS.hasFnAttr(Attribute::NoBuiltin))<br>+  if (CS.isNoBuiltin())<br>    return 0;<br><br>  Function *Callee = CS.getCalledFunction();<br><br>Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=185049&r1=185048&r2=185049&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=185049&r1=185048&r2=185049&view=diff</a><br>==============================================================================<br>--- llvm/trunk/lib/AsmParser/LLLexer.cpp (original)<br>+++ llvm/trunk/lib/AsmParser/LLLexer.cpp Wed Jun 26 19:25:01 2013<br>@@ -563,6 +563,7 @@ lltok::Kind LLLexer::LexIdentifier() {<br>  KEYWORD(attributes);<br><br>  KEYWORD(alwaysinline);<br>+  KEYWORD(builtin);<br>  KEYWORD(byval);<br>  KEYWORD(cold);<br>  KEYWORD(inlinehint);<br><br>Modified: llvm/trunk/lib/AsmParser/LLParser.cpp<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=185049&r1=185048&r2=185049&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=185049&r1=185048&r2=185049&view=diff</a><br>==============================================================================<br>--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)<br>+++ llvm/trunk/lib/AsmParser/LLParser.cpp Wed Jun 26 19:25:01 2013<br>@@ -810,13 +810,13 @@ bool LLParser::ParseUnnamedAttrGrp() {<br>  assert(Lex.getKind() == lltok::AttrGrpID);<br>  unsigned VarID = Lex.getUIntVal();<br>  std::vector<unsigned> unused;<br>-  LocTy NoBuiltinLoc;<br>+  LocTy BuiltinLoc;<br>  Lex.Lex();<br><br>  if (ParseToken(lltok::equal, "expected '=' here") ||<br>      ParseToken(lltok::lbrace, "expected '{' here") ||<br>      ParseFnAttributeValuePairs(NumberedAttrBuilders[VarID], unused, true,<br>-                                 NoBuiltinLoc) ||<br>+                                 BuiltinLoc) ||<br>      ParseToken(lltok::rbrace, "expected end of attribute group"))<br>    return true;<br><br>@@ -830,15 +830,15 @@ bool LLParser::ParseUnnamedAttrGrp() {<br>///   ::= <attr> | <attr> '=' <value><br>bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,<br>                                          std::vector<unsigned> &FwdRefAttrGrps,<br>-                                          bool inAttrGrp, LocTy &NoBuiltinLoc) {<br>+                                          bool inAttrGrp, LocTy &BuiltinLoc) {<br>  bool HaveError = false;<br><br>  B.clear();<br><br>  while (true) {<br>    lltok::Kind Token = Lex.getKind();<br>-    if (Token == lltok::kw_nobuiltin)<br>-      NoBuiltinLoc = Lex.getLoc();<br>+    if (Token == lltok::kw_builtin)<br>+      BuiltinLoc = Lex.getLoc();<br>    switch (Token) {<br>    default:<br>      if (!inAttrGrp) return HaveError;<br>@@ -909,6 +909,7 @@ bool LLParser::ParseFnAttributeValuePair<br>      continue;<br>    }<br>    case lltok::kw_alwaysinline:      B.addAttribute(Attribute::AlwaysInline); break;<br>+    case lltok::kw_builtin:           B.addAttribute(Attribute::Builtin); break;<br>    case lltok::kw_cold:              B.addAttribute(Attribute::Cold); break;<br>    case lltok::kw_inlinehint:        B.addAttribute(Attribute::InlineHint); break;<br>    case lltok::kw_minsize:           B.addAttribute(Attribute::MinSize); break;<br>@@ -1165,6 +1166,7 @@ bool LLParser::ParseOptionalParamAttrs(A<br><br>    case lltok::kw_alignstack:<br>    case lltok::kw_alwaysinline:<br>+    case lltok::kw_builtin:<br>    case lltok::kw_inlinehint:<br>    case lltok::kw_minsize:<br>    case lltok::kw_naked:<br>@@ -1223,6 +1225,7 @@ bool LLParser::ParseOptionalReturnAttrs(<br><br>    case lltok::kw_alignstack:<br>    case lltok::kw_alwaysinline:<br>+    case lltok::kw_builtin:<br>    case lltok::kw_cold:<br>    case lltok::kw_inlinehint:<br>    case lltok::kw_minsize:<br>@@ -2983,7 +2986,7 @@ bool LLParser::ParseFunctionHeader(Funct<br>  bool isVarArg;<br>  AttrBuilder FuncAttrs;<br>  std::vector<unsigned> FwdRefAttrGrps;<br>-  LocTy NoBuiltinLoc;<br>+  LocTy BuiltinLoc;<br>  std::string Section;<br>  unsigned Alignment;<br>  std::string GC;<br>@@ -2994,7 +2997,7 @@ bool LLParser::ParseFunctionHeader(Funct<br>      ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr,<br>                         &UnnamedAddrLoc) ||<br>      ParseFnAttributeValuePairs(FuncAttrs, FwdRefAttrGrps, false,<br>-                                 NoBuiltinLoc) ||<br>+                                 BuiltinLoc) ||<br>      (EatIfPresent(lltok::kw_section) &&<br>       ParseStringConstant(Section)) ||<br>      ParseOptionalAlignment(Alignment) ||<br>@@ -3002,8 +3005,8 @@ bool LLParser::ParseFunctionHeader(Funct<br>       ParseStringConstant(GC)))<br>    return true;<br><br>-  if (FuncAttrs.contains(Attribute::NoBuiltin))<br>-    return Error(NoBuiltinLoc, "'nobuiltin' attribute not valid on function");<br>+  if (FuncAttrs.contains(Attribute::Builtin))<br>+    return Error(BuiltinLoc, "'builtin' attribute not valid on function");<br><br>  // If the alignment was parsed as an attribute, move to the alignment field.<br>  if (FuncAttrs.hasAlignmentAttr()) {<br>@@ -3927,7 +3930,7 @@ bool LLParser::ParseCall(Instruction *&I<br>                         bool isTail) {<br>  AttrBuilder RetAttrs, FnAttrs;<br>  std::vector<unsigned> FwdRefAttrGrps;<br>-  LocTy NoBuiltinLoc;<br>+  LocTy BuiltinLoc;<br>  CallingConv::ID CC;<br>  Type *RetType = 0;<br>  LocTy RetTypeLoc;<br>@@ -3942,7 +3945,7 @@ bool LLParser::ParseCall(Instruction *&I<br>      ParseValID(CalleeID) ||<br>      ParseParameterList(ArgList, PFS) ||<br>      ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false,<br>-                                 NoBuiltinLoc))<br>+                                 BuiltinLoc))<br>    return true;<br><br>  // If RetType is a non-function pointer type, then this is the short syntax<br><br>Modified: llvm/trunk/lib/AsmParser/LLParser.h<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=185049&r1=185048&r2=185049&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=185049&r1=185048&r2=185049&view=diff</a><br>==============================================================================<br>--- llvm/trunk/lib/AsmParser/LLParser.h (original)<br>+++ llvm/trunk/lib/AsmParser/LLParser.h Wed Jun 26 19:25:01 2013<br>@@ -242,7 +242,7 @@ namespace llvm {<br>    bool ParseUnnamedAttrGrp();<br>    bool ParseFnAttributeValuePairs(AttrBuilder &B,<br>                                    std::vector<unsigned> &FwdRefAttrGrps,<br>-                                    bool inAttrGrp, LocTy &NoBuiltinLoc);<br>+                                    bool inAttrGrp, LocTy &BuiltinLoc);<br><br>    // Type Parsing.<br>    bool ParseType(Type *&Result, bool AllowVoid = false);<br><br>Modified: llvm/trunk/lib/AsmParser/LLToken.h<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=185049&r1=185048&r2=185049&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=185049&r1=185048&r2=185049&view=diff</a><br>==============================================================================<br>--- llvm/trunk/lib/AsmParser/LLToken.h (original)<br>+++ llvm/trunk/lib/AsmParser/LLToken.h Wed Jun 26 19:25:01 2013<br>@@ -95,6 +95,7 @@ namespace lltok {<br>    kw_attributes,<br>    kw_alwaysinline,<br>    kw_sanitize_address,<br>+    kw_builtin,<br>    kw_byval,<br>    kw_cold,<br>    kw_inlinehint,<br><br>Modified: llvm/trunk/lib/IR/Attributes.cpp<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Attributes.cpp?rev=185049&r1=185048&r2=185049&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Attributes.cpp?rev=185049&r1=185048&r2=185049&view=diff</a><br>==============================================================================<br>--- llvm/trunk/lib/IR/Attributes.cpp (original)<br>+++ llvm/trunk/lib/IR/Attributes.cpp Wed Jun 26 19:25:01 2013<br>@@ -157,6 +157,8 @@ std::string Attribute::getAsString(bool<br>    return "sanitize_address";<br>  if (hasAttribute(Attribute::AlwaysInline))<br>    return "alwaysinline";<br>+  if (hasAttribute(Attribute::Builtin))<br>+    return "builtin";<br>  if (hasAttribute(Attribute::ByVal))<br>    return "byval";<br>  if (hasAttribute(Attribute::InlineHint))<br>@@ -399,6 +401,7 @@ uint64_t AttributeImpl::getAttrMask(Attr<br>  case Attribute::NoBuiltin:       return 1ULL << 38;<br>  case Attribute::Returned:        return 1ULL << 39;<br>  case Attribute::Cold:            return 1ULL << 40;<br>+  case Attribute::Builtin:         return 1ULL << 41;<br>  }<br>  llvm_unreachable("Unsupported attribute type");<br>}<br><br>Modified: llvm/trunk/lib/IR/Instructions.cpp<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Instructions.cpp?rev=185049&r1=185048&r2=185049&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Instructions.cpp?rev=185049&r1=185048&r2=185049&view=diff</a><br>==============================================================================<br>--- llvm/trunk/lib/IR/Instructions.cpp (original)<br>+++ llvm/trunk/lib/IR/Instructions.cpp Wed Jun 26 19:25:01 2013<br>@@ -346,7 +346,7 @@ void CallInst::removeAttribute(unsigned<br>  setAttributes(PAL);<br>}<br><br>-bool CallInst::hasFnAttr(Attribute::AttrKind A) const {<br>+bool CallInst::hasFnAttrImpl(Attribute::AttrKind A) const {<br>  if (AttributeList.hasAttribute(AttributeSet::FunctionIndex, A))<br>    return true;<br>  if (const Function *F = getCalledFunction())<br>@@ -574,7 +574,7 @@ void InvokeInst::setSuccessorV(unsigned<br>  return setSuccessor(idx, B);<br>}<br><br>-bool InvokeInst::hasFnAttr(Attribute::AttrKind A) const {<br>+bool InvokeInst::hasFnAttrImpl(Attribute::AttrKind A) const {<br>  if (AttributeList.hasAttribute(AttributeSet::FunctionIndex, A))<br>    return true;<br>  if (const Function *F = getCalledFunction())<br><br>Modified: llvm/trunk/lib/IR/Verifier.cpp<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=185049&r1=185048&r2=185049&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=185049&r1=185048&r2=185049&view=diff</a><br>==============================================================================<br>--- llvm/trunk/lib/IR/Verifier.cpp (original)<br>+++ llvm/trunk/lib/IR/Verifier.cpp Wed Jun 26 19:25:01 2013<br>@@ -692,6 +692,7 @@ void Verifier::VerifyAttributeTypes(Attr<br>        I->getKindAsEnum() == Attribute::SanitizeMemory ||<br>        I->getKindAsEnum() == Attribute::MinSize ||<br>        I->getKindAsEnum() == Attribute::NoDuplicate ||<br>+        I->getKindAsEnum() == Attribute::Builtin ||<br>        I->getKindAsEnum() == Attribute::NoBuiltin ||<br>        I->getKindAsEnum() == Attribute::Cold) {<br>      if (!isFunction)<br>@@ -877,6 +878,13 @@ void Verifier::visitFunction(Function &F<br>  // Check function attributes.<br>  VerifyFunctionAttrs(FT, Attrs, &F);<br><br>+  // On function declarations/definitions, we do not support the builtin<br>+  // attribute. We do not check this in VerifyFunctionAttrs since that is<br>+  // checking for Attributes that can/can not ever be on functions.<br>+  Assert1(!Attrs.hasAttribute(AttributeSet::FunctionIndex,<br>+                              Attribute::Builtin),<br>+          "Attribute 'builtin' can only be applied to a callsite.", &F);<br>+<br>  // Check that this function meets the restrictions on this calling convention.<br>  switch (F.getCallingConv()) {<br>  default:<br>@@ -1435,6 +1443,14 @@ void Verifier::VerifyCallSite(CallSite C<br>              "Function has metadata parameter but isn't an intrinsic", I);<br>  }<br><br>+  // If the call site has the 'builtin' attribute, verify that it's applied to a<br>+  // direct call to a function with the 'nobuiltin' attribute.<br>+  if (CS.hasFnAttr(Attribute::Builtin))<br>+    Assert1(CS.getCalledFunction() &&<br>+            CS.getCalledFunction()->hasFnAttribute(Attribute::NoBuiltin),<br>+            "Attribute 'builtin' can only be used in a call to a function with "<br>+            "the 'nobuiltin' attribute.", I);<br>+<br>  visitInstruction(*I);<br>}<br><br><br>Modified: llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp?rev=185049&r1=185048&r2=185049&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp?rev=185049&r1=185048&r2=185049&view=diff</a><br>==============================================================================<br>--- llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp (original)<br>+++ llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp Wed Jun 26 19:25:01 2013<br>@@ -1940,7 +1940,7 @@ LibCallSimplifier::~LibCallSimplifier()<br>}<br><br>Value *LibCallSimplifier::optimizeCall(CallInst *CI) {<br>-  if (CI->hasFnAttr(Attribute::NoBuiltin)) return 0;<br>+  if (CI->isNoBuiltin()) return 0;<br>  return Impl->optimizeCall(CI);<br>}<br><br><br>Added: llvm/trunk/test/Assembler/attribute-builtin.ll<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/attribute-builtin.ll?rev=185049&view=auto">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/attribute-builtin.ll?rev=185049&view=auto</a><br>==============================================================================<br>--- llvm/trunk/test/Assembler/attribute-builtin.ll (added)<br>+++ llvm/trunk/test/Assembler/attribute-builtin.ll Wed Jun 26 19:25:01 2013<br>@@ -0,0 +1,52 @@<br>+<br>+; Make sure that llvm-as/llvm-dis properly assembly/disassembly the 'builtin'<br>+; attribute.<br>+;<br>+;<span class="Apple-converted-space"> </span><a href="rdar://13727199">rdar://13727199</a><br>+<br>+; RUN: llvm-as -disable-verify < %s | \<br>+;      llvm-dis -disable-verify | \<br>+;      llvm-as -disable-verify | \<br>+;      llvm-dis -disable-verify | \<br>+;      FileCheck -check-prefix=ASSEMBLES %s<br>+<br>+; CHECK-ASSEMBLES: declare i8* @foo(i8*) [[NOBUILTIN:#[0-9]+]]<br>+; CHECK-ASSEMBLES: call i8* @foo(i8* %x) [[BUILTIN:#[0-9]+]]<br>+; CHECK-ASSEMBLES: attributes [[NOBUILTIN]] = { nobuiltin }<br>+; CHECK-ASSEMBLES: attributes [[BUILTIN]] = { builtin }<br>+<br>+declare i8* @foo(i8*) #1<br>+define i8* @bar(i8* %x) {<br>+  %y = call i8* @foo(i8* %x) #0<br>+  ret i8* %y<br>+}<br>+<br>+; Make sure that we do not accept the 'builtin' attribute on function<br>+; definitions, function declarations, and on call sites that call functions<br>+; which do not have nobuiltin on them.<br>+;<span class="Apple-converted-space"> </span><a href="rdar://13727199">rdar://13727199</a><br>+<br>+; RUN: not llvm-as <%s 2>&1  | FileCheck -check-prefix=BAD %s<br>+<br>+; CHECK-BAD: Attribute 'builtin' can only be used in a call to a function with the 'nobuiltin' attribute.<br>+; CHECK-BAD-NEXT: %y = call i8* @lar(i8* %x) #1<br>+; CHECK-BAD: Attribute 'builtin' can only be applied to a callsite.<br>+; CHECK-BAD-NEXT: i8* (i8*)* @car<br>+; CHECK-BAD: Attribute 'builtin' can only be applied to a callsite.<br>+; CHECK-BAD-NEXT: i8* (i8*)* @mar<br>+<br>+declare i8* @lar(i8*)<br>+<br>+define i8* @har(i8* %x) {<br>+  %y = call i8* @lar(i8* %x) #0<br>+  ret i8* %y<br>+}<br>+<br>+define i8* @car(i8* %x) #0 {<br>+  ret i8* %x<br>+}<br>+<br>+declare i8* @mar(i8*) #0<br>+<br>+attributes #0 = { builtin }<br>+attributes #1 = { nobuiltin }<br><br>Modified: llvm/trunk/test/Transforms/InstCombine/simplify-libcalls.ll<br>URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/simplify-libcalls.ll?rev=185049&r1=185048&r2=185049&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/simplify-libcalls.ll?rev=185049&r1=185048&r2=185049&view=diff</a><br>==============================================================================<br>--- llvm/trunk/test/Transforms/InstCombine/simplify-libcalls.ll (original)<br>+++ llvm/trunk/test/Transforms/InstCombine/simplify-libcalls.ll Wed Jun 26 19:25:01 2013<br>@@ -130,3 +130,15 @@ define i32 @MemCpy() {<br>}<br><br>declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind<br>+<br>+declare i32 @strcmp(i8*, i8*) #0<br>+<br>+define void @test9(i8* %x) {<br>+; CHECK: @test9<br>+; CHECK-NOT: strcmp<br>+  %y = call i32 @strcmp(i8* %x, i8* %x) #1<br>+  ret void<br>+}<br>+<br>+attributes #0 = { nobuiltin }<br>+attributes #1 = { builtin }<br><br><br>_______________________________________________<br>llvm-commits mailing list<br><a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br><a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a></div></blockquote></div><br></div></body></html>