[Bug tree-optimization/82911] New: missing strlen optimization for strncpy with constant strings and constant bound

msebor at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Thu Nov 9 00:42:00 GMT 2017


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

            Bug ID: 82911
           Summary: missing strlen optimization for strncpy with constant
                    strings and constant bound
           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: ---

GCC can figure out the length of the string created by the first two statements
in f0() but it doesn't do the same in f1().  The optimization in f1() is
possible regardless of which of the constant strings is selected by the
conditional expression because they are both longer than the constant bound
specified by the third argument to strncpy.  By making use of the
get_range_strln() function defined in gimple-fold.c the tree-ssa-strlen.c pass
could determine the length of the shortest source string and use it to gate the
same optimization as in the first case.

$ cat c.c && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout c.c
void f0 (char *d)
{
  __builtin_strncpy (d, "123", 2);
  d[2] = 0;

  if (__builtin_strlen (d) != 2)   // eliminated, good
    __builtin_abort ();
}

void f1 (char *d, _Bool b)
{
  __builtin_strncpy (d, b ? "123" : "1234", 2);
  d[2] = 0;

  if (__builtin_strlen (d) != 2)   // not eliminated but could be
    __builtin_abort ();
}

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

f0 (char * d)
{
  <bb 2> [local count: 10000]:
  __builtin_memcpy (d_3(D), "123", 2);
  MEM[(char *)d_3(D) + 2B] = 0;
  return;

}



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

f1 (char * d, _Bool b)
{
  long unsigned int _1;
  const char * iftmp.0_2;

  <bb 2> [local count: 10000]:
  if (b_3(D) != 0)
    goto <bb 4>; [50.00%]
  else
    goto <bb 3>; [50.00%]

  <bb 3> [local count: 5000]:

  <bb 4> [local count: 10000]:
  # iftmp.0_2 = PHI <"123"(2), "1234"(3)>
  __builtin_strncpy (d_5(D), iftmp.0_2, 2);
  MEM[(char *)d_5(D) + 2B] = 0;
  _1 = __builtin_strlen (d_5(D));
  if (_1 != 2)
    goto <bb 5>; [0.04%]
  else
    goto <bb 6>; [99.96%]

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

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

}


More information about the Gcc-bugs mailing list