https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121909
Jan Hubicka <hubicka at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Ever confirmed|0 |1 Last reconfirmed| |2025-09-11 Status|UNCONFIRMED |NEW --- Comment #1 from Jan Hubicka <hubicka at gcc dot gnu.org> --- The problem is that last basic block has: _7 = a; and fnsplit considers only splitting where the split part leads directly to return (which is kind of a limitation that can be avoided, too). Hand optimizing it to: int *a; int *get() { int *aa = a; if (!aa) a = aa = new (int); return aa; } Problem is that equivalent transformation is done only later by PRE int * get () { int * a.0_1; void * _5; int * prephitmp_8; <bb 2> [local count: 1073741824]: a.0_1 = a; if (a.0_1 == 0B) goto <bb 3>; [17.43%] else goto <bb 4>; [82.57%] <bb 3> [local count: 187153200]: _5 = operator new (4); a = _5; <bb 4> [local count: 1073741824]: # prephitmp_8 = PHI <a.0_1(2), _5(3)> return prephitmp_8; } I am not sure why FRE does not see it. Load in return is fully redundant.