<p dir="ltr">On 22 Apr 2015 1:54 am, "Richard Smith" <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> wrote:<br>
><br>
> On Tue, Apr 21, 2015 at 5:34 PM, Renato Golin <<a href="mailto:renato.golin@linaro.org">renato.golin@linaro.org</a>> wrote:<br>
>><br>
>> On 21 April 2015 at 17:06, Reid Kleckner <<a href="mailto:rnk@google.com">rnk@google.com</a>> wrote:<br>
>> > Is "ABI alignment" just the alignment of an i64 as specified in DataLayout,<br>
>> > or is it something else? Maybe we are computing that alignment incorrectly,<br>
>> > and the alignment of an i40 should be 4.<br>
>><br>
>> Alignment of bitfields in ARM depends on the alignment of the declared<br>
>> type. In this case, int, or 4 bytes. What happened in this example is<br>
>> that there are more bits than 32, but the ABI states that you must use<br>
>> containers aligned to the declared type, so even if you use more than<br>
>> 32 bits, you still need to align to 4 bytes. This essentially means<br>
>> that you just keep using 4-byte integer containers until all bits fit<br>
>> inside.<br>
>><br>
>> Since i40 doesn't exist in any target, LLVM does the obvious thing and<br>
>> promotes it to i64, but again, on ARM, long long (which is what i64<br>
>> means) aligns to 8 bytes, then you have the conflict. I cannot imagine<br>
>> a pass in LLVM that would see an i40 and split it into i32+i8 and<br>
>> convert to { i32, i32 } just because it used to be a bitfield. Too<br>
>> many things can go wrong, including alignment.<br>
>><br>
>><br>
>> > Alternatively, we could have Clang slap 'align 4' on the global and call it<br>
>> > fixed.<br>
>><br>
>> Would LLVM understand that correctly?<br>
><br>
><br>
> 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.<br>
>  <br>
>><br>
>> Would the ARM backend interpret<br>
>> that correctly and "realise" it's supposed to extend only the extra i8<br>
>> to an i32? Would that work on other backends? Or would it be better to<br>
>><br>
>> let Clang, which knows about the ARM ABI, to emit { i32, i32 }?<br>
><br>
><br>
> 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).</p>
<p dir="ltr">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. </p>