[llvm] r209185 - Add 'nonnull', a new parameter and return attribute which indicates that the pointer is not null. Instcombine will elide comparisons between these and null. Patch by Luqman Aden!
Nick Lewycky
nicholas at mxc.ca
Mon May 19 18:23:41 PDT 2014
Author: nicholas
Date: Mon May 19 20:23:40 2014
New Revision: 209185
URL: http://llvm.org/viewvc/llvm-project?rev=209185&view=rev
Log:
Add 'nonnull', a new parameter and return attribute which indicates that the pointer is not null. Instcombine will elide comparisons between these and null. Patch by Luqman Aden!
Modified:
llvm/trunk/docs/LangRef.rst
llvm/trunk/include/llvm-c/Core.h
llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
llvm/trunk/include/llvm/IR/Argument.h
llvm/trunk/include/llvm/IR/Attributes.h
llvm/trunk/lib/Analysis/ValueTracking.cpp
llvm/trunk/lib/AsmParser/LLLexer.cpp
llvm/trunk/lib/AsmParser/LLParser.cpp
llvm/trunk/lib/AsmParser/LLToken.h
llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
llvm/trunk/lib/IR/Attributes.cpp
llvm/trunk/lib/IR/Function.cpp
llvm/trunk/test/Bitcode/attributes.ll
Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=209185&r1=209184&r2=209185&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Mon May 19 20:23:40 2014
@@ -847,6 +847,13 @@ Currently, only the following parameter
operands for the :ref:`bitcast instruction <i_bitcast>`. This is not a
valid attribute for return values and can only be applied to one parameter.
+``nonnull``
+ This indicates that the parameter or return pointer is not null. This
+ attribute may only be applied to pointer typed parameters. This is not
+ checked or enforced by LLVM, the caller must ensure that the pointer
+ passed in is non-null, or the callee must ensure that the returned pointer
+ is non-null.
+
.. _gc:
Garbage Collector Names
Modified: llvm/trunk/include/llvm-c/Core.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Core.h?rev=209185&r1=209184&r2=209185&view=diff
==============================================================================
--- llvm/trunk/include/llvm-c/Core.h (original)
+++ llvm/trunk/include/llvm-c/Core.h Mon May 19 20:23:40 2014
@@ -165,7 +165,8 @@ typedef enum {
LLVMStackProtectStrongAttribute = 1ULL<<33,
LLVMCold = 1ULL << 34,
LLVMOptimizeNone = 1ULL << 35,
- LLVMInAllocaAttribute = 1ULL << 36
+ LLVMInAllocaAttribute = 1ULL << 36,
+ LLVMNonNullAttribute = 1ULL << 37
*/
} LLVMAttribute;
Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h?rev=209185&r1=209184&r2=209185&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h (original)
+++ llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h Mon May 19 20:23:40 2014
@@ -371,7 +371,8 @@ namespace bitc {
ATTR_KIND_BUILTIN = 35,
ATTR_KIND_COLD = 36,
ATTR_KIND_OPTIMIZE_NONE = 37,
- ATTR_KIND_IN_ALLOCA = 38
+ ATTR_KIND_IN_ALLOCA = 38,
+ ATTR_KIND_NON_NULL = 39
};
} // End bitc namespace
Modified: llvm/trunk/include/llvm/IR/Argument.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Argument.h?rev=209185&r1=209184&r2=209185&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Argument.h (original)
+++ llvm/trunk/include/llvm/IR/Argument.h Mon May 19 20:23:40 2014
@@ -55,6 +55,10 @@ public:
/// For example in "void foo(int a, float b)" a is 0 and b is 1.
unsigned getArgNo() const;
+ /// \brief Return true if this argument has the nonnull attribute on it in
+ /// its containing function.
+ bool hasNonNullAttr() const;
+
/// \brief Return true if this argument has the byval attribute on it in its
/// containing function.
bool hasByValAttr() const;
Modified: llvm/trunk/include/llvm/IR/Attributes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Attributes.h?rev=209185&r1=209184&r2=209185&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Attributes.h (original)
+++ llvm/trunk/include/llvm/IR/Attributes.h Mon May 19 20:23:40 2014
@@ -86,6 +86,7 @@ public:
NoInline, ///< inline=never
NonLazyBind, ///< Function is called early and/or
///< often, so lazy binding isn't worthwhile
+ NonNull, ///< Pointer is known to be not null
NoRedZone, ///< Disable redzone
NoReturn, ///< Mark the function as not returning
NoUnwind, ///< Function doesn't unwind stack
Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=209185&r1=209184&r2=209185&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Mon May 19 20:23:40 2014
@@ -2065,9 +2065,9 @@ bool llvm::isKnownNonNull(const Value *V
// Alloca never returns null, malloc might.
if (isa<AllocaInst>(V)) return true;
- // A byval or inalloca argument is never null.
+ // A byval, inalloca, or nonnull argument is never null.
if (const Argument *A = dyn_cast<Argument>(V))
- return A->hasByValOrInAllocaAttr();
+ return A->hasByValOrInAllocaAttr() || A->hasNonNullAttr();
// Global values are not null unless extern weak.
if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=209185&r1=209184&r2=209185&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLLexer.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLLexer.cpp Mon May 19 20:23:40 2014
@@ -593,6 +593,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(noimplicitfloat);
KEYWORD(noinline);
KEYWORD(nonlazybind);
+ KEYWORD(nonnull);
KEYWORD(noredzone);
KEYWORD(noreturn);
KEYWORD(nounwind);
Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=209185&r1=209184&r2=209185&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Mon May 19 20:23:40 2014
@@ -1003,6 +1003,7 @@ bool LLParser::ParseFnAttributeValuePair
case lltok::kw_nest:
case lltok::kw_noalias:
case lltok::kw_nocapture:
+ case lltok::kw_nonnull:
case lltok::kw_returned:
case lltok::kw_sret:
HaveError |=
@@ -1217,6 +1218,7 @@ bool LLParser::ParseOptionalParamAttrs(A
case lltok::kw_nest: B.addAttribute(Attribute::Nest); break;
case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break;
case lltok::kw_nocapture: B.addAttribute(Attribute::NoCapture); break;
+ case lltok::kw_nonnull: B.addAttribute(Attribute::NonNull); break;
case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break;
case lltok::kw_readonly: B.addAttribute(Attribute::ReadOnly); break;
case lltok::kw_returned: B.addAttribute(Attribute::Returned); break;
@@ -1269,6 +1271,7 @@ bool LLParser::ParseOptionalReturnAttrs(
return HaveError;
case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break;
case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break;
+ case lltok::kw_nonnull: B.addAttribute(Attribute::NonNull); break;
case lltok::kw_signext: B.addAttribute(Attribute::SExt); break;
case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break;
Modified: llvm/trunk/lib/AsmParser/LLToken.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=209185&r1=209184&r2=209185&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLToken.h (original)
+++ llvm/trunk/lib/AsmParser/LLToken.h Mon May 19 20:23:40 2014
@@ -117,6 +117,7 @@ namespace lltok {
kw_noimplicitfloat,
kw_noinline,
kw_nonlazybind,
+ kw_nonnull,
kw_noredzone,
kw_noreturn,
kw_nounwind,
Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=209185&r1=209184&r2=209185&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon May 19 20:23:40 2014
@@ -569,6 +569,8 @@ static Attribute::AttrKind GetAttrFromCo
return Attribute::NoInline;
case bitc::ATTR_KIND_NON_LAZY_BIND:
return Attribute::NonLazyBind;
+ case bitc::ATTR_KIND_NON_NULL:
+ return Attribute::NonNull;
case bitc::ATTR_KIND_NO_RED_ZONE:
return Attribute::NoRedZone;
case bitc::ATTR_KIND_NO_RETURN:
Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=209185&r1=209184&r2=209185&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Mon May 19 20:23:40 2014
@@ -197,6 +197,8 @@ static uint64_t getAttrKindEncoding(Attr
return bitc::ATTR_KIND_NO_INLINE;
case Attribute::NonLazyBind:
return bitc::ATTR_KIND_NON_LAZY_BIND;
+ case Attribute::NonNull:
+ return bitc::ATTR_KIND_NON_NULL;
case Attribute::NoRedZone:
return bitc::ATTR_KIND_NO_RED_ZONE;
case Attribute::NoReturn:
Modified: llvm/trunk/lib/IR/Attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Attributes.cpp?rev=209185&r1=209184&r2=209185&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Attributes.cpp (original)
+++ llvm/trunk/lib/IR/Attributes.cpp Mon May 19 20:23:40 2014
@@ -193,6 +193,8 @@ std::string Attribute::getAsString(bool
return "noinline";
if (hasAttribute(Attribute::NonLazyBind))
return "nonlazybind";
+ if (hasAttribute(Attribute::NonNull))
+ return "nonnull";
if (hasAttribute(Attribute::NoRedZone))
return "noredzone";
if (hasAttribute(Attribute::NoReturn))
@@ -392,6 +394,7 @@ uint64_t AttributeImpl::getAttrMask(Attr
case Attribute::Builtin: return 1ULL << 41;
case Attribute::OptimizeNone: return 1ULL << 42;
case Attribute::InAlloca: return 1ULL << 43;
+ case Attribute::NonNull: return 1ULL << 44;
}
llvm_unreachable("Unsupported attribute type");
}
@@ -1177,6 +1180,7 @@ AttributeSet AttributeFuncs::typeIncompa
.addAttribute(Attribute::Nest)
.addAttribute(Attribute::NoAlias)
.addAttribute(Attribute::NoCapture)
+ .addAttribute(Attribute::NonNull)
.addAttribute(Attribute::ReadNone)
.addAttribute(Attribute::ReadOnly)
.addAttribute(Attribute::StructRet)
Modified: llvm/trunk/lib/IR/Function.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Function.cpp?rev=209185&r1=209184&r2=209185&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Function.cpp (original)
+++ llvm/trunk/lib/IR/Function.cpp Mon May 19 20:23:40 2014
@@ -76,6 +76,14 @@ unsigned Argument::getArgNo() const {
return ArgIdx;
}
+/// hasNonNullAttr - Return true if this argument has the nonnull attribute on
+/// it in its containing function.
+bool Argument::hasNonNullAttr() const {
+ if (!getType()->isPointerTy()) return false;
+ return getParent()->getAttributes().
+ hasAttribute(getArgNo()+1, Attribute::NonNull);
+}
+
/// hasByValAttr - Return true if this argument has the byval attribute on it
/// in its containing function.
bool Argument::hasByValAttr() const {
Modified: llvm/trunk/test/Bitcode/attributes.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/attributes.ll?rev=209185&r1=209184&r2=209185&view=diff
==============================================================================
--- llvm/trunk/test/Bitcode/attributes.ll (original)
+++ llvm/trunk/test/Bitcode/attributes.ll Mon May 19 20:23:40 2014
@@ -218,6 +218,11 @@ define void @f36(i8* inalloca) {
ret void
}
+define nonnull i8* @f37(i8* nonnull %a) {
+; CHECK: define nonnull i8* @f37(i8* nonnull %a) {
+ ret i8* %a
+}
+
; CHECK: attributes #0 = { noreturn }
; CHECK: attributes #1 = { nounwind }
; CHECK: attributes #2 = { readnone }
More information about the llvm-commits
mailing list