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

            Bug ID: 86083
           Summary: handle non-constant assignments in strlen
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

As discussed in pr57230, the strlen optimizing pass manages to track string
lengths across non-nul constant character stores, it doesn't do the same for
non-constant stores even if their value is known to be non-nul (i.e., it's in
some range that excludes nul).  It's a trivial enhancement to have the pass
consider value ranges and implement the tracking in the non-constant case so
that the bodies of both functions below are eliminated and not just that of
f().

$ cat c.c && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout c.c
void f (void)
{
  char a[] = "123";

  a[1] = '4';

  if (__builtin_strlen (a) != 3)   // folded
    __builtin_abort ();
}

void g (unsigned i)
{
  char a[] = "123";

  a[1] = '0' + (i % 10);

  if (__builtin_strlen (a) != 3)   // not folded
    __builtin_abort ();
}

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

f ()
{
  <bb 2> [local count: 1073741825]:
  return;

}



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

g (unsigned int i)
{
  char a[4];
  unsigned int _1;
  unsigned char _2;
  unsigned char _3;
  char _4;
  long unsigned int _5;

  <bb 2> [local count: 1073741825]:
  a = "123";
  _1 = i_8(D) % 10;
  _2 = (unsigned char) _1;
  _3 = _2 + 48;
  _4 = (char) _3;
  a[1] = _4;
  _5 = __builtin_strlen (&a);
  if (_5 != 3)
    goto <bb 3>; [0.00%]
  else
    goto <bb 4>; [99.96%]

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

  <bb 4> [local count: 1073312327]:
  a ={v} {CLOBBER};
  return;

}

Reply via email to