This is an archive of the discontinued LLVM Phabricator instance.

align_value attribute in Clang
ClosedPublic

Authored by hfinkel on Jul 22 2014, 7:09 PM.

Details

Summary

This patch introduces support for the align_value attribute. This attribute is supported by Intel's compiler (versions 14.0+), and several of my HPC users have requested support in Clang. It specifies an alignment assumption on the values to which a pointer points, and is used by numerical libraries to encourage efficient generation of vector code.

Of course, we already have an aligned attribute that can specify enhanced alignment for a type, so why is this additional attribute important? The problem is that if you want to specify that an input array of T is, say, 64-byte aligned, you could try this:

typedef double aligned_double attribute((aligned(64)));
void foo(aligned_double *P) {

double x = P[0]; // This is fine.
double y = P[1]; // What alignment did those doubles have again?

}

the access here to P[1] causes problems. P was specified as a pointer to type aligned_double, and any object of type aligned_double must be 64-byte aligned. But if P[0] is 64-byte aligned, then P[1] cannot be, and this access causes undefined behavior. Getting round this problem requires a lot of awkward casting and hand-unrolling of loops, all of which is bad.

With the align_value attribute, we can accomplish what we'd like in a well defined way:
typedef double *aligned_double_ptr attribute((align_value(64)));
void foo(aligned_double_ptr P) {

double x = P[0]; // This is fine.
double y = P[1]; // This is fine too.

}

This patch is not predicated on any uncommitted LLVM features -- CodeGen just adds the align attribute on function arguments, which has the desired effect as of r213670 -- (although, as follow-up work, can be enhanced to apply to more than just function parameters when combined with the in-development llvm.assume functionality).

Some documentation on the align_value attribute from Intel is on this page:
https://software.intel.com/en-us/articles/data-alignment-to-assist-vectorization

Thanks again!

P.S. I would have chosen to call this aligned_value, not align_value, for better naming consistency with the aligned attribute, but I think it would be more useful to users to adopt Intel's name.

Diff Detail

Event Timeline

hfinkel updated this revision to Diff 11798.Jul 22 2014, 7:09 PM
hfinkel retitled this revision from to align_value attribute in Clang.
hfinkel updated this object.
hfinkel edited the test plan for this revision. (Show Details)
hfinkel added reviewers: rsmith, aaron.ballman.
hfinkel added a subscriber: Unknown Object (MLST).
rsmith edited edge metadata.

+Michael Spencer, he was considering proposing something similar for standardization.

One aspect perhaps worth some thought:

typedef double * aligned_double_ptr attribute((align_value(64)));
aligned_double_ptr x;

void foo(decltype(x + 3) y, aligned_double_ptr z) {}

Does y also carry the alignment assumption? As it stands in my current patch, the answer is no -- I think that is the desirable outcome, but I could be convinced otherwise ;)

Thanks again,
Hal

  • Original Message -----

From: "Richard Smith" <richard@metafoo.co.uk>
To: hfinkel@anl.gov, "aaron ballman" <aaron.ballman@gmail.com>, bigcheesegs@gmail.com, richard@metafoo.co.uk
Cc: cfe-commits@cs.uiuc.edu
Sent: Tuesday, July 22, 2014 9:18:56 PM
Subject: Re: [PATCH] align_value attribute in Clang

+Michael Spencer, he was considering proposing something similar for
standardization.

http://reviews.llvm.org/D4635

ABataev edited edge metadata.Jul 23 2014, 1:43 AM

In icc this attribute is inherited.

Best regards,

Alexey Bataev

Software Engineer
Intel Compiler Team
Intel Corp.

23.07.2014 10:13, Hal Finkel пишет:

One aspect perhaps worth some thought:

typedef double * aligned_double_ptr attribute((align_value(64)));
aligned_double_ptr x;

void foo(decltype(x + 3) y, aligned_double_ptr z) {}

Does y also carry the alignment assumption? As it stands in my current patch, the answer is no -- I think that is the desirable outcome, but I could be convinced otherwise ;)

Thanks again,
Hal

  • Original Message -----

