[cfe-dev] Alignment of bitfield structs

Richard Smith richard at metafoo.co.uk
Tue Apr 21 19:09:02 PDT 2015


On Tue, Apr 21, 2015 at 6:07 PM, Renato Golin <renato.golin at linaro.org>
wrote:

> On 22 Apr 2015 1:54 am, "Richard Smith" <richard at metafoo.co.uk> wrote:
> >
> > On Tue, Apr 21, 2015 at 5:34 PM, Renato Golin <renato.golin at linaro.org>
> wrote:
> >>
> >> On 21 April 2015 at 17:06, Reid Kleckner <rnk at google.com> wrote:
> >> > Is "ABI alignment" just the alignment of an i64 as specified in
> DataLayout,
> >> > or is it something else? Maybe we are computing that alignment
> incorrectly,
> >> > and the alignment of an i40 should be 4.
> >>
> >> Alignment of bitfields in ARM depends on the alignment of the declared
> >> type. In this case, int, or 4 bytes. What happened in this example is
> >> that there are more bits than 32, but the ABI states that you must use
> >> containers aligned to the declared type, so even if you use more than
> >> 32 bits, you still need to align to 4 bytes. This essentially means
> >> that you just keep using 4-byte integer containers until all bits fit
> >> inside.
> >>
> >> Since i40 doesn't exist in any target, LLVM does the obvious thing and
> >> promotes it to i64, but again, on ARM, long long (which is what i64
> >> means) aligns to 8 bytes, then you have the conflict. I cannot imagine
> >> a pass in LLVM that would see an i40 and split it into i32+i8 and
> >> convert to { i32, i32 } just because it used to be a bitfield. Too
> >> many things can go wrong, including alignment.
> >>
> >>
> >> > Alternatively, we could have Clang slap 'align 4' on the global and
> call it
> >> > fixed.
> >>
> >> Would LLVM understand that correctly?
> >
> >
> > Why wouldn't it? It looks like the problem is shallow: we happen to emit
> a global in such a way that LLVM thinks it should be 8 byte aligned and
> Clang wanted it to be 4 byte aligned. If the alignment inferred from the
> type isn't the one we wanted, emitting an explicit alignment is exactly the
> right thing to do.
> >
> >>
> >> Would the ARM backend interpret
> >> that correctly and "realise" it's supposed to extend only the extra i8
> >> to an i32? Would that work on other backends? Or would it be better to
> >>
> >> let Clang, which knows about the ARM ABI, to emit { i32, i32 }?
> >
> >
> > The type we use for a global variable, beyond the size and implied
> alignment, is not supposed to matter. If some backend is using the type of
> a global variable for something ABI-relevant, we have a problem (we assume
> that we can change the type on a whim, for instance to make it match the
> type of a constant initializer).
>
> The type does matter, for instance, on a big vs little endian issue, as to
> where the final bits will end up. Literal i40 may work for big endian, but
> has to be converted to i32 + i32 for little endian.
>
That depends on the type used for loads and stores, not on the type used
for the global, no?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20150421/5e766c59/attachment.html>


More information about the cfe-dev mailing list