The usual implementation of RVO is that the calling code passes the address of a memory chunk where the function should construct its result object.
When the function result is directly an automatic variable that is not a formal argument, that that local variable can simply be placed in the caller-provided memory chunk, and the return statement then does no copying at all.
For an argument passed by value the calling machine code has to copy-initialize its actual argument into the formal argument’s location before jumping to the function. For the function to place its result there it would have to destroy the formal argument object first, which has some tricky special cases (e.g., when that construction directly or indirectly refers to the formal argument object). So, instead of identifying the result location with the formal argument location, an optimization here logically has to use a separate called-provided memory chunk for the function result.
However, a function result that is not passed in a register is normally provided by the caller. I.e., what one could reasonably talk about as RVO, a kind of diminished RVO, for the case of a return
expression that denotes a formal argument, is what would happen anyway. And it does not fit with the text “by constructing the automatic object directly into the function’s return value”.
Summing up, the data flow requiring that the caller passes in a value, means that it is necessarily the caller that initializes a formal argument's storage, and not the function. Hence, copying back from a formal argument can not be avoided in general (that weasel term covers the special cases where the compiler can do very special things, in particular for inlined machine code). However, it is the function that initializes any other local automatic object’s storage, and then it’s no problem to do RVO.