http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50693
--- Comment #15 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-10-11 14:34:47 UTC --- Note that it doesn't handle memset though, and the convoluted loop wouldn't be easy to detect either. size_t i = 0; bool loop_cond = i < n; while (loop_cond) { goto copy_block; loop_back: loop_cond = i < n; } goto end; copy_block: v->chars[i] = c; i++; goto loop_back; end: v->chars[n] = '\0'; return v; is simply trying to be too clever. I can't even understand that source ;) What probably causes this is that we don't merge the blocks # i_29 = PHI <i_10(3), 0(2)> copy_block: D.3506_7 = v_20->chars; D.3507_8 = D.3506_7 + i_29; *D.3507_8 = c_9(D); i_10 = i_29 + 1; goto <bb 3> (loop_back); loop_back: loop_cond_11 = i_10 < n_3(D); if (loop_cond_11 != 0) goto <bb 4> (copy_block); else goto <bb 5> (end); even though it's a fallthru edge. We don't do this to preserve user labels for debugging (and mind, no code-gen differences between -g0 vs. -g).