From: "Richard Smith" <richard@metafoo.co.uk>
To: hfinkel@anl.gov, "aaron ballman" <aaron.ballman@gmail.com>, bigcheesegs@gmail.com, richard@metafoo.co.uk
Cc: cfe-commits@cs.uiuc.edu
Sent: Tuesday, July 22, 2014 9:18:56 PM
Subject: Re: [PATCH] align_value attribute in Clang

+Michael Spencer, he was considering proposing something similar for
standardization.

http://reviews.llvm.org/D4635

  • Original Message -----

From: "Alexey Bataev" <a.bataev@hotmail.com>
To: hfinkel@anl.gov, "aaron ballman" <aaron.ballman@gmail.com>, bigcheesegs@gmail.com, richard@metafoo.co.uk, "a
bataev" <a.bataev@hotmail.com>
Cc: cfe-commits@cs.uiuc.edu
Sent: Wednesday, July 23, 2014 3:43:25 AM
Subject: Re: [PATCH] align_value attribute in Clang

In icc this attribute is inherited.

Interestingly, I made this:

def AlignValue : InheritableAttr

but I suppose that does not do this?

-Hal

Best regards,

Alexey Bataev

Software Engineer
Intel Compiler Team
Intel Corp.

23.07.2014 10:13, Hal Finkel пишет:

One aspect perhaps worth some thought:

typedef double * aligned_double_ptr
attribute((align_value(64)));
aligned_double_ptr x;

void foo(decltype(x + 3) y, aligned_double_ptr z) {}

Does y also carry the alignment assumption? As it stands in my
current patch, the answer is no -- I think that is the desirable
outcome, but I could be convinced otherwise ;)

Thanks again,
Hal

  • Original Message -----

From: "Richard Smith" <richard@metafoo.co.uk>
To: hfinkel@anl.gov, "aaron ballman" <aaron.ballman@gmail.com>,
bigcheesegs@gmail.com, richard@metafoo.co.uk
Cc: cfe-commits@cs.uiuc.edu
Sent: Tuesday, July 22, 2014 9:18:56 PM
Subject: Re: [PATCH] align_value attribute in Clang

+Michael Spencer, he was considering proposing something similar
for
standardization.

http://reviews.llvm.org/D4635

http://reviews.llvm.org/D4635

Hal,
probably you should add processing of this attribute to function
mergeDeclAttribute() in SemaDecl.cpp or something like this.

Best regards,

Alexey Bataev

Software Engineer
Intel Compiler Team

23 Июль 2014 г. 19:22:35, hfinkel@anl.gov писал:

  • Original Message -----

From: "Alexey Bataev" <a.bataev@hotmail.com>
To: hfinkel@anl.gov, "aaron ballman" <aaron.ballman@gmail.com>, bigcheesegs@gmail.com, richard@metafoo.co.uk, "a
bataev" <a.bataev@hotmail.com>
Cc: cfe-commits@cs.uiuc.edu
Sent: Wednesday, July 23, 2014 3:43:25 AM
Subject: Re: [PATCH] align_value attribute in Clang

In icc this attribute is inherited.

Interestingly, I made this:

def AlignValue : InheritableAttr

but I suppose that does not do this?

-Hal

Best regards,

Alexey Bataev

Software Engineer
Intel Compiler Team
Intel Corp.

23.07.2014 10:13, Hal Finkel пишет:

One aspect perhaps worth some thought:

typedef double * aligned_double_ptr
attribute((align_value(64)));
aligned_double_ptr x;

void foo(decltype(x + 3) y, aligned_double_ptr z) {}

Does y also carry the alignment assumption? As it stands in my
current patch, the answer is no -- I think that is the desirable
outcome, but I could be convinced otherwise ;)

Thanks again,
Hal

  • Original Message -----

From: "Richard Smith" <richard@metafoo.co.uk>
To: hfinkel@anl.gov, "aaron ballman" <aaron.ballman@gmail.com>,
bigcheesegs@gmail.com, richard@metafoo.co.uk
Cc: cfe-commits@cs.uiuc.edu
Sent: Tuesday, July 22, 2014 9:18:56 PM
Subject: Re: [PATCH] align_value attribute in Clang

