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;
}