https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80944
--- Comment #1 from Marc Glisse <glisse at gcc dot gnu.org> --- (In reply to Martin Sebor from comment #0) > struct S { char *s; unsigned n; }; > > void f (struct S *s) > { > __builtin_memset (s->s, 0, s->n); > __builtin_free (s->s); > __builtin_memset (s, 0, sizeof *s); > __builtin_free (s); > } If you replace the first 2 lines of f with char* t=s->s; __builtin_memset (t, 0, s->n); __builtin_free (t); we optimize away both memset just fine. Consider: struct S*s=malloc(sizeof(struct S)); s->s = s; s->n = sizeof(char*); f(s); that is, the first memset may modify s->s, so it cannot be removed.