+Michael Spencer, he was considering proposing something similar
for
standardization.

http://reviews.llvm.org/D4635

http://reviews.llvm.org/D4635

http://reviews.llvm.org/D4635

hfinkel updated this revision to Diff 12919.Aug 25 2014, 1:51 PM
hfinkel edited edge metadata.

An updated patch, accounting for review comments -- but this does not yet properly treat the attribute as a type attribute (so that it will be inherited by auto, etc.). I still need to work on that aspect, and I'll post another revision once I have those semantics working.

hfinkel updated this revision to Diff 13430.Sep 8 2014, 4:38 PM

Rebased, and removed from inappropriate isTypeDependent/isValueDependent checks (inappropriate here for the same reason they were inappropriate in patch D4601 for the assume_aligned attribute).

Work still needs to be done to allow use as a type attribute (so that the attribute follows type deduction, auto, etc.). I'll send a follow-up e-mail about this with questions.

  • Original Message -----

From: hfinkel@anl.gov
To: hfinkel@anl.gov, "aaron ballman" <aaron.ballman@gmail.com>, bigcheesegs@gmail.com, richard@metafoo.co.uk, "a
bataev" <a.bataev@hotmail.com>
Cc: cfe-commits@cs.uiuc.edu, "nurmukhametov alex" <nurmukhametov.alex@gmail.com>
Sent: Monday, September 8, 2014 6:38:44 PM
Subject: Re: [PATCH] align_value attribute in Clang

Rebased, and removed from inappropriate
isTypeDependent/isValueDependent checks (inappropriate here for the
same reason they were inappropriate in patch D4601 for the
assume_aligned attribute).

Work still needs to be done to allow use as a type attribute (so that
the attribute follows type deduction, auto, etc.). I'll send a
follow-up e-mail about this with questions.

I need this attribute to follow type deduction (auto, etc.), and as we've discussed, just making this a declaration attribute does not seem to do this. It seems to me that what I need to do, or at least might do, is hook align_value into AttributedType, and handle it in lib/Sema/SemaType.cpp. First, it is not clear where I should store the alignment parameter:

  • address_space stores its value in the type qualifiers
  • reg_parm stores its value as part of FunctionType
  • vector_type / ext_vector_type are their own Type subclasses (where ExtVectorType is a subclass of VectorType, but there is also DependentSizedExtVectorType which handles dependent attributes).

Given that align_value also needs to handle dependent alignment values, that seems most like the ExtVectorType/DependentSizedExtVectorType setup. I could create AlignValuePointerType/DependentAlignValuePointerType (or similar), maybe with AlignValuePointerType being a subclass of PointerType? (or maybe both being subclasses of PointerType?)

That having been said, creating subclasses of PointerType and/or new Type subclasses seems like an unfortunate amount of infrastructure for this feature. An alternative would be to place extra data directly into PointerType, but I don't like that idea because it adds memory (and some runtime) overhead to the common case with no corresponding benefit.

Ideally, I'd be able to use the original AlignValueAttr nodes, perhaps in combination with AttributedType somehow to indicate that a relevant AlignValueAttr node exists somewhere. Is there a way to do this?

In short, I'm not sure what the best way of doing this is, and I'm looking for advice.

Thanks again,
Hal

http://reviews.llvm.org/D4635

Files:

include/clang/Basic/Attr.td
include/clang/Basic/AttrDocs.td
include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Sema/AttributeList.h
include/clang/Sema/Sema.h
lib/CodeGen/CGCall.cpp
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
test/CodeGen/align_value.cpp
test/Sema/align_value.c
test/SemaCXX/align_value.cpp
  • Original Message -----

