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>
Momchil Velikov via llvm-dev
2021-Mar-31 08:51 UTC
[llvm-dev] Controlling parameter alignment
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 ? ~chill -- Compiler scrub, Arm -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210331/68e022ab/attachment.html>
Momchil Velikov via llvm-dev
2021-Apr-13 17:45 UTC
[llvm-dev] Controlling parameter alignment
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 passedin>> > >> 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 passedin 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 ofthe 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 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 aprecedent 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 least16 bytes aligned>> * the caller is passing a pointer to that slot, which pointer itselfshould 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>