https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61619
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |ASSIGNED CC| |jamborm at gcc dot gnu.org Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org --- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- ._94/3491 (constexpr const long unsigned int ._94 [1]) @0x7ffff1d5ca90 Type: variable definition analyzed Visibility: prevailing_def_ironly artificial References: Referring: main/3232 (read) Availability: available Varpool flags: initialized read-only const-value-known Ok, for the above SRA fails to do a scalar replacement and value-numbering doesn't even reach the aggregate copy from the constant initializer. That's because only PRE exposes it and PRE doesn't do all the fancy VN tricks. I suppose I have to look closer at some point. Interesting testcase showing possible issues with C++ constexpr initializers. Note that we also have MEM[(char * {ref-all})&S] = MEM[(char * {ref-all})&._94]; but this aggregate copy has sizeof (long) so we could have optimized it (it's ref-all already) to use an integer type. This is lowered from array<long unsigned int, 1ul>::array (&S, (const struct initializer_list &) &TARGET_EXPR <D.64552, {._M_array=(const long unsigned int *) &._94, ._M_len=1}>) to D.64552._M_array = &._94; D.64552._M_len = 1; try { array<long unsigned int, 1ul>::array (&S, &D.64552); } which eventually ends up calling memmove which we optimize to the aggregate assignment.