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.