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