(original) (raw)
On Wed, Mar 24, 2021 at 5:46 PM Momchil Velikov <momchil.velikov@gmail.com> wrote:
On Wed, Mar 24, 2021 at 11:28 AM Momchil Velikov <momchil.velikov@gmail.com> wrote:
>
> On Wed, Mar 10, 2021 at 9:51 PM Reid Kleckner <rnk@google.com> wrote:
> >
> > On Wed, Mar 10, 2021 at 6:35 AM Momchil Velikov <momchil.velikov@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(\[, \])\`)
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