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

            Bug ID: 90879
           Summary: fold zero-equality of strcmp between a longer string
                    and a smaller array
           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: ---

Here's another strcmp optimization opportunity (besides pr90626 and pr90876)
that could easily be taken advantage of on top of the solution for pr83026.

When strncmp is called with a bound in excess of the sizes of the pointed-to
arrays, GCC eliminates the pointless excessive bound and transforms the strncpy
call to strcpy (in a subset of the cases when this is possible).  This can be
seen in function f in the test case below.

But when, in a call to strcmp or strncmp, a string argument is longer than the
size of the array it's being compared with for equality, the optimization fails
to take advantage of the fact that a string that long cannot be equal to one
stored in a smaller array.  This can be seen in function g in the test case.

The existing optimization has all the smarts to go this extra step, it just
doesn't do it.

$ cat a.c && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout a.c
extern char a[4];

void f (void)
{
  if (0 == __builtin_strncmp (a, "12345", 8))   // transformed to strcmp
    __builtin_abort ();                         // when the whole expression
could be folded to zero
}

void g (void)
{ 
  if (0 == __builtin_strcmp (a, "123456"))      // not folded
    __builtin_abort ();
}

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

f ()
{
  int _1;

  <bb 2> [local count: 1073741824]:
  _1 = __builtin_strcmp (&a, "12345");
  if (_1 == 0)
    goto <bb 3>; [0.00%]
  else
    goto <bb 4>; [100.00%]

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

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

}



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

g ()
{
  int _1;

  <bb 2> [local count: 1073741824]:
  _1 = __builtin_strcmp (&a, "123456");
  if (_1 == 0)
    goto <bb 3>; [0.00%]
  else
    goto <bb 4>; [100.00%]

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

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

}

Reply via email to