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/81435] New: missing strlen optimization for strcat past the beginning of clear array


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

            Bug ID: 81435
           Summary: missing strlen optimization for strcat past the
                    beginning of clear array
           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: ---

The tree-ssa-strlen pass is able to track the lengths of some dynamically
created and modified strings by calls to strcpy and strcat.  But in at least
one case where the strcat optimization could achieve parity with strcpy it does
not: when strcat is called to copy a string of known length pasty the beginning
of a zeroed-out buffer as is done in function g1() below the same optimization
done for strcpy is not done, and the pass loses track of the length of the
appended (copied) string.

$ cat a.c && gcc -O2 -S -Wall -Wextra  -fdump-tree-strlen=/dev/stdout a.c
void f0 (void)
{
  char a[4] = "234";
  char b[5] = "1";

  __builtin_strcpy (b + 1, a);

  if (__builtin_strlen (b + 1) != 3)   // optimized into 3
    __builtin_abort ();
}

void f1 (void)
{
  char a[4] = "234";
  char b[5] = "";

  __builtin_strcpy (b + 1, a);

  if (__builtin_strlen (b + 1) != 3)   // optimized into 3
    __builtin_abort ();
}

void g0 (void)
{
  char a[4] = "234";
  char b[5] = "1";

  __builtin_strcat (b + 1, a);

  if (__builtin_strlen (b + 1) != 3)   // optimized into 3
    __builtin_abort ();
}

void g1 (void)
{
  char a[4] = "234";
  char b[5] = "";

  __builtin_strcat (b + 1, a);

  if (__builtin_strlen (b + 1) != 3)   // not optimized
    __builtin_abort ();
}


;; Function f0 (f0, funcdef_no=0, decl_uid=1815, cgraph_uid=0, symbol_order=0)

f0 ()
{
  char b[5];
  char a[4];
  long unsigned int _1;

  <bb 2> [100.00%] [count: INV]:
  a = "234";
  b = "1";
  __builtin_memcpy (&MEM[(void *)&b + 1B], &a, 4);
  _1 = 3;
  if (_1 != 3)
    goto <bb 3>; [0.04%] [count: 0]
  else
    goto <bb 4>; [99.96%] [count: INV]

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

  <bb 4> [99.96%] [count: INV]:
  a ={v} {CLOBBER};
  b ={v} {CLOBBER};
  return;

}



;; Function f1 (f1, funcdef_no=1, decl_uid=1820, cgraph_uid=1, symbol_order=1)

f1 ()
{
  char b[5];
  char a[4];
  long unsigned int _1;

  <bb 2> [100.00%] [count: INV]:
  a = "234";
  b = "";
  __builtin_memcpy (&MEM[(void *)&b + 1B], &a, 4);
  _1 = 3;
  if (_1 != 3)
    goto <bb 3>; [0.04%] [count: 0]
  else
    goto <bb 4>; [99.96%] [count: INV]

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

  <bb 4> [99.96%] [count: INV]:
  a ={v} {CLOBBER};
  b ={v} {CLOBBER};
  return;

}



;; Function g0 (g0, funcdef_no=2, decl_uid=1825, cgraph_uid=2, symbol_order=2)

g0 ()
{
  char b[5];
  char a[4];
  long unsigned int _1;

  <bb 2> [100.00%] [count: INV]:
  a = "234";
  b = "1";
  __builtin_memcpy (&MEM[(void *)&b + 1B], &a, 4);
  _1 = 3;
  if (_1 != 3)
    goto <bb 3>; [0.04%] [count: 0]
  else
    goto <bb 4>; [99.96%] [count: INV]

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

  <bb 4> [99.96%] [count: INV]:
  a ={v} {CLOBBER};
  b ={v} {CLOBBER};
  return;

}



;; Function g1 (g1, funcdef_no=3, decl_uid=1830, cgraph_uid=3, symbol_order=3)

g1 ()
{
  char b[5];
  char a[4];
  long unsigned int _1;

  <bb 2> [100.00%] [count: INV]:
  a = "234";
  b = "";
  __builtin_strcat (&MEM[(void *)&b + 1B], &a);
  _1 = __builtin_strlen (&MEM[(void *)&b + 1B]);
  if (_1 != 3)
    goto <bb 3>; [0.04%] [count: 0]
  else
    goto <bb 4>; [99.96%] [count: INV]

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

  <bb 4> [99.96%] [count: INV]:
  a ={v} {CLOBBER};
  b ={v} {CLOBBER};
  return;

}

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