From: "Hal Finkel" <hfinkel@anl.gov>
To: reviews+D4635+public+b7e82bdc1d8c324a@reviews.llvm.org
Cc: "a bataev" <a.bataev@hotmail.com>, "nurmukhametov alex" <nurmukhametov.alex@gmail.com>, "aaron ballman"
<aaron.ballman@gmail.com>, richard@metafoo.co.uk, cfe-commits@cs.uiuc.edu
Sent: Monday, September 8, 2014 6:59:07 PM
Subject: Re: [PATCH] align_value attribute in Clang

  • Original Message -----

From: hfinkel@anl.gov
To: hfinkel@anl.gov, "aaron ballman" <aaron.ballman@gmail.com>,
bigcheesegs@gmail.com, richard@metafoo.co.uk, "a
bataev" <a.bataev@hotmail.com>
Cc: cfe-commits@cs.uiuc.edu, "nurmukhametov alex"
<nurmukhametov.alex@gmail.com>
Sent: Monday, September 8, 2014 6:38:44 PM
Subject: Re: [PATCH] align_value attribute in Clang

Rebased, and removed from inappropriate
isTypeDependent/isValueDependent checks (inappropriate here for the
same reason they were inappropriate in patch D4601 for the
assume_aligned attribute).

Work still needs to be done to allow use as a type attribute (so
that
the attribute follows type deduction, auto, etc.). I'll send a
follow-up e-mail about this with questions.

Pinging re: the design question below.

Thanks again,
Hal

I need this attribute to follow type deduction (auto, etc.), and as
we've discussed, just making this a declaration attribute does not
seem to do this. It seems to me that what I need to do, or at least
might do, is hook align_value into AttributedType, and handle it in
lib/Sema/SemaType.cpp. First, it is not clear where I should store
the alignment parameter:

  • address_space stores its value in the type qualifiers
  • reg_parm stores its value as part of FunctionType
  • vector_type / ext_vector_type are their own Type subclasses (where ExtVectorType is a subclass of VectorType, but there is also DependentSizedExtVectorType which handles dependent attributes).

Given that align_value also needs to handle dependent alignment
values, that seems most like the
ExtVectorType/DependentSizedExtVectorType setup. I could create
AlignValuePointerType/DependentAlignValuePointerType (or similar),
maybe with AlignValuePointerType being a subclass of PointerType?
(or maybe both being subclasses of PointerType?)

That having been said, creating subclasses of PointerType and/or new
Type subclasses seems like an unfortunate amount of infrastructure
for this feature. An alternative would be to place extra data
directly into PointerType, but I don't like that idea because it
adds memory (and some runtime) overhead to the common case with no
corresponding benefit.

Ideally, I'd be able to use the original AlignValueAttr nodes,
perhaps in combination with AttributedType somehow to indicate that
a relevant AlignValueAttr node exists somewhere. Is there a way to
do this?

In short, I'm not sure what the best way of doing this is, and I'm
looking for advice.

Thanks again,
Hal

http://reviews.llvm.org/D4635

Files:

include/clang/Basic/Attr.td
include/clang/Basic/AttrDocs.td
include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Sema/AttributeList.h
include/clang/Sema/Sema.h
lib/CodeGen/CGCall.cpp
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
test/CodeGen/align_value.cpp
test/Sema/align_value.c
test/SemaCXX/align_value.cpp

Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory


cfe-commits mailing list
cfe-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

I'd like some more information about how ICC treats this attribute. Does it produce a new type? For instance:

typedef int *I32 __attribute__((align_value(32)));
typedef int *I64 __attribute__((align_value(64)));

typedef I32 X; typedef I64 X; // ill-formed?
template<typename> struct Y;
typedef Y<I32> Z; typedef Y<I64> Z; // ill-formed?

extern I32 i32;
I64 i64 = i32; // ill-formed? Is an explicit cast required?
I32 i32 = i64; // ill-formed? Is there an implicit conversion that discards alignment?

... and if there's an implicit conversion that discards alignment, what is its conversion rank?

If I have:

int n __attribute__((aligned(32)));

... then what is decltype(&n)? Is it int*, or int* __attribute__((align_value(32)))?

  • Original Message -----

