https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83821
Bug ID: 83821 Summary: local aggregate initialization defeats strlen optimization 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: --- For the test case below, GCC optimizes the strlen call in f() but fails to do the same in g(). It appears because the maybe_invalidate() function in the pass considers the initialization of/assignment to b.i as possibly clobbering the value of b.s, not realizing that there is no way for the two members to alias. $ cat z.c && gcc -O2 -S -fdump-tree-optimized=/dev/stdout z.c #define STR "0123456789" struct A { char s[sizeof STR]; }; void f (void) { struct A a = { STR }; if (__builtin_strlen (a.s) != sizeof STR - 1) // folded __builtin_abort (); // eliminated } struct B { char s[sizeof STR]; int i; }; void g (void) { struct B b = { STR, 123 }; if (__builtin_strlen (b.s) != sizeof STR - 1) // not folded __builtin_abort (); // not eliminated } ;; Function f (f, funcdef_no=0, decl_uid=1952, cgraph_uid=0, symbol_order=0) f () { <bb 2> [local count: 1073741825]: return; } ;; Function g (g, funcdef_no=1, decl_uid=1959, cgraph_uid=1, symbol_order=1) g () { struct B b; long unsigned int _1; <bb 2> [local count: 1073741825]: b.s = "0123456789"; b.i = 123; _1 = __builtin_strlen (&b.s); if (_1 != 10) goto <bb 3>; [0.00%] else goto <bb 4>; [99.96%] <bb 3> [count: 0]: __builtin_abort (); <bb 4> [local count: 1073312327]: b ={v} {CLOBBER}; return; }