[Bug tree-optimization/82991] New: memcpy and strcpy return value can be assumed to be equal to first argument

msebor at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue Nov 14 16:21:00 GMT 2017


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

            Bug ID: 82991
           Summary: memcpy and strcpy return value can be assumed to be
                    equal to first argument
           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: ---

I noticed another even more straightforward optimization opportunity that the
one pointed out in pr82665.  The test case below shows that GCC knows that
stpcpy(p, s) returns p + strlen(s) but it doesn't "know" that strcpy(p, s)
returns p, or that memcmpy(p, s, n) also returns p.

$ cat c.c && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout c.c
void f1 (char *p)
{
  char *q = __builtin_stpcpy (p, "123");
  unsigned n = q - p;

  if (n != 3)             // eliminated
    __builtin_abort ();
}

void f2 (char *p)
{
  char *q = __builtin_strcpy (p, "123");
  unsigned n = q - p;

  if (n)                  // not eliminated
    __builtin_abort ();
}

void f3 (char *p, const char *s)
{
  char *q = __builtin_memcpy (p, s, 3);
  unsigned n = q - p;

  if (n)                  // not eliminated
    __builtin_abort ();
}

;; Function f1 (f1, funcdef_no=0, decl_uid=1891, cgraph_uid=0, symbol_order=0)

f1 (char * p)
{
  <bb 2> [local count: 10000]:
  __builtin_memcpy (p_2(D), "123", 4); [tail call]
  return;

}



;; Function f2 (f2, funcdef_no=1, decl_uid=1896, cgraph_uid=1, symbol_order=1)

f2 (char * p)
{
  unsigned int n;
  char * q;
  long int q.2_1;
  long int p.3_2;
  long int _3;

  <bb 2> [local count: 10000]:
  q_7 = __builtin_memcpy (p_5(D), "123", 4);
  q.2_1 = (long int) q_7;
  p.3_2 = (long int) p_5(D);
  _3 = q.2_1 - p.3_2;
  n_8 = (unsigned int) _3;
  if (n_8 != 0)
    goto <bb 3>; [0.04%]
  else
    goto <bb 4>; [99.96%]

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

  <bb 4> [local count: 9996]:
  return;

}



;; Function f3 (f3, funcdef_no=2, decl_uid=1902, cgraph_uid=2, symbol_order=2)

f3 (char * p, const char * s)
{
  unsigned int n;
  char * q;
  long int q.4_1;
  long int p.5_2;
  long int _3;

  <bb 2> [local count: 10000]:
  q_8 = __builtin_memcpy (p_5(D), s_6(D), 3);
  q.4_1 = (long int) q_8;
  p.5_2 = (long int) p_5(D);
  _3 = q.4_1 - p.5_2;
  n_9 = (unsigned int) _3;
  if (n_9 != 0)
    goto <bb 3>; [0.04%]
  else
    goto <bb 4>; [99.96%]

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

  <bb 4> [local count: 9996]:
  return;

}


More information about the Gcc-bugs mailing list