This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/81435] New: missing strlen optimization for strcat past the beginning of clear array
- From: "msebor at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Thu, 13 Jul 2017 21:52:11 +0000
- Subject: [Bug tree-optimization/81435] New: missing strlen optimization for strcat past the beginning of clear array
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81435
Bug ID: 81435
Summary: missing strlen optimization for strcat past the
beginning of clear array
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: ---
The tree-ssa-strlen pass is able to track the lengths of some dynamically
created and modified strings by calls to strcpy and strcat. But in at least
one case where the strcat optimization could achieve parity with strcpy it does
not: when strcat is called to copy a string of known length pasty the beginning
of a zeroed-out buffer as is done in function g1() below the same optimization
done for strcpy is not done, and the pass loses track of the length of the
appended (copied) string.
$ cat a.c && gcc -O2 -S -Wall -Wextra -fdump-tree-strlen=/dev/stdout 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) // optimized into 3
__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 ();
}
;; Function f0 (f0, funcdef_no=0, decl_uid=1815, cgraph_uid=0, symbol_order=0)
f0 ()
{
char b[5];
char a[4];
long unsigned int _1;
<bb 2> [100.00%] [count: INV]:
a = "234";
b = "1";
__builtin_memcpy (&MEM[(void *)&b + 1B], &a, 4);
_1 = 3;
if (_1 != 3)
goto <bb 3>; [0.04%] [count: 0]
else
goto <bb 4>; [99.96%] [count: INV]
<bb 3> [0.04%] [count: 0]:
__builtin_abort ();
<bb 4> [99.96%] [count: INV]:
a ={v} {CLOBBER};
b ={v} {CLOBBER};
return;
}
;; Function f1 (f1, funcdef_no=1, decl_uid=1820, cgraph_uid=1, symbol_order=1)
f1 ()
{
char b[5];
char a[4];
long unsigned int _1;
<bb 2> [100.00%] [count: INV]:
a = "234";
b = "";
__builtin_memcpy (&MEM[(void *)&b + 1B], &a, 4);
_1 = 3;
if (_1 != 3)
goto <bb 3>; [0.04%] [count: 0]
else
goto <bb 4>; [99.96%] [count: INV]
<bb 3> [0.04%] [count: 0]:
__builtin_abort ();
<bb 4> [99.96%] [count: INV]:
a ={v} {CLOBBER};
b ={v} {CLOBBER};
return;
}
;; Function g0 (g0, funcdef_no=2, decl_uid=1825, cgraph_uid=2, symbol_order=2)
g0 ()
{
char b[5];
char a[4];
long unsigned int _1;
<bb 2> [100.00%] [count: INV]:
a = "234";
b = "1";
__builtin_memcpy (&MEM[(void *)&b + 1B], &a, 4);
_1 = 3;
if (_1 != 3)
goto <bb 3>; [0.04%] [count: 0]
else
goto <bb 4>; [99.96%] [count: INV]
<bb 3> [0.04%] [count: 0]:
__builtin_abort ();
<bb 4> [99.96%] [count: INV]:
a ={v} {CLOBBER};
b ={v} {CLOBBER};
return;
}
;; Function g1 (g1, funcdef_no=3, decl_uid=1830, cgraph_uid=3, symbol_order=3)
g1 ()
{
char b[5];
char a[4];
long unsigned int _1;
<bb 2> [100.00%] [count: INV]:
a = "234";
b = "";
__builtin_strcat (&MEM[(void *)&b + 1B], &a);
_1 = __builtin_strlen (&MEM[(void *)&b + 1B]);
if (_1 != 3)
goto <bb 3>; [0.04%] [count: 0]
else
goto <bb 4>; [99.96%] [count: INV]
<bb 3> [0.04%] [count: 0]:
__builtin_abort ();
<bb 4> [99.96%] [count: INV]:
a ={v} {CLOBBER};
b ={v} {CLOBBER};
return;
}