https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92486
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |wrong-code CC| |law at gcc dot gnu.org --- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- Yes, memcpy of course needs to copy padding. So the issue is that with f (struct s * p, struct s * q) { struct s w; long unsigned int _4; long unsigned int _8; <bb 2> : w = *q_2(D); _4 = MEM[(char * {ref-all})q_2(D)]; MEM[(char * {ref-all})&w] = _4; *p_6(D) = w; _8 = MEM[(char * {ref-all})&w]; MEM[(char * {ref-all})p_6(D)] = _8; w ={v} {CLOBBER}; return; we view assignments of the form w = *q_2(D); or *p_6(D) = w; as killing definitions and "loads" like *q_2(D) as loading all bytes. This leads value-numbering to the conclusion that MEM[(char * {ref-all})&w] = _4; is a redundant store. The same reasoning would lead DSE to think that the store to the padding is "dead" for __attribute__((noinline,noclone)) void g(struct s *p, struct s * __restrict q) { *((char *)p + 1) = 3; *p = *q; } where it elides the store of 3. Aggregate assignments are bad. The revs. in question don't really address this cases but merely happen to fix one or another case (here because of the intent to preserve the dynamic-type changing store). Of course it's again SRA that "exposes" the individual fields when scalarizing an aggregate copy, defeating the alias machinerys view of the IL (but IIRC RTL expansion shares SRAs view, even if that's not appearant in this testcase?). Now as an exercise build a complete testcase for the DSE issue above.