https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92813

            Bug ID: 92813
           Summary: sprintf result not used by strlen pass
           Product: gcc
           Version: 10.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: ---

With the integration of the sprintf pass into strlen, GCC 10 makes use of
string lengths computed by the strlen pass to also compute the size of sprintf
(and snprintf) output.  This makes it possible to optimize calls like the one
if function f() below.  But the integration exposes string lengths only in one
direction, and doesn't also make the lengths computed by the sprintf pass
available to the strlen pass.  This can be seen in the dump for function g()
below which should be optimized away just like f() but isn't.

$ cat t.c && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout t.c
void f (void)
{
  char a[8];
  __builtin_strcpy (a, "1234");
  if (__builtin_snprintf (0, 0, "%s", a) != 4)
    __builtin_abort ();
}

void g (void)
{
  char a[8];
  __builtin_sprintf (a, "1234");
  if (__builtin_strlen (a) != 4)
    __builtin_abort ();
}

;; Function f (f, funcdef_no=0, decl_uid=1930, cgraph_uid=1, symbol_order=0)

f ()
{
  <bb 2> [local count: 1073741824]:
  return;

}



;; Function g (g, funcdef_no=1, decl_uid=1934, cgraph_uid=2, symbol_order=1)

g ()
{
  char a[8];
  long unsigned int _1;

  <bb 2> [local count: 1073741824]:
  __builtin_memcpy (&a, "1234", 5);
  _1 = __builtin_strlen (&a);
  if (_1 != 4)
    goto <bb 3>; [0.00%]
  else
    goto <bb 4>; [100.00%]

  <bb 3> [count: 0]:
  __builtin_abort ();

  <bb 4> [local count: 1073741824]:
  a ={v} {CLOBBER};
  return;

}

Reply via email to