[llvm-dev] Controlling parameter alignment

Momchil Velikov via llvm-dev llvm-dev at lists.llvm.org
Tue Apr 13 10:45:01 PDT 2021


On Wed, Mar 31, 2021 at 9:51 AM Momchil Velikov <momchil.velikov at gmail.com>
wrote:
> On Wed, Mar 24, 2021 at 5:46 PM Momchil Velikov <momchil.velikov at gmail.com>
wrote:
>>
>> On Wed, Mar 24, 2021 at 11:28 AM Momchil Velikov <
momchil.velikov at gmail.com> wrote:
>> >
>> > On Wed, Mar 10, 2021 at 9:51 PM Reid Kleckner <rnk at google.com> wrote:
>> > >
>> > > On Wed, Mar 10, 2021 at 6:35 AM Momchil Velikov <
momchil.velikov at gmail.com> wrote:
>> > >>
>> > >> Just to be clear, the suggestion is to introduce `alignstack` to
>> > >> affect argument alignment, while retaining
>> > >> the current semantics for `align`?
>> > >>
>> > >> Thus, a pointer argument having both `align(A)` and `alignstack(B)`
>> > >> would itself be allocated at B boundary (if it happens to be passed
in
>> > >> memory),
>> > >> while it would contain an A-aligned address?
>> > >
>> > >
>> > > Yes, that's the proposal as I understand it.
>> >
>> > Something is not quite right here.
>> >
>> > We have up to three relevant alignment properties for a parameter:
>> >  * the alignment of the parameter itself (if it happenes to be passed
in memory)
>> >  * if it's a pointer, the actual alignment of the pointed to memory
(as an optimisation aid)
>> >  * if it's a `byval` or a `byref` argument, the minimum alignment of
the storage, allocated
>> >    for the original argument value (ABI affecting).
>> >
>> > For non-pointer arguments `alignstack(N)` gives stack slot alignment.
>> > For pointer arguments, we retain that use of `alignstack(N)` and also
have `align(M)` to give
>> > the actual alignment of the contained pointer.
>> >
>> > Now when we add `byval` or `byref` to the above, there is no attribute
left to give the alignment
>> > of the allocated memory. We thought of using `alignstack(N)`, but that
would leave us without a way
>> > to specify the pointer alignment itself.
>>
>>
>> I hope I'm not missing something obvious, and if I don't here's an idea:
>>
>> Extend the `byval(Ty)` attribute to `byval(Ty [, Align])` (same for
`byref`).
>>
>> (Most of the attributes take zero or one parameters, but there's a
precedent with `allocsize(<EltSizeParam>[, <NumEltsParam>])`)
>>
>> So we end up with :
>> * `align(N)` for pointer content
>> * `stackalign(N)` for the minimum alignment for of the actual argument,
if it ends up in memory
>> * `byval(Ty[, N])` and `byref(Ty[, N])` for the original argument value
>>
>> Thus something like `call %f(%struct.S * alignstack(8) align(32)
byval(%struct.S, 16) p);`
>> would mean:
>> * the caller has allocated a slot for `struct S`, that slot is at least
16 bytes aligned
>> * the caller is passing a pointer to that slot, which pointer itself
should be 8 bytes aligned, if it ends up in memory
>> * that pointer happens to have the lower five bits clear
>
>
> Hello,
>
> Any comments, suggestions, ideas ?

I have put up for an initial review a draft/prototype implementation of
this proposal above, for `byval` only.

https://reviews.llvm.org/D100397

--
Compiler scrub, Arm
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210413/8cf550e5/attachment.html>


More information about the llvm-dev mailing list