https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92408
Bug ID: 92408
Summary: strlen(s) != 0 not folded into *s
Product: gcc
Version: 10.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: msebor at gcc dot gnu.org
Target Milestone: ---
In simple expressions, GCC folds strlen(*s) calls whose result is only used in
a test for equality with zero to tests for the first character being nul. But
it does only a superficial job and doesn't also do the same folding when the
result is stored in a variable that is then tested for the same equality.
Clang folds both.
$ cat z.c && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout z.c
void f (void);
void g (const char *s)
{
if (__builtin_strlen (s)) // folded to if (*s)
f ();
}
void h (const char *s)
{
__SIZE_TYPE__ n = __builtin_strlen (s);
if (n) // not folded into if (*s) but could be
f ();
}
;; Function g (g, funcdef_no=0, decl_uid=1932, cgraph_uid=1, symbol_order=0)
Removing basic block 5
g (const char * s)
{
char _1;
<bb 2> [local count: 1073741824]:
_1 = *s_4(D);
if (_1 != 0)
goto <bb 3>; [33.00%]
else
goto <bb 4>; [67.00%]
<bb 3> [local count: 354334802]:
f (); [tail call]
<bb 4> [local count: 1073741824]:
return;
}
;; Function h (h, funcdef_no=1, decl_uid=1935, cgraph_uid=2, symbol_order=1)
Removing basic block 5
h (const char * s)
{
long unsigned int n;
<bb 2> [local count: 1073741824]:
n_4 = __builtin_strlen (s_3(D));
if (n_4 != 0)
goto <bb 3>; [33.00%]
else
goto <bb 4>; [67.00%]
<bb 3> [local count: 354334802]:
f (); [tail call]
<bb 4> [local count: 1073741824]:
return;
}