[Bug tree-optimization/92486] Wrong optimization: padding in structs is not copied even with memcpy
rguenth at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Nov 13 11:45:00 GMT 2019
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.
More information about the Gcc-bugs
mailing list