diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -1210,12 +1210,14 @@ .. _attr_align: ``align `` or ``align()`` - This indicates that the pointer value has the specified alignment. - If the pointer value does not have the specified alignment, - :ref:`poison value ` is returned or passed instead. The - ``align`` attribute should be combined with the ``noundef`` attribute to - ensure a pointer is aligned, or otherwise the behavior is undefined. Note - that ``align 1`` has no effect on non-byval, non-preallocated arguments. + This indicates that the pointer value or vector of pointers has the + specified alignment. If applied to a vector of pointers, *all* pointers + (elements) have the specified alignment. If the pointer value does not have + the specified alignment, :ref:`poison value ` is returned or + passed instead. The ``align`` attribute should be combined with the + ``noundef`` attribute to ensure a pointer is aligned, or otherwise the + behavior is undefined. Note that ``align 1`` has no effect on non-byval, + non-preallocated arguments. Note that this attribute has additional semantics when combined with the ``byval`` or ``preallocated`` attribute, which are documented there. 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 @@ -1839,12 +1839,12 @@ AttrBuilder Incompatible; if (!Ty->isIntegerTy()) - // Attribute that only apply to integers. + // Attributes that only apply to integers. Incompatible.addAttribute(Attribute::SExt) .addAttribute(Attribute::ZExt); if (!Ty->isPointerTy()) - // Attribute that only apply to pointers. + // Attributes that only apply to pointers. Incompatible.addAttribute(Attribute::Nest) .addAttribute(Attribute::NoAlias) .addAttribute(Attribute::NoCapture) @@ -1852,7 +1852,6 @@ .addAttribute(Attribute::ReadNone) .addAttribute(Attribute::ReadOnly) .addAttribute(Attribute::SwiftError) - .addAlignmentAttr(1) // the int here is ignored .addDereferenceableAttr(1) // the int here is ignored .addDereferenceableOrNullAttr(1) // the int here is ignored .addPreallocatedAttr(Ty) @@ -1862,6 +1861,10 @@ .addByRefAttr(Ty) .addTypeAttr(Attribute::ElementType, Ty); + if (!Ty->isPtrOrPtrVectorTy()) + // Attributes that only apply to pointers or vectors of pointers. + Incompatible.addAlignmentAttr(1); // the int here is ignored + // Some attributes can apply to all "values" but there are no `void` values. if (Ty->isVoidTy()) Incompatible.addAttribute(Attribute::NoUndef); diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll --- a/llvm/test/Bitcode/attributes.ll +++ b/llvm/test/Bitcode/attributes.ll @@ -510,6 +510,12 @@ ret void; } +; CHECK-TYPED: define void @f83(<4 x i8*> align 32 %0, align 64 %1) +; CHECK-OPQUE: define void @f83(<4 x ptr> align 32 %0, align 64 %1) +define void @f83(<4 x i8*> align 32 %0, align 64 %1) { + ret void +} + ; CHECK: attributes #0 = { noreturn } ; CHECK: attributes #1 = { nounwind } ; CHECK: attributes #2 = { readnone }