[cfe-dev] [RFC] Use preferred alignment instead of ABI alignment for complete object when applicable

James Y Knight via cfe-dev cfe-dev at lists.llvm.org
Thu Aug 20 06:26:22 PDT 2020

On Wed, Aug 19, 2020 at 8:53 PM David Rector <davrecthreads at gmail.com>

> For that matter "preferred alignment" is also confusing.  Who prefers it?
> When might that preference not be met?
> Here is my full understanding so far, expressed in the hope that pointing
> out my confusions here might better help answer Xiangling’s questions below:
>    - The "ABI" alignment of a type = the ABI-guaranteed minimum alignment
>    of any object of that type built by any standard-conformant compiler.
> Correct, this is the guaranteed alignment of any(***) object of that type
(either top-level complete object or a subobject).

>    - The "preferred" alignment of a type = the actual alignment, at least
>    as large as the ABI alignment, that *our* compiler will *always* use
>    in constructing an object of that type.
> When constructing a global or local variable, yes, we do.

>    - Therefore, whenever we are dealing with an object we know *our*
>    compiler has constructed, we can use the "preferred" alignment.
>       - And thereby take advantage of target-specific optimizations like
>       AIX.
>    - However, whenever we are dealing with e.g. a pointer to an object we
>    are not sure we built — i.e. which may have been constructed within a
>    function not compiled by our compiler (e.g. a function compiled without AIX
>    in some library might have constructed that object and passed a pointer to
>    it to some function our compiler is presently building) -- we are forced to
>    use only the ABI-guaranteed minimum alignment.
>       - `-And thereby miss out on AIX.
> The most critical difference isn't really our compiler vs someone else's
compiler. The "preferred" alignment is actually part of the ABI, too (yet
another reason why "ABI alignment" is an awful name, and "guaranteed
alignment" is better).

The preferred alignment applies only to creation of a full object, not, for
example, to fields within a struct. E.g. on x86-32:
   struct Foo { int i; double d; };
the double is placed at offset 4 within the struct, not 8. So, on x86-32,
when we have a pointer than could be pointing to such an object, we must
only assume the pointee has alignment of 4, not 8.

>    - Whenever a type has alignas(N), that alignment will be returned
>    for…both the ABI and the preferred alignments?  It will override both?  Is
>    that right?  I recall it overrides the preferred alignment in Xiangling’s
>    implementation, at least, not sure about the ABI case.
> Yes. Except that alignas can never reduce the alignment below the
guaranteed alignment according to the C/C++ language rules, so in effect it
can only override preferred alignment. (The nonstandard
`__attribute__((aligned))` and `__attribute__((packed))` can reduce
alignment below the default abi alignment, and in that case, you do
override both.)

>    - alignof(T) / __alignof(T) must return the "ABI" and "preferred"
>    alignments of T, respectively.
> Yep.

***: Of course, with the nonstandard packed/aligned attributes, you can
create objects which violate these alignment guarantees. If you do so, you
must be extremely careful to only access such an object through the
appropriately attributed type, and not through a normal unadorned pointer.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20200820/9c228cd8/attachment.html>

More information about the cfe-dev mailing list