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,12 @@ 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. That is, it's similar to putting + `align(N)` on the return value of the function but it's specified by the caller of the + function and values which aren't a power of 2 are undefined behavior. + .. _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 @@ -677,6 +677,7 @@ ATTR_KIND_NO_SANITIZE_COVERAGE = 76, ATTR_KIND_ELEMENTTYPE = 77, ATTR_KIND_DISABLE_SANITIZER_INSTRUMENTATION = 78, + ATTR_KIND_ALLOC_ALIGN = 79, }; 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 @@ -1437,6 +1437,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/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 @@ -902,6 +902,7 @@ switch (Attr.getKindAsEnum()) { // Those attributes cannot be propagated safely. Explicitly list them // here so we get a warning if new attributes are added. + case Attribute::AllocAlign: case Attribute::AllocSize: case Attribute::ArgMemOnly: case Attribute::Builtin: 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