https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86061
Bug ID: 86061 Summary: dead memset followed by strncpy and assignment not eliminated 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: --- This is similar to bug 86010 except the optimization is absent from all versions of GCC all the way back to 4.1. In the test case below the memset call zeroes out the entire destination array, only to have its contents overwritten by the subsequent call to strncpy followed by the write to its last element. Rather than eliminating the memset call and keeping the single-character store GCC does the opposite, which is obviously suboptimal. This code is reduced from code that's idiomatic in the Linux kernel when copying between kernel data (that's not necessarily nul-terminated) and user-space strings (which are expected to be nul-terminated). $ cat c.c && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout c.c struct S { int i; char n[256]; int j; }; void f (char*); void g (struct S *p) { char a[sizeof p->n + 1]; __builtin_memset (a, 0, sizeof a); // dead store, can be eliminated __builtin_strncpy (a, p->n, sizeof a - 1); a[sizeof a - 1] = '\0'; f (a); } ;; Function g (g, funcdef_no=0, decl_uid=1964, cgraph_uid=0, symbol_order=0) g (struct S * p) { char a[257]; char[256] * _1; <bb 2> [local count: 1073741825]: __builtin_memset (&a, 0, 257); _1 = &p_4(D)->n; __builtin_strncpy (&a, _1, 256); f (&a); a ={v} {CLOBBER}; return; }