https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89653
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- Ah, OK. So our special pass to deal with std::min taking arguments by reference is "confused" enough by _4 = *_3; // vec[i] D.17247 = _5; if (_4 > _5) goto <bb 5>; [34.00%] else goto <bb 6>; [66.00%] <bb 5> [local count: 324914276]: <bb 6> [local count: 955630225]: # _17 = PHI <_3(4), &D.17247(5)> _6 = *_17; the pass tries to replace the dereference in BB6 but fails on the 4->6 edge where it thinks placing *_3 on it isn't profitable. Only the if-conversion phase in the vectorizer will then recognize the MIN_EXPR operation but it is too late to get rid of the "memory" temporary involved here. Note that PRE performs what the special phiprop could have done, but it leaves the dead memory operation around, which the DCE that's there cannot remove because D.17094 still appears to have its address taken. _5 = reciptmp_8 * _4; D.17094 = _5; if (_4 > _5) goto <bb 7>; [34.00%] else goto <bb 6>; [66.00%] <bb 6> [local count: 630715944]: <bb 7> [local count: 955630224]: # prephitmp_29 = PHI <_5(5), _4(6)> *_3 = prephitmp_29; D.17094 ={v} {CLOBBER}; there are plenty DCE passes between this and vectorization but no DSE which would fix it up and also no update-address-taken. Doing this after PRE is too early (the PHI with the address-taking is still in the IL), doing it after each DCE might be a (somewhat costly) option. I also have a patch to make the above catched in phiprop.