https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71120
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jamborm at gcc dot gnu.org Summary|[6/7 Regression] Aliasing |[6/7 Regression] Aliasing |"struct sockaddr_storage" |"struct sockaddr_storage" |produces invalid code |produces invalid code due | |to SRA --- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- Actually the issue is that SRA decomposes the aggregate assignment in a way leaving the "interesting" piece out. sin_addr.s_addr is at offset 4 bytes and 4 bytes in size while the scalarization ss$ss_family_13 = MEM[(struct sockaddr_storage *)&ss3]; ss$__ss_align_4 = MEM[(struct sockaddr_storage *)&ss3 + 8B]; fails to cover that area. It scalarizes struct sockaddr_storage { sa_family_t ss_family; unsigned long int __ss_align; char __ss_padding[(128 - (2 * sizeof (unsigned long int)))]; }; but the actual data is of type struct sockaddr_in { sa_family_t sin_family; in_port_t sin_port; struct in_addr sin_addr; unsigned char sin_zero[sizeof (struct sockaddr) - (sizeof (unsigned short int)) - sizeof (in_port_t) - sizeof (struct in_addr)]; }; so somehow it applies "strict aliasing" rules when fully scalarizing the block copy. That needs to be fixed (with -fno-strict-aliasing an aggregate copy needs to copy all padding). In this case the scalarization is also very inefficiently using chars around the calloc call which will force us to spill all the regs anyway. All this worked in GCC 5 because somehow we didn't consider to scalarize ss in the end: Candidate (4191): ss Rejected (4190): not aggregate: l ! Disqualifying ss - No scalar replacements to be created. but I think we're just lucky here. Relevant accesses should be built from the aggregate assignment l_11->addr = ss; which is again of sockaddr_storage type. sockaddr_storage should really have the may_alias attribute (but in this case this won't help I think). To recap, with -fno-strict-aliasing the code is valid and should work. With -fstrict-aliasing the code is bogus and should use memcpy and not aggregate assignment for both ss = *ss2 and l->addr = ss.