https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92714
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2019-11-28 CC| |law at gcc dot gnu.org Summary|[missed-optimization] |[missed-optimization] |aggregate initialization of |aggregate initialization of |an array fills the whole |an array fills the whole |array with zeros first, |array with zeros first, |including non-zero elements |including leading non-zero | |elements Ever confirmed|0 |1 --- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> --- It's actually an optimization - it's cheaper to clear the whole object if most of it is zero. What we miss is to notice the special-case of only the tail being zeros. Jeff added memset pruning to DSE but this case has <bb 2> [local count: 1073741824]: a = {}; MEM <unsigned long> [(int *)&a] = 8589934593; MEM <unsigned long> [(int *)&a + 8B] = 17179869187; sink = &a; the other obvious place to fix it is in the gimplifier of course which creates the above code in the first place. The same issue happens with void *sink; void bar() { int a[100] = { [96]=1,2,3,4}; sink = a; // a escapes the function asm("":::"memory"); // and compiler memory barrier // forces the compiler to materialize a[] in memory instead of optimizing away } or void *sink; void bar() { int a[100] = { 1,2,3,4,[96]=1,2,3,4}; sink = a; // a escapes the function asm("":::"memory"); // and compiler memory barrier // forces the compiler to materialize a[] in memory instead of optimizing away } though the trailing zeros are probably the most common case.