How does byval work?

Can someone explain how byval works internally? On x86_64 linux it seems a struct “byval” is passed on the stack (not coerced to registers) but as values on the callside, but is that how it works everywhere and am I understanding this correctly?

Thanks,

From the point of view of the middle end, passing an argument “byval” is very similar to passing the argument directly. The only difference is that the “byval” argument is represented as a pointer in the IR, suggesting that the argument will be stored in memory. Note that although it is represented as a pointer, it does not mean that you can change the callers value from the callee – an implicit copy of the argument is made at the time of the call.

How you lower a “byval” argument in a backend is up to you, but you must ensure that the caller and the callee have distinct copies of the argument. Usually this is done by memcpying the argument to the callees call frame (which is then expanded into a series of scalar stores).

Yeah I’m actually looking for the behavior as it is now. I’m not implementing a new backend, I’m trying to see if byval passes it on the stack on all platforms (arm, aarch64, x86_64, i386, etc), so I was wondering if there is a default behavior here somewhere.