This is the second attempt of r333500 (Update NRVO logic to support early return).
The previous one was reverted for a miscompilation for an incorrect NRVO set up on templates such as:
struct Foo {}; template <typename T> T bar() { T t; if (false) return T(); return t; }
Where, t is marked as non-NRVO variable before its instantiation. However, while its instantiation, it's left an NRVO candidate, turned into an NRVO variable later.
You don't need the -O0 here; that's the default.