https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80937
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |missed-optimization --- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> --- A test case for the "unknown" destination is below. In the memcpy case, the second call is eliminated when the pointer arguments are declared restrict, but in the strcpy case it doesn't matter. I can't think of a reason why declaring the caller's arguments restrict should affect the optimization: both memcpy's and strcpy's arguments are declared restrict and both functions' behavior is undefined when the copies overlap. void memcpy_unknown (void *d, const void *s) { __builtin_memcpy (d, s, 32); __builtin_memcpy (d, s, 32); // not eliminated } void strcpy_unknown (char* restrict d, const char* restrict s) { __builtin_strcpy (d, s); __builtin_strcpy (d, s); // not eliminated } ;; Function memcpy_unknown (memcpy_unknown, funcdef_no=0, decl_uid=1794, cgraph_uid=0, symbol_order=0) memcpy_unknown (void * d, const void * s) { <bb 2> [100.00%]: __builtin_memcpy (d_2(D), s_3(D), 32); __builtin_memcpy (d_2(D), s_3(D), 32); [tail call] return; } ;; Function strcpy_unknown (strcpy_unknown, funcdef_no=1, decl_uid=1798, cgraph_uid=1, symbol_order=1) strcpy_unknown (char * restrict d, const char * restrict s) { <bb 2> [100.00%]: __builtin_strcpy (d_2(D), s_3(D)); __builtin_strcpy (d_2(D), s_3(D)); [tail call] return; }