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