https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90766
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |missed-optimization Blocks| |83819 --- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> --- For the same reason, although GCC folds the strlen() computation in the first two functions into the difference N - i (where N is the known length of the string), it fails to do the same thing in the last instance (ditto when b is a char*). $ cat a.c && gcc -O2 -S -Wall -Wextra -Wpedantic -fdump-tree-optimized=/dev/stdout a.c typedef __SIZE_TYPE__ size_t; const char s[] = "123"; size_t f (unsigned i) { return __builtin_strlen (&s[i]); // folded to 3 - i } extern char a[8]; size_t g (unsigned i) { __builtin_strcpy (a, "123"); return __builtin_strlen (&s[i]); // folded to 3 - i } extern char b[]; size_t h (unsigned i) { __builtin_strcpy (b, "123"); return __builtin_strlen (&b[i]); // not folded but could be } ;; Function f (f, funcdef_no=0, decl_uid=1908, cgraph_uid=1, symbol_order=1) Removing basic block 5 f (unsigned int i) { sizetype _1; size_t iftmp.0_2; size_t iftmp.0_4; <bb 2> [local count: 1073741824]: if (i_3(D) <= 3) goto <bb 3>; [50.00%] else goto <bb 4>; [50.00%] <bb 3> [local count: 536870913]: _1 = (sizetype) i_3(D); iftmp.0_4 = 3 - _1; <bb 4> [local count: 1073741824]: # iftmp.0_2 = PHI <iftmp.0_4(3), 0(2)> return iftmp.0_2; } ;; Function g (g, funcdef_no=1, decl_uid=1912, cgraph_uid=2, symbol_order=2) Removing basic block 5 g (unsigned int i) { sizetype _1; size_t iftmp.1_2; size_t iftmp.1_6; <bb 2> [local count: 1073741824]: __builtin_memcpy (&a, "123", 4); if (i_5(D) <= 3) goto <bb 3>; [50.00%] else goto <bb 4>; [50.00%] <bb 3> [local count: 536870913]: _1 = (sizetype) i_5(D); iftmp.1_6 = 3 - _1; <bb 4> [local count: 1073741824]: # iftmp.1_2 = PHI <iftmp.1_6(3), 0(2)> return iftmp.1_2; } ;; Function h (h, funcdef_no=2, decl_uid=1916, cgraph_uid=3, symbol_order=3) h (unsigned int i) { char * _1; size_t _5; sizetype _6; <bb 2> [local count: 1073741824]: __builtin_memcpy (&b, "123", 4); _6 = (sizetype) i_4(D); _1 = &b + _6; _5 = __builtin_strlen (_1); [tail call] return _5; } Referenced Bugs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83819 [Bug 83819] [meta-bug] missing strlen optimizations