rjmccall wrote:
I agree that the standard does not appear to permit this in C. There are three
ways to fix this:
1. Disable NRVO in the callee just in case the address being initialized is
aliased.
2. Disable RVO in the caller when aliasing is possible.
3. Convince the committee that they should change the standard to permit these
simple optimizations.
(1) also requires disabling copy elision in some cases. It is not possible to
directly observe the address of the compound literal in `return (struct S) {
E1, E2 };`, as the other example does, but E1 or E2 might assign to a field of
the alias, and such modifications must be overwritten when the return occurs.
It is tractable to implement (2) with a simple local escape analysis of the
variable's initializer. This would *not* be tractable if the initialized
variable were a global variable, but, fortunately, C does not permit global
variables to be initialized with non-constant expressions.
(3) would presumably take the form of either permitting objects to overlap in
certain situations, the same way that C++ permits copy elision, or just
generally weakening object overlap rules during initialization.
Richard, I'm sorry to contradict you, but Aaron is correct to guess that this
is ABI-affecting: ABIs should and sometimes do specify whether an indirect
return address is allowed to be aliased. For example, the x86_64 psABI is
quite clear:
> If the type has class MEMORY, then the caller provides space for the return
> value and passes the address of this storage in %rdi as if it were the first
> argument to the function. In effect, this address becomes a “hidden” first
> argument. This storage must not overlap any data visible to the callee
> through other names than this argument.
So on x86_64, we are clearly required to at least do (2). I don't think we
want different rules on different targets unless we're forced to.
If (2) is implemented correctly, I believe there's no way to observe NRVO, so
we don't also need to implement (1).
https://github.com/llvm/llvm-project/pull/101038
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits