diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -1379,6 +1379,14 @@ information that is not mapped to base types in the backend (for example, over-alignment specification through language attributes). +``allocalign`` + The function parameter marked with this attribute is is the alignment in bytes of the + newly allocated block returned by this function. The returned value must either have + the specified alignment or be the null pointer. The return value MAY be more aligned + than the requested alignment, but not less aligned. Invalid (e.g. non-power-of-2) + alignments are permitted for the allocalign parameter, so long as the returned pointer + is null. This attribute may only be applied to integer parameters. + .. _gc: Garbage Collector Strategy Names diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h --- a/llvm/include/llvm/AsmParser/LLToken.h +++ b/llvm/include/llvm/AsmParser/LLToken.h @@ -177,6 +177,7 @@ // Attributes: kw_attributes, + kw_allocalign, kw_allocsize, kw_alwaysinline, kw_argmemonly, diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -678,6 +678,7 @@ ATTR_KIND_ELEMENTTYPE = 77, ATTR_KIND_DISABLE_SANITIZER_INSTRUMENTATION = 78, ATTR_KIND_NO_SANITIZE_BOUNDS = 79, + ATTR_KIND_ALLOC_ALIGN = 80, }; enum ComdatSelectionKindCodes { diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td --- a/llvm/include/llvm/IR/Attributes.td +++ b/llvm/include/llvm/IR/Attributes.td @@ -47,6 +47,10 @@ /// 0 means unaligned (different from align(1)). def Alignment : IntAttr<"align", [ParamAttr, RetAttr]>; +/// Parameter of a function that tells us the alignment of an allocation, as in +/// aligned_alloc and aligned ::operator::new. +def AllocAlign: EnumAttr<"allocalign", [ParamAttr]>; + /// The result of the function is guaranteed to point to a number of bytes that /// we can determine if we know the value of the function's arguments. def AllocSize : IntAttr<"allocsize", [FnAttr]>; diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -634,6 +634,7 @@ KEYWORD(attributes); KEYWORD(alwaysinline); + KEYWORD(allocalign); KEYWORD(allocsize); KEYWORD(argmemonly); KEYWORD(builtin); diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1520,6 +1520,8 @@ return Attribute::Dereferenceable; case bitc::ATTR_KIND_DEREFERENCEABLE_OR_NULL: return Attribute::DereferenceableOrNull; + case bitc::ATTR_KIND_ALLOC_ALIGN: + return Attribute::AllocAlign; case bitc::ATTR_KIND_ALLOC_SIZE: return Attribute::AllocSize; case bitc::ATTR_KIND_NO_RED_ZONE: diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -610,6 +610,8 @@ switch (Kind) { case Attribute::Alignment: return bitc::ATTR_KIND_ALIGNMENT; + case Attribute::AllocAlign: + return bitc::ATTR_KIND_ALLOC_ALIGN; case Attribute::AllocSize: return bitc::ATTR_KIND_ALLOC_SIZE; case Attribute::AlwaysInline: diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -1780,7 +1780,8 @@ if (!Ty->isIntegerTy()) // Attributes that only apply to integers. Incompatible.addAttribute(Attribute::SExt) - .addAttribute(Attribute::ZExt); + .addAttribute(Attribute::ZExt) + .addAttribute(Attribute::AllocAlign); if (!Ty->isPointerTy()) // Attributes that only apply to pointers. diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -962,6 +962,7 @@ break; // These attributes cannot be applied to functions. case Attribute::Alignment: + case Attribute::AllocAlign: case Attribute::ByVal: case Attribute::Dereferenceable: case Attribute::DereferenceableOrNull: diff --git a/llvm/test/Bitcode/compatibility.ll b/llvm/test/Bitcode/compatibility.ll --- a/llvm/test/Bitcode/compatibility.ll +++ b/llvm/test/Bitcode/compatibility.ll @@ -560,6 +560,8 @@ ; CHECK: declare void @f.param.swiftasync(i8* swiftasync) declare void @f.param.swifterror(i8** swifterror) ; CHECK: declare void @f.param.swifterror(i8** swifterror) +declare void @f.param.allocalign(i32 allocalign) +; CHECK: declare void @f.param.allocalign(i32 allocalign) ; Functions -- unnamed_addr and local_unnamed_addr declare void @f.unnamed_addr() unnamed_addr