https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82991
Bug ID: 82991 Summary: memcpy and strcpy return value can be assumed to be equal to first argument Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- I noticed another even more straightforward optimization opportunity that the one pointed out in pr82665. The test case below shows that GCC knows that stpcpy(p, s) returns p + strlen(s) but it doesn't "know" that strcpy(p, s) returns p, or that memcmpy(p, s, n) also returns p. $ cat c.c && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout c.c void f1 (char *p) { char *q = __builtin_stpcpy (p, "123"); unsigned n = q - p; if (n != 3) // eliminated __builtin_abort (); } void f2 (char *p) { char *q = __builtin_strcpy (p, "123"); unsigned n = q - p; if (n) // not eliminated __builtin_abort (); } void f3 (char *p, const char *s) { char *q = __builtin_memcpy (p, s, 3); unsigned n = q - p; if (n) // not eliminated __builtin_abort (); } ;; Function f1 (f1, funcdef_no=0, decl_uid=1891, cgraph_uid=0, symbol_order=0) f1 (char * p) { <bb 2> [local count: 10000]: __builtin_memcpy (p_2(D), "123", 4); [tail call] return; } ;; Function f2 (f2, funcdef_no=1, decl_uid=1896, cgraph_uid=1, symbol_order=1) f2 (char * p) { unsigned int n; char * q; long int q.2_1; long int p.3_2; long int _3; <bb 2> [local count: 10000]: q_7 = __builtin_memcpy (p_5(D), "123", 4); q.2_1 = (long int) q_7; p.3_2 = (long int) p_5(D); _3 = q.2_1 - p.3_2; n_8 = (unsigned int) _3; if (n_8 != 0) goto <bb 3>; [0.04%] else goto <bb 4>; [99.96%] <bb 3> [count: 0]: __builtin_abort (); <bb 4> [local count: 9996]: return; } ;; Function f3 (f3, funcdef_no=2, decl_uid=1902, cgraph_uid=2, symbol_order=2) f3 (char * p, const char * s) { unsigned int n; char * q; long int q.4_1; long int p.5_2; long int _3; <bb 2> [local count: 10000]: q_8 = __builtin_memcpy (p_5(D), s_6(D), 3); q.4_1 = (long int) q_8; p.5_2 = (long int) p_5(D); _3 = q.4_1 - p.5_2; n_9 = (unsigned int) _3; if (n_9 != 0) goto <bb 3>; [0.04%] else goto <bb 4>; [99.96%] <bb 3> [count: 0]: __builtin_abort (); <bb 4> [local count: 9996]: return; }