https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84824
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |alias, missed-optimization Status|UNCONFIRMED |NEW Last reconfirmed| |2018-03-12 CC| |rguenth at gcc dot gnu.org Component|c++ |tree-optimization Ever confirmed|0 |1 --- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> --- The issue is that printf () clobbers global memory and thus the std::function object: <bb 2> [100.00%]: MEM[(struct __lambda0 *)&D.30227] = 1; D.30227._M_invoker = _M_invoke; D.30227.D.29944._M_manager = _M_manager; __builtin_printf ("%d", 3); <bb 3> [100.00%]: _5 = MEM[(struct _Function_base *)&D.30227]._M_manager; if (_5 != 0B) goto <bb 4>; [94.39%] else goto <bb 5>; [5.61%] <bb 4> [94.39%]: _5 (&MEM[(struct _Function_base *)&D.30227]._M_functor, &MEM[(struct _Function_base *)&D.30227]._M_functor, 3); .. we fail to CSE the load from ._M_manager across printf for this reason. Note that D.30227 later escapes and given our "IPA mod-ref" analysis is context insensitive this is enough to not optimize it. I'm not sure if any std::function reorg could help with this issue. Better escape analysis might.