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

            Bug ID: 90876
           Summary: fold zero-equality of memcmp and strncmp involving
                    strings of unequal lengths
           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: ---

Thanks to the solution for pr83026 committed in r261039 GCC optimizes strcmp
inequalities involving strings of different lengths.  However, it only handles
simple cases involving strcmp and misses other, equivalent cases involving
strncmp or memcmp that could be easily handled as well.  The test case below
shows the optimization in f0 and its absence in f1 and f2:

$ cat a.c && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout a.c
int f0 (void)
{ 
  char a[4], b[4];
  __builtin_strcpy (a, "12");
  __builtin_strcpy (b, "123");
  return 0 == __builtin_strcmp (a, b);   // folded to 0
}

int f1 (void)
{
  char a[4], b[4];
  __builtin_strcpy (a, "12");
  __builtin_strcpy (b, "123");
  return 0 == __builtin_strncmp (a, b, 3);   // not folded
}

int f2 (void)
{ 
  char a[4], b[4];
  __builtin_strcpy (a, "12");
  __builtin_strcpy (b, "123");
  return 0 == __builtin_memcmp (a, b, 3);   // not folded
}

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

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

}



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

f1 ()
{
  char b[4];
  char a[4];
  int _1;
  _Bool _2;
  int _6;

  <bb 2> [local count: 1073741824]:
  __builtin_memcpy (&a, "12", 3);
  MEM <unsigned char[4]> [(char * {ref-all})&b] = MEM <unsigned char[4]> [(char
* {ref-all})"123"];
  _1 = __builtin_strncmp (&a, &b, 3);
  _2 = _1 == 0;
  _6 = (int) _2;
  a ={v} {CLOBBER};
  b ={v} {CLOBBER};
  return _6;

}



;; Function f2 (f2, funcdef_no=2, decl_uid=1916, cgraph_uid=3, symbol_order=2)

f2 ()
{
  char b[4];
  char a[4];
  int _1;
  _Bool _2;
  int _6;

  <bb 2> [local count: 1073741824]:
  __builtin_memcpy (&a, "12", 3);
  MEM <unsigned char[4]> [(char * {ref-all})&b] = MEM <unsigned char[4]> [(char
* {ref-all})"123"];
  _1 = __builtin_memcmp_eq (&a, &b, 3);
  _2 = _1 == 0;
  _6 = (int) _2;
  a ={v} {CLOBBER};
  b ={v} {CLOBBER};
  return _6;

}

Reply via email to