From: "Richard Smith" <richard@metafoo.co.uk>
To: hfinkel@anl.gov, "aaron ballman" <aaron.ballman@gmail.com>, bigcheesegs@gmail.com, richard@metafoo.co.uk, "a
bataev" <a.bataev@hotmail.com>
Cc: cfe-commits@cs.uiuc.edu
Sent: Thursday, September 25, 2014 7:06:33 PM
Subject: Re: [PATCH] align_value attribute in Clang

I'd like some more information about how ICC treats this attribute.
Does it produce a new type? For instance:

I did a quick experiment with icc (ICC) 14.0.1 20131008 (with -Wall -O3 -pedantic):

typedef int *I32 __attribute__((align_value(32)));
typedef int *I64 __attribute__((align_value(64)));

typedef I32 X; typedef I64 X; // ill-formed?

No diagnostic.

template<typename> struct Y;
typedef Y<I32> Z; typedef Y<I64> Z; // ill-formed?

No diagnostic.

extern I32 i32;
I64 i64 = i32; // ill-formed? Is an explicit cast required?

No diagnostic.

I32 i32 = i64; // ill-formed? Is there an implicit conversion that
discards alignment?

No diagnostic.

Alexey, can you please comment on the specifics?

-Hal

... and if there's an implicit conversion that discards alignment,
what is its conversion rank?

If I have:

int n __attribute__((aligned(32)));

... then what is decltype(&n)? Is it int*, or `int*
attribute((align_value(32)))`?

http://reviews.llvm.org/D4635

  1. ICC does not create a new type for type with this attribute. All

types are still the same.

int n attribute((aligned(32)));
decltype(&n) - int*.

Best regards,

Alexey Bataev

Software Engineer
Intel Compiler Team

26.09.2014 4:28, Hal Finkel пишет:

  • Original Message -----

From: "Richard Smith" <richard@metafoo.co.uk>
To: hfinkel@anl.gov, "aaron ballman" <aaron.ballman@gmail.com>, bigcheesegs@gmail.com, richard@metafoo.co.uk, "a
bataev" <a.bataev@hotmail.com>
Cc: cfe-commits@cs.uiuc.edu
Sent: Thursday, September 25, 2014 7:06:33 PM
Subject: Re: [PATCH] align_value attribute in Clang

I'd like some more information about how ICC treats this attribute.
Does it produce a new type? For instance:

I did a quick experiment with icc (ICC) 14.0.1 20131008 (with -Wall -O3 -pedantic):

typedef int *I32 __attribute__((align_value(32)));
typedef int *I64 __attribute__((align_value(64)));

typedef I32 X; typedef I64 X; // ill-formed?

No diagnostic.

template<typename> struct Y;
typedef Y<I32> Z; typedef Y<I64> Z; // ill-formed?

No diagnostic.

extern I32 i32;
I64 i64 = i32; // ill-formed? Is an explicit cast required?

No diagnostic.

I32 i32 = i64; // ill-formed? Is there an implicit conversion that
discards alignment?

No diagnostic.

Alexey, can you please comment on the specifics?

-Hal

... and if there's an implicit conversion that discards alignment,
what is its conversion rank?

If I have:

int n __attribute__((aligned(32)));

... then what is decltype(&n)? Is it int*, or `int*
attribute((align_value(32)))`?

http://reviews.llvm.org/D4635

hfinkel updated this revision to Diff 14343.Oct 2 2014, 1:10 PM

Alright, after much discussion, I think this is ready.

To quickly recap, there had been some discussion regarding whether or not align_value needed to be part of the type system (so that it would be propagated by template type deduction, for example), after after receiving feedback from Richard, Alexey, et al., we're settled on no. This is not part of the type system, and will only "propagate" through templates, auto, etc. by optimizer deduction after inlining. This seems consistent with Intel's implementation.

Aaron, this new revision should account for all additional points from your last review.

hfinkel accepted this revision.Oct 2 2014, 2:31 PM
hfinkel added a reviewer: hfinkel.
This revision is now accepted and ready to land.Oct 2 2014, 2:31 PM
hfinkel closed this revision.Oct 2 2014, 2:32 PM

r218910, thanks!