This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tree-optimization/86075] New: dead store elimination defeats strlen optimization after memset zero followed by strcpy


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

            Bug ID: 86075
           Summary: dead store elimination defeats strlen optimization
                    after memset zero followed by strcpy
           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: ---

GCC emits optimally efficient code for the first of the two equivalent
functions below but generates very inefficient code for the latter.  First, it
zeroes out the entire array even though only a small part of it is used. 
Worse, (and ironically) because it eliminates the store to a[3] as dead early
on (in fre1) and before the strlen pass runs, the strlen optimization isn't
performed, and so the entire dead body of the function isn't eliminated.

Since unnecessarily zeroing-out storage just before storing strings in it is
common practice, detecting and handling it could lead to significant
improvements.  The solution for the missing strlen optimization in this case
could be as simple as enhancing the strlen pass to track not just string
lengths but also sizes of zeroed-out blocks of storage used for strings.

$ cat c.c && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout c.c
void f (void)
{
  char a[4096];

  __builtin_memcpy (a, "123", 3);
  a[3] = 0;

  if (__builtin_strlen (a) != 3)    // folded
    __builtin_abort ();
}

void g (void)
{
  char a[4096] = "";                // all bytes zeroed out

  __builtin_memcpy (a, "123", 3);
  a[3] = 0;                         // eliminated

  if (__builtin_strlen (a) != 3)    // not folded
    __builtin_abort ();
}

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

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

}



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

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

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

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

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

}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]