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