This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/81704] New: strncpy folding defeats strlen optimization
- 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, 03 Aug 2017 18:32:58 +0000
- Subject: [Bug tree-optimization/81704] New: strncpy folding defeats strlen optimization
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81704
Bug ID: 81704
Summary: strncpy folding 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: ---
Similar to bug 81703, when a call to strncpy() copies an initial sequence from
a string of known length without NUL-terminating the result, the
gimple_fold_builtin_strncpy function transforms the call into a direct memory
access. When the copy is immediately followed by setting the last element of
the destination to NUL the transformation then prevents a subsequent strlen
optimization that could otherwise take place (bug 81433 tracks the strncpy
optimization that's missing from tree-ssa-strlen). As a result, examples like
the one in the test case below are not optimized into optimal code.
As in bug 81703, I think the way to solve this is to defer the folding until
after the tree-ssa-strlen pass has run, similarly to how bug 77671 has been
handled.
$ cat a.c && gcc -O2 -S -Wall -Wextra -Wpedantic
-fdump-tree-optimized=/dev/stdout a.c
tree-optimized=/dev/stdout a.c
unsigned f (void)
{
char d[8];
__builtin_strcpy (d, "0123456");
return __builtin_strlen (d);
}
unsigned g (void)
{
char d[8];
__builtin_strncpy (d, "01234567", sizeof d);
d[sizeof d - 1] = '\0';
return __builtin_strlen (d);
}
;; Function f (f, funcdef_no=0, decl_uid=1815, cgraph_uid=0, symbol_order=0)
f ()
{
<bb 2> [100.00%] [count: INV]:
return 7;
}
;; Function g (g, funcdef_no=1, decl_uid=1819, cgraph_uid=1, symbol_order=1)
g ()
{
char d[8];
long unsigned int _1;
unsigned int _5;
<bb 2> [100.00%] [count: INV]:
MEM[(char * {ref-all})&d] = MEM[(char * {ref-all})"01234567"];
d[7] = 0;
_1 = __builtin_strlen (&d);
_5 = (unsigned int) _1;
d ={v} {CLOBBER};
return _5;
}