zygoloid wrote:

> Typically, the absence of a statement must be interpreted as a lack of a 
> guarantee. In this case, however, I would argue it is more plausible to infer 
> that the ABI authors did not consider the possibility of passing a pointer to 
> aliased memory for the return value, and therefore we should interpret their 
> silence as an implicit statement that compilers are not permitted to do that.

That seems like a reasonable argument. However, in my testing, a lot of C 
compilers (including GCC, Clang, ICC) pass a pointer to aliased memory for 
cases like `struct X x = f(&x);` in practice, and Clang seems to be the only 
one to do NRVO. A non-aliasing return slot plus NRVO seems to be ABI-conforming 
(at least for the ABIs that specify a non-aliasing return slot) and probably 
the best choice for performance, but it also seems to be the choice that is 
maximally incompatible with everyone else in practice :)

Should we try to convince at least the GCC folks that they're getting this 
wrong too?

> (1) also requires disabling copy elision in some cases:
> 
> ```c
> struct S { int x, y; char make_it_huge[1024]; };
> struct S foo(struct S *alias) {
>   return (struct S) { .x = 5, .y = (alias->x = 7, 0) };
> }
> void test() {
>   struct S var = foo(&var); // var.x must contain 5
> }
> ```
> 
> I put "when aliasing is possible" in (1), but I can't see any reasonable way 
> to make this decision locally in the callee because essentially any pointer 
> could alias the return value. (1) really has to be done unconditionally.

For what it's worth, (1) appears to be what GCC and ICC do, unconditionally. 
(And MSVC appears to make an unconditional copy in both the caller and the 
callee.)

https://github.com/llvm/llvm-project/pull/101038
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to