[cfe-dev] Alignment of bitfield structs

Renato Golin renato.golin at linaro.org
Tue Apr 21 18:07:07 PDT 2015


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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20150422/1a7f4462/attachment.html>


More information about the cfe-dev mailing list