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

            Bug ID: 83674
           Summary: strcpy folding of small strings defeats strlen
                    optimization
           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: ---

Here's another test case showing the detrimental effect of early folding into
MEM_REFs that the strlen pass isn't equipped to handle.  The first dump that
shows the MEM_REF is forwprop1.  The interesting aspect of this test case is
that whether or not the optimization takes place depends on both the size of
the destination and the lengths of the source strings.

$ cat z.c && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout z.c
char d[8];

#define A1 "123456"
#define A2 "654321"

const char a1[] = A1;
const char a2[] = A2;

void f7 (int i)
{
  __builtin_strcpy (d, i < 0 ? A1 : A2);

  if (__builtin_strlen (d) != sizeof A1 - 1)   // optimized
    __builtin_abort ();
}

void g7 (int i)
{
  __builtin_strcpy (d, i < 0 ? a1 : a2);

  if (__builtin_strlen (d) != sizeof a1 - 1)   // optimized
    __builtin_abort ();
}


#define B1 "1234567"
#define B2 "7654321"

const char b1[] = B1;
const char b2[] = B2;

void f8 (int i)
{
  __builtin_strcpy (d, i < 0 ? B1 : B2);

  if (__builtin_strlen (d) != sizeof B1 - 1)   // not optimized
    __builtin_abort ();
}

void g8 (int i)
{
  __builtin_strcpy (d, i < 0 ? B1 : B2);

  if (__builtin_strlen (d) != sizeof b1 - 1)   // not optimized
    __builtin_abort ();
}


;; Function f7 (f7, funcdef_no=0, decl_uid=1955, cgraph_uid=0, symbol_order=3)

f7 (int i)
{
  char[7] * iftmp.0_7;

  <bb 2> [local count: 1073741825]:
  if (i_3(D) < 0)
    goto <bb 4>; [36.00%]
  else
    goto <bb 3>; [64.00%]

  <bb 3> [local count: 687194769]:

  <bb 4> [local count: 1073312329]:
  # iftmp.0_7 = PHI <"123456"(2), "654321"(3)>
  __builtin_memcpy (&d, iftmp.0_7, 7); [tail call]
  return;

}



;; Function g7 (g7, funcdef_no=1, decl_uid=1958, cgraph_uid=1, symbol_order=4)

g7 (int i)
{
  const char * iftmp.1_7;

  <bb 2> [local count: 1073741825]:
  if (i_3(D) < 0)
    goto <bb 4>; [36.00%]
  else
    goto <bb 3>; [64.00%]

  <bb 3> [local count: 687194769]:

  <bb 4> [local count: 1073312329]:
  # iftmp.1_7 = PHI <&a1(2), &a2(3)>
  __builtin_memcpy (&d, iftmp.1_7, 7); [tail call]
  return;

}



;; Function f8 (f8, funcdef_no=2, decl_uid=1963, cgraph_uid=2, symbol_order=7)

f8 (int i)
{
  long unsigned int _1;
  long unsigned int _4;

  <bb 2> [local count: 1073741825]:
  if (i_3(D) < 0)
    goto <bb 3>; [36.00%]
  else
    goto <bb 4>; [64.00%]

  <bb 3> [local count: 386547056]:

  <bb 4> [local count: 1073741825]:
  # _4 = PHI <13847469359445559(2), 15540725856023089(3)>
  MEM[(char * {ref-all})&d] = _4;
  _1 = __builtin_strlen (&d);
  if (_1 != 7)
    goto <bb 5>; [0.00%]
  else
    goto <bb 6>; [99.96%]

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

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

}



;; Function g8 (g8, funcdef_no=5, decl_uid=1966, cgraph_uid=3, symbol_order=8)

g8 (int i)
{
  <bb 2> [local count: 1073741826]:
  f8 (i_2(D)); [tail call]
  return;

}

Reply via email to