https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117638
--- Comment #4 from Jan Hubicka <hubicka at gcc dot gnu.org> --- Both with assertions or without we offline _M_default_append which would be better inlined. It is because main is known to be called once. One difference is that non-assertion clobbers the vectors prior construction <bb 2> [local count: 10737416]: - MEM[(struct _Vector_impl_data *)&a] ={v} {CLOBBER(bob)}; - MEM[(struct _Vector_impl_data *)&a]._M_finish = 0B; - MEM[(struct _Vector_impl_data *)&b] ={v} {CLOBBER(bob)}; - MEM[(struct _Vector_impl_data *)&b]._M_finish = 0B; - MEM[(struct _Vector_impl_data *)&c] ={v} {CLOBBER(bob)}; - MEM[(struct _Vector_impl_data *)&c]._M_finish = 0B; MEM <float *> [(struct vector *)&a] = 0B; + MEM <float *> [(struct vector *)&a + 8B] = 0B; MEM <float *> [(struct vector *)&a + 16B] = 0B; std::vector<float>::_M_default_append (&a, 100000000); <bb 3> [local count: 10737416]: - a$_M_start_113 = MEM <float *> [(struct vector *)&a]; - a$_M_end_of_storage_114 = MEM <float *> [(struct vector *)&a + 16B]; + a$_M_start_127 = MEM <float *> [(struct vector *)&a]; + a$_M_finish_128 = MEM <float *> [(struct vector *)&a + 8B]; + a$_M_end_of_storage_140 = MEM <float *> [(struct vector *)&a + 16B]; MEM <float *> [(struct vector *)&b] = 0B; + MEM <float *> [(struct vector *)&b + 8B] = 0B; MEM <float *> [(struct vector *)&b + 16B] = 0B; std::vector<float>::_M_default_append (&b, 100000000); goto <bb 5>; [100.00%] It is not clear to me why CLOBBER is gone... However the main problem is that we do not know # of iterations of the loop. With assertions enabled we know that loop will terminate once it reaches the vector size but we do not know its size which is computed as: std::vector<float>::_M_default_append (&c, 100000000); goto <bb 7>; [100.00%] <bb 6> [count: 0]: <L13>: c$_M_start_188 = MEM <float *> [(struct vector *)&c]; if (c$_M_start_188 != 0B) goto <bb 32>; [0.00%] else goto <bb 33>; [0.00%] c$_M_start_198 = MEM <float *> [(struct vector *)&c]; c$_M_finish_199 = MEM <float *> [(struct vector *)&c + 8B]; c$_M_end_of_storage_187 = MEM <float *> [(struct vector *)&c + 16B]; _194 = b$_M_finish_174 - b$_M_start_97; __dif_195 = _194 /[ex] 4; So I think we would need to either inline _M_realloc_append (bypasing called once heuristics and based on knowledge that vector is empty at the begining) We also can not optimize the loop exit condition since we do now know that the vector does not point to s.