llvm.org GIT mirror llvm / fe47ebf
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! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209185 91177308-0d34-0410-b5e6-96231b3b80d8 Nick Lewycky 5 years ago
14 changed file(s) with 44 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
845845 the callee. The parameter and the function return type must be valid
846846 operands for the :ref:`bitcast instruction `. This is not a
847847 valid attribute for return values and can only be applied to one parameter.
848
849 ``nonnull``
850 This indicates that the parameter or return pointer is not null. This
851 attribute may only be applied to pointer typed parameters. This is not
852 checked or enforced by LLVM, the caller must ensure that the pointer
853 passed in is non-null, or the callee must ensure that the returned pointer
854 is non-null.
848855
849856 .. _gc:
850857
370370 ATTR_KIND_BUILTIN = 35,
371371 ATTR_KIND_COLD = 36,
372372 ATTR_KIND_OPTIMIZE_NONE = 37,
373 ATTR_KIND_IN_ALLOCA = 38
373 ATTR_KIND_IN_ALLOCA = 38,
374 ATTR_KIND_NON_NULL = 39
374375 };
375376
376377 } // End bitc namespace
5454 /// For example in "void foo(int a, float b)" a is 0 and b is 1.
5555 unsigned getArgNo() const;
5656
57 /// \brief Return true if this argument has the nonnull attribute on it in
58 /// its containing function.
59 bool hasNonNullAttr() const;
60
5761 /// \brief Return true if this argument has the byval attribute on it in its
5862 /// containing function.
5963 bool hasByValAttr() const;
8585 NoInline, ///< inline=never
8686 NonLazyBind, ///< Function is called early and/or
8787 ///< often, so lazy binding isn't worthwhile
88 NonNull, ///< Pointer is known to be not null
8889 NoRedZone, ///< Disable redzone
8990 NoReturn, ///< Mark the function as not returning
9091 NoUnwind, ///< Function doesn't unwind stack
164164 LLVMStackProtectStrongAttribute = 1ULL<<33,
165165 LLVMCold = 1ULL << 34,
166166 LLVMOptimizeNone = 1ULL << 35,
167 LLVMInAllocaAttribute = 1ULL << 36
167 LLVMInAllocaAttribute = 1ULL << 36,
168 LLVMNonNullAttribute = 1ULL << 37
168169 */
169170 } LLVMAttribute;
170171
20642064 // Alloca never returns null, malloc might.
20652065 if (isa(V)) return true;
20662066
2067 // A byval or inalloca argument is never null.
2067 // A byval, inalloca, or nonnull argument is never null.
20682068 if (const Argument *A = dyn_cast(V))
2069 return A->hasByValOrInAllocaAttr();
2069 return A->hasByValOrInAllocaAttr() || A->hasNonNullAttr();
20702070
20712071 // Global values are not null unless extern weak.
20722072 if (const GlobalValue *GV = dyn_cast(V))
592592 KEYWORD(noimplicitfloat);
593593 KEYWORD(noinline);
594594 KEYWORD(nonlazybind);
595 KEYWORD(nonnull);
595596 KEYWORD(noredzone);
596597 KEYWORD(noreturn);
597598 KEYWORD(nounwind);
10021002 case lltok::kw_nest:
10031003 case lltok::kw_noalias:
10041004 case lltok::kw_nocapture:
1005 case lltok::kw_nonnull:
10051006 case lltok::kw_returned:
10061007 case lltok::kw_sret:
10071008 HaveError |=
12161217 case lltok::kw_nest: B.addAttribute(Attribute::Nest); break;
12171218 case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break;
12181219 case lltok::kw_nocapture: B.addAttribute(Attribute::NoCapture); break;
1220 case lltok::kw_nonnull: B.addAttribute(Attribute::NonNull); break;
12191221 case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break;
12201222 case lltok::kw_readonly: B.addAttribute(Attribute::ReadOnly); break;
12211223 case lltok::kw_returned: B.addAttribute(Attribute::Returned); break;
12681270 return HaveError;
12691271 case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break;
12701272 case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break;
1273 case lltok::kw_nonnull: B.addAttribute(Attribute::NonNull); break;
12711274 case lltok::kw_signext: B.addAttribute(Attribute::SExt); break;
12721275 case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break;
12731276
116116 kw_noimplicitfloat,
117117 kw_noinline,
118118 kw_nonlazybind,
119 kw_nonnull,
119120 kw_noredzone,
120121 kw_noreturn,
121122 kw_nounwind,
568568 return Attribute::NoInline;
569569 case bitc::ATTR_KIND_NON_LAZY_BIND:
570570 return Attribute::NonLazyBind;
571 case bitc::ATTR_KIND_NON_NULL:
572 return Attribute::NonNull;
571573 case bitc::ATTR_KIND_NO_RED_ZONE:
572574 return Attribute::NoRedZone;
573575 case bitc::ATTR_KIND_NO_RETURN:
196196 return bitc::ATTR_KIND_NO_INLINE;
197197 case Attribute::NonLazyBind:
198198 return bitc::ATTR_KIND_NON_LAZY_BIND;
199 case Attribute::NonNull:
200 return bitc::ATTR_KIND_NON_NULL;
199201 case Attribute::NoRedZone:
200202 return bitc::ATTR_KIND_NO_RED_ZONE;
201203 case Attribute::NoReturn:
192192 return "noinline";
193193 if (hasAttribute(Attribute::NonLazyBind))
194194 return "nonlazybind";
195 if (hasAttribute(Attribute::NonNull))
196 return "nonnull";
195197 if (hasAttribute(Attribute::NoRedZone))
196198 return "noredzone";
197199 if (hasAttribute(Attribute::NoReturn))
391393 case Attribute::Builtin: return 1ULL << 41;
392394 case Attribute::OptimizeNone: return 1ULL << 42;
393395 case Attribute::InAlloca: return 1ULL << 43;
396 case Attribute::NonNull: return 1ULL << 44;
394397 }
395398 llvm_unreachable("Unsupported attribute type");
396399 }
11761179 .addAttribute(Attribute::Nest)
11771180 .addAttribute(Attribute::NoAlias)
11781181 .addAttribute(Attribute::NoCapture)
1182 .addAttribute(Attribute::NonNull)
11791183 .addAttribute(Attribute::ReadNone)
11801184 .addAttribute(Attribute::ReadOnly)
11811185 .addAttribute(Attribute::StructRet)
7373 ++ArgIdx;
7474
7575 return ArgIdx;
76 }
77
78 /// hasNonNullAttr - Return true if this argument has the nonnull attribute on
79 /// it in its containing function.
80 bool Argument::hasNonNullAttr() const {
81 if (!getType()->isPointerTy()) return false;
82 return getParent()->getAttributes().
83 hasAttribute(getArgNo()+1, Attribute::NonNull);
7684 }
7785
7886 /// hasByValAttr - Return true if this argument has the byval attribute on it
215215 define void @f36(i8* inalloca) {
216216 ; CHECK: define void @f36(i8* inalloca) {
217217 ret void
218 }
219
220 define nonnull i8* @f37(i8* nonnull %a) {
221 ; CHECK: define nonnull i8* @f37(i8* nonnull %a) {
222 ret i8* %a
218223 }
219224
220225 ; CHECK: attributes #0 = { noreturn }