Momchil Velikov via llvm-dev
2021-Mar-24 11:28 UTC
[llvm-dev] Controlling parameter alignment
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. ~chill -- Compiler scrub, Arm -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210324/f8b50a43/attachment.html>
Momchil Velikov via llvm-dev
2021-Mar-24 17:46 UTC
[llvm-dev] Controlling parameter alignment
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 inmemory)> * if it's a pointer, the actual alignment of the pointed to memory (asan optimisation aid)> * if it's a `byval` or a `byref` argument, the minimum alignment of thestorage, 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 alsohave `align(M)` to give> the actual alignment of the contained pointer. > > Now when we add `byval` or `byref` to the above, there is no attributeleft to give the alignment> of the allocated memory. We thought of using `alignstack(N)`, but thatwould 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 ~chill -- Compiler scrub, Arm -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210324/63cb3d69/attachment.html>