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;

}

Reply via email to