[llvm-dev] Controlling parameter alignment

Reid Kleckner via llvm-dev llvm-dev at lists.llvm.org
Fri Feb 26 12:50:16 PST 2021


On Thu, Feb 25, 2021 at 5:00 PM Doerfert, Johannes <jdoerfert at anl.gov>
wrote:

> To double check, the problem is the last argument here
> https://godbolt.org/z/Gqva4Y does not carry the align(16)
> information anymore, correct?
>

Basically, yes.


> If so, I don't see an immediate problem with allowing an "alignment"
> be applied to non-pointer values. The semantics would probably say
> that if the value is demoted to memory/stack, the associated alignment
> has to be guaranteed. As noted before [0], `align` is actually a hint
> and not a requirement. I'm unsure if we could not make it binding TBH,
> will think about that, interested in opinions.
>
> I take it we can't/don't want to legalize the constraints in the
> backend, right? I mean, use `%sturct.S* align(16) byval(%sturct.S) %p`
> in the IR. On that thought, what happens if we have a `struct S *`
> argument in source which we then promote to pass it by value?
>

Yes, we wouldn't want to use byval in the frontend because it is best to
use IR arguments that are lowered correctly regardless of their position in
the argument list. Using byval usually forces the argument to be passed in
memory, and that isn't correct if the six double arguments are removed from
the original example. This has the surprising consequence that we can't,
for example, remove arguments from vararg functions:
https://reviews.llvm.org/rGe6e88f99b35f2fde5008e36f0d93f5231564b7d8
 And, generally, byval results in worse code at the call site than passing
SSA values does.

If LLVM is able to do argument promotion, usually that means there is no
ABI compatibility concern, and the arguments don't have to be aligned or
arranged in any particular way. I think argument promotion in this case
would pass each field individually.

----

I think what we need here is a new attribute, or a repurposed attribute, to
control argument alignment. The original patch uses alignstack(n) for this
purpose, which to date is used to control the stack pointer alignment for
the whole call frame, and not for arguments. Do people like that, or is it
confusing? If it's OK to use alignstack(n) on an argument, should we start
using it on byval arguments in addition to align(), or is that just churn?
Is it useful to have this kind of strong separation between ABI attributes
and optimization hint attributes?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210226/d93157c7/attachment.html>


More information about the llvm-dev mailing list