[llvm] r185049 - Added support for the Builtin attribute.
Michael Gottesman
mgottesman at apple.com
Wed Jun 26 17:25:02 PDT 2013
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 }
More information about the llvm-commits
mailing list