This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/81385] New: missing optimization involving strlen of arrays of known size
- 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: Mon, 10 Jul 2017 18:17:04 +0000
- Subject: [Bug tree-optimization/81385] New: missing optimization involving strlen of arrays of known size
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81385
Bug ID: 81385
Summary: missing optimization involving strlen of arrays of
known size
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: ---
A valid argument to the strlen() function that is an array of known size (or
that points to one) must contain a string whose length is less than the array
size. It is possible to rely on this guarantee to emit more efficient code
than without it. The test case below shows that GCC doesn't take advantage of
this optimization opportunity.
$ cat b.c && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout b.c
typedef __SIZE_TYPE__ size_t;
size_t strlen (const char*);
char a[7];
void f (void)
{
unsigned n = strlen (a);
if (n >= sizeof a) // can never hold
__builtin_abort (); // can be eliminated
}
struct S { char a[7]; int i; };
void g (const struct S *s)
{
unsigned n = strlen (s->a);
if (n >= sizeof s->a) // can never hold
__builtin_abort (); // can be eliminated
}
;; Function f (f, funcdef_no=0, decl_uid=1819, cgraph_uid=0, symbol_order=1)
f ()
{
unsigned int n;
long unsigned int _1;
<bb 2> [100.00%] [count: INV]:
_1 = strlen (&a);
n_3 = (unsigned int) _1;
if (n_3 > 6)
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]:
return;
}
;; Function g (g, funcdef_no=1, decl_uid=1826, cgraph_uid=1, symbol_order=2)
g (const struct S * s)
{
unsigned int n;
const char[7] * _1;
long unsigned int _2;
<bb 2> [100.00%] [count: INV]:
_1 = &s_3(D)->a;
_2 = strlen (_1);
n_5 = (unsigned int) _2;
if (n_5 > 6)
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]:
return;
}