loongson-community / gcc

GCC source tree for Loongson
GNU General Public License v2.0
17 stars 1 forks source link

[tree-ssa-strlen] missing strlen optimization for strcat past the beginning of clear array #12

Open xiangzhai opened 6 years ago

xiangzhai commented 6 years ago

Hi fellows,

As PR81435 mentioned: Testcase:

$cat a.c
void f0 (void)
{
  char a[4] = "234";
  char b[5] = "1";

  __builtin_strcpy (b + 1, a);

  if (__builtin_strlen (b + 1) != 3)   // optimized into 3
    __builtin_abort ();
}

void f1 (void)
{
  char a[4] = "234";
  char b[5] = "";

  __builtin_strcpy (b + 1, a);

  if (__builtin_strlen (b + 1) != 3)   // optimized into 3
    __builtin_abort ();
}

void g0 (void)
{
  char a[4] = "234";
  char b[5] = "1";

  __builtin_strcat (b + 1, a);

  if (__builtin_strlen (b + 1) != 3)   // GCC 8.x optimized into 3, but GCC 5.5 failed
    __builtin_abort ();
}

void g1 (void)
{
  char a[4] = "234";
  char b[5] = "";

  __builtin_strcat (b + 1, a);

  if (__builtin_strlen (b + 1) != 3)   // not optimized
    __builtin_abort ();
}

GCC 8.x failed to optimize g1, GCC 5.5 failed for g0 and g1:

$ /opt/loongson-gnu-5.5/bin/mips64-linux-gnu-gcc -O2 -S -Wall -Wextra  -fdump-tree-strlen=/dev/stdout a.c

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

f0 ()
{
  char b[5];
  char a[4];
  long unsigned int _5;

  <bb 2>:
  a = "234";
  b = "1";
  __builtin_memcpy (&MEM[(void *)&b + 1B], &a, 4);
  _5 = 3;
  if (_5 != 3)
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3>:
  __builtin_abort ();

  <bb 4>:
  a ={v} {CLOBBER};
  b ={v} {CLOBBER};
  return;

}

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

f1 ()
{
  char b[5];
  char a[4];
  long unsigned int _5;

  <bb 2>:
  a = "234";
  b = "";
  __builtin_memcpy (&MEM[(void *)&b + 1B], &a, 4);
  _5 = 3;
  if (_5 != 3)
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3>:
  __builtin_abort ();

  <bb 4>:
  a ={v} {CLOBBER};
  b ={v} {CLOBBER};
  return;

}

;; Function g0 (g0, funcdef_no=2, decl_uid=1496, cgraph_uid=2, symbol_order=2)

g0 ()
{
  char b[5];
  char a[4];
  long unsigned int _5;

  <bb 2>:
  a = "234";
  b = "1";
  __builtin_strcat (&MEM[(void *)&b + 1B], &a);
  _5 = __builtin_strlen (&MEM[(void *)&b + 1B]);
  if (_5 != 3)
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3>:
  __builtin_abort ();

  <bb 4>:
  a ={v} {CLOBBER};
  b ={v} {CLOBBER};
  return;

}

;; Function g1 (g1, funcdef_no=3, decl_uid=1501, cgraph_uid=3, symbol_order=3)

g1 ()
{
  char b[5];
  char a[4];
  long unsigned int _5;

  <bb 2>:
  a = "234";
  b = "";
  __builtin_strcat (&MEM[(void *)&b + 1B], &a);
  _5 = __builtin_strlen (&MEM[(void *)&b + 1B]);
  if (_5 != 3)
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3>:
  __builtin_abort ();

  <bb 4>:
  a ={v} {CLOBBER};
  b ={v} {CLOBBER};
  return;

}

Regards, Leslie Zhai