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

Xiangling Liao via cfe-dev cfe-dev at lists.llvm.org
Tue Aug 18 08:01:11 PDT 2020

It looks to me as if at least examples 1, 2, and 4 are places that should
*not* be changed to use the "AIX preferred" alignment, because they are
inquiring about the guaranteed alignment of an existing pointer, which may
well not have been placed at the preferred alignment. I haven't dug into
the code beyond your snippet so I'm not sure about examples 3 and 5.

To be honest, I am not familiar with every snippet where functions like
“getTypeAlignInChars” is used. So I just list some locations that call
“getTypeAlignInChars”. But I did mean that we probably should replace them
with “PreferredAlignment” for AIX.

1. In AIX rules, not only an aggregate can now have a different preferred
alignment from guaranteed alignment, but also double, long double.

We see the semantic of “PreferredAlignment” on AIX represents a “T”’s
actual alignment. In other words, ABI alignment on AIX is kinda useless
except for being used to let “alignof(T)” return a correct value.

2. For the example1, you mentioned the “the guaranteed alignment of an
existing pointer may well not have been placed at the preferred alignment”.
But as I know, what function “getPreferredTypeAlign” does is to get the
ABI/guaranteed alignment of a “T” first by invoking “getTypeInfo”, and then
minor adjust some values. So we seems don’t need to worry about we cannot
get a pointer’s ABI alignment, and many other cases as well, if that’s the
correct one for AIX.

Besides, I am not sure if I understand the code snippet right in example1.


  // If that failed, return the type's alignment.

  return S.Context.getTypeAlignInChars(E->getType()->getPointeeType());



A pointer’s pointeeType can be anything, which may be an aggregate,  double,
or long doble etc. For those types, on AIX, we do need to get the

3. So far, I didn’t investigate every usage of those four functions:

1) getTypeAlignInChars [invokes getTypeAlign]

2) getTypeAlign <=> getTypeInfo(T).Align

3) getTypeInfo [ invokes ‘getTypeInfoImpl’]

4) getTypeInfoInChars

Because I am not sure if we really want to spend a lot of time on digging
each crack. An initial scan of them shows a large amount of them used in
Clang. How do you think about this?

And most importantly, besides of “adding a flag” way to handle speical
alignment on AIX, I am wondering in which way we can handle it better?


On Tue, Aug 18, 2020 at 8:48 AM James Y Knight <jyknight at google.com> wrote:

> On Tue, Aug 18, 2020, 12:54 AM David Rector <davrecthreads at gmail.com>
> wrote:
>> I would have to think that, whatever the documentation for  e.g.
>> getTypeAlignInChars(T), most users expect it to return T’s actual
>> alignment for their target, whether it was determined from the ABI, or the
>> AIX alignment scheme, or whatever.
> There really are two concepts at play here.
> 1. Given a pointer to some object of type T or a field of type T inside
> another object, what can I know for sure about the alignment of that
> pointer? (How many of the low bits are absolutely guaranteed to be 0,
> assuming the program doesn't involve Undefined Behavior?)
> 2. If I want to allocate a brand new complete object of type T, at what
> alignment should I use to place it? This must be at least the alignment
> from 1. But beyond that, it could differ by circumstance, e.g. stack,
> global, and function parameter allocations could make different choices. In
> some cases, increasing the alignment of an allocation above the required
> minimum may just be an optimization, but in other cases it has an ABI
> impact.
> AIX is not the first platform where these alignments differ -- the type
> 'double' on x86-32 being the other notable example. But, the AIX rules
> trigger differences in more circumstances than we've had before, and thus
> we now need to potentially make a choice in other parts of the code.
> Importantly: in AIX rules, an aggregate can now have a different preferred
> alignment from guaranteed alignment, too.
> The first case brought up where this surely matters, is 'new T[100]' where
> T has a destructor. This thread is exploring whether there are other such
> cases that we might need to change, too. I suspect that there are not many,
> but that remains to be determined.
>> In fact, maybe we can go further: I would think that any valid use of
>> type alignment which explicitly ignores AIX or other target-specific
>> alignment schemes are probably just implementation details used only in the
>> calculation of some composed type’s alignment under that scheme.  In other
>> words I would assume every function call in which AIX preferred alignment
>> needed to be ignored is in the some layout-building implementation — is
>> that right?
>> E.g. the lib/AST/RecordLayoutBuilder.cpp example you cite below fits
>> this description — in LayoutField(FieldDecl *D, …) you propose to change
>> the call to fetch the ABI/non-AIX type info via
>> getTypeInfo(D->getType(), true/* NeedsABIAlignment */);
>> but only so that you can later tweak that info whenever
>> DefaultsToAIXPowerAlignment==true.
>> If all the changes you would need to make are indeed similar to this,
>> these expanded usages are really only implementation details needed to
>> build type layouts, and thus the goal should simply be to sufficiently hide
>> these details from common programmers who don’t need to build type layouts,
>> only access them.
>> I think your original option #2 ("add a flag"), i.e. adding new defaulted
>> parameters to a few functions, seems to be a reasonable way to hide these
>> new details, so long as the new parameters are well named and
>> documented.  It also seems sufficiently general to be useful for
>> implementing other special default alignment schemes in the future.
>> Dave
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20200818/58c3de49/attachment-0001.html>

More information about the cfe-dev mailing list