https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86075
Bug ID: 86075 Summary: dead store elimination defeats strlen optimization after memset zero followed by strcpy 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: --- GCC emits optimally efficient code for the first of the two equivalent functions below but generates very inefficient code for the latter. First, it zeroes out the entire array even though only a small part of it is used. Worse, (and ironically) because it eliminates the store to a[3] as dead early on (in fre1) and before the strlen pass runs, the strlen optimization isn't performed, and so the entire dead body of the function isn't eliminated. Since unnecessarily zeroing-out storage just before storing strings in it is common practice, detecting and handling it could lead to significant improvements. The solution for the missing strlen optimization in this case could be as simple as enhancing the strlen pass to track not just string lengths but also sizes of zeroed-out blocks of storage used for strings. $ cat c.c && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout c.c void f (void) { char a[4096]; __builtin_memcpy (a, "123", 3); a[3] = 0; if (__builtin_strlen (a) != 3) // folded __builtin_abort (); } void g (void) { char a[4096] = ""; // all bytes zeroed out __builtin_memcpy (a, "123", 3); a[3] = 0; // eliminated if (__builtin_strlen (a) != 3) // not folded __builtin_abort (); } ;; Function f (f, funcdef_no=0, decl_uid=1956, cgraph_uid=0, symbol_order=0) f () { <bb 2> [local count: 1073741825]: return; } ;; Function g (g, funcdef_no=1, decl_uid=1960, cgraph_uid=1, symbol_order=1) g () { char a[4096]; long unsigned int _1; <bb 2> [local count: 1073741825]: a = ""; __builtin_memcpy (&a, "123", 3); _1 = __builtin_strlen (&a); if (_1 != 3) goto <bb 3>; [0.00%] else goto <bb 4>; [99.96%] <bb 3> [count: 0]: __builtin_abort (); <bb 4> [local count: 1073312327]: a ={v} {CLOBBER}; return; }