https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88813
Bug ID: 88813 Summary: snprintf less optimal than sprintf for %s with big enough destination Product: gcc Version: 9.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: --- The discussion of the background on pr88793 (https://bugzilla.redhat.com/show_bug.cgi?id=1480664) made me realize that GCC could do a better job optimizing some common snprintf calls. Specifically, it transforms calls to sprintf(d, "%s", s) to strcpy(d, s), and it similarly transforms calls to snprintf(d, sizeof d, "%s", s) to memcpy(d, s, strlen(s) + 1) if it can tell that strlen(s) is less than sizeof(d). Unfortunately, it can only tell that for constant strings, and it doesn't consider array sizes. It should be able to both (a) track string lengths (by relying on the strlen pass), and also (b) make use of array sizes and transform snprintf(d, sizeof d, "%s", s) to strcpy(d, s) whenever sizeof(s) <= sizeof(d). (a) is planned for GCC 10. (b) Below is a test case where GCC could emit optimal code for both functions: $ cat z.c && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout z.c char d[8]; char s[8]; void f (void) { __builtin_sprintf (d, "%s", s); // optimized } void g (void) { __builtin_snprintf (d, sizeof d, "%s", s); // not optimized } ;; Function f (f, funcdef_no=0, decl_uid=1908, cgraph_uid=1, symbol_order=2) f () { <bb 2> [local count: 1073741824]: __builtin_strcpy (&d, &s); [tail call] return; } ;; Function g (g, funcdef_no=1, decl_uid=1911, cgraph_uid=2, symbol_order=3) g () { <bb 2> [local count: 1073741824]: __builtin_snprintf (&d, 8, "%s", &s); [tail call] return; }