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

            Bug ID: 92408
           Summary: strlen(s) != 0 not folded into *s
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

In simple expressions, GCC folds strlen(*s) calls whose result is only used in
a test for equality with zero to tests for the first character being nul.  But
it does only a superficial job and doesn't also do the same folding when the
result is stored in a variable that is then tested for the same equality.

Clang folds both.

$ cat z.c && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout z.c
void f (void);

void g (const char *s)
{
  if (__builtin_strlen (s))   // folded to if (*s)
    f ();
}

void h (const char *s)
{
  __SIZE_TYPE__ n = __builtin_strlen (s);
  if (n)                      // not folded into if (*s) but could be
    f ();
}

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

Removing basic block 5
g (const char * s)
{
  char _1;

  <bb 2> [local count: 1073741824]:
  _1 = *s_4(D);
  if (_1 != 0)
    goto <bb 3>; [33.00%]
  else
    goto <bb 4>; [67.00%]

  <bb 3> [local count: 354334802]:
  f (); [tail call]

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

}



;; Function h (h, funcdef_no=1, decl_uid=1935, cgraph_uid=2, symbol_order=1)

Removing basic block 5
h (const char * s)
{
  long unsigned int n;

  <bb 2> [local count: 1073741824]:
  n_4 = __builtin_strlen (s_3(D));
  if (n_4 != 0)
    goto <bb 3>; [33.00%]
  else
    goto <bb 4>; [67.00%]

  <bb 3> [local count: 354334802]:
  f (); [tail call]

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

}

Reply via email to