https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61773
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Richard Biener from comment #3) > Proper testcase (string init was missing): > > char *stpcpy (char*, const char *); > char *foo (void) > { > char *p = __builtin_calloc (64, 1); > char *q = __builtin_calloc (64, 1); > __builtin_strcat (q, "abcde"); > __builtin_strcat (p, "ab"); > p[1] = 'a'; > __builtin_strcat (p, q); > return q; > } > > this isn't optimized either, only when p[0] = 'a'; is there the last > strcat will be optimized with known strlen of p. Hmm, a p[1] = '\0' > isn't optimized either. > > Unfortunately strlen isn't very verbose in its -details dump. Ok, those are all because the store is MEM[ptr, 1] = ... while only a zero offset MEM is handled in handle_char_store. For non-constant offset this gets handled by handle_pointer_plus. It seems to me that all builtin handling will have a similar issue when faced with arguments of &MEM[ptr_1, <nonzero-offset>] (zero-offset should be folded to plain ptr_1 of course, so doesn't happen). Simple char *stpcpy (char*, const char *); char *foo (void) { char *p = __builtin_calloc (64, 1); char *q = __builtin_calloc (64, 1); __builtin_strcat (q, "abcde"); __builtin_strcat (p, "ab"); p = p + 1; __builtin_strcat (p, q); return q; } isn't optimized because we get _10 = p_3 + _9; __builtin_memcpy (_10, "ab", 3); p_12 = p_3 + 1; __builtin_strcat (p_12, q_5); and likely p_3 string-info is invalidated instead of made a copy of that of _10 (as _9 is zero). char *stpcpy (char*, const char *); char *foo (char *q) { char *p = __builtin_strdup ("abcde"); p = p + 1; __builtin_strcat (p, "blah"); return q; } is also not handled well as we don't seem to recognize strdup?