https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109442
--- Comment #35 from Jan Hubicka <hubicka at gcc dot gnu.org> --- On #include <vector> bool test1(const std::vector<int>& in) { return in == std::vector<int>{42}; } we produce: bool test1 (const struct vector & in) { bool _12; int * _13; int * _14; long int _24; unsigned int _43; int * _50; unsigned int _64; bool iftmp.5_69; <bb 2> [local count: 1073741824]: _50 = operator new (4); MEM <unsigned int> [(char * {ref-all})_50] = 42; _13 = MEM[(int * *)in_6(D)]; _14 = MEM[(int * *)in_6(D) + 8B]; _24 = _14 - _13; if (_24 == 4) goto <bb 3>; [34.00%] else goto <bb 4>; [66.00%] <bb 3> [local count: 182536112]: _43 = MEM <unsigned int> [(char * {ref-all})_13]; _64 = MEM <unsigned int> [(char * {ref-all})_50]; _12 = _43 == _64; <bb 4> [local count: 1073741824]: # iftmp.5_69 = PHI <_12(3), 0(2)> operator delete (_50, 4); return iftmp.5_69; } Allocation is not removed because we store 42 to the block: MEM <unsigned int> [(char * {ref-all})_50] = 42; and later read it again _64 = MEM <unsigned int> [(char * {ref-all})_50]; I think this is pass ordering issue. At PRE time we have _61 = __builtin_memcmp (_13, _50, 4); eventually it is taken away by strlen pass, but there is no another FRE to handle this scheduled after strlen.