[Bug tree-optimization/86075] New: dead store elimination defeats strlen optimization after memset zero followed by strcpy
msebor at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu Jun 7 00:06:00 GMT 2018
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86075
Bug ID: 86075
Summary: dead store elimination defeats strlen optimization
after memset zero followed by strcpy
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 emits optimally efficient code for the first of the two equivalent
functions below but generates very inefficient code for the latter. First, it
zeroes out the entire array even though only a small part of it is used.
Worse, (and ironically) because it eliminates the store to a[3] as dead early
on (in fre1) and before the strlen pass runs, the strlen optimization isn't
performed, and so the entire dead body of the function isn't eliminated.
Since unnecessarily zeroing-out storage just before storing strings in it is
common practice, detecting and handling it could lead to significant
improvements. The solution for the missing strlen optimization in this case
could be as simple as enhancing the strlen pass to track not just string
lengths but also sizes of zeroed-out blocks of storage used for strings.
$ cat c.c && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout c.c
void f (void)
{
char a[4096];
__builtin_memcpy (a, "123", 3);
a[3] = 0;
if (__builtin_strlen (a) != 3) // folded
__builtin_abort ();
}
void g (void)
{
char a[4096] = ""; // all bytes zeroed out
__builtin_memcpy (a, "123", 3);
a[3] = 0; // eliminated
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 ()
{
char a[4096];
long unsigned int _1;
<bb 2> [local count: 1073741825]:
a = "";
__builtin_memcpy (&a, "123", 3);
_1 = __builtin_strlen (&a);
if (_1 != 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;
}
More information about the Gcc-bugs
mailing list