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