[Bug tree-optimization/71120] [6/7 Regression] Aliasing "struct sockaddr_storage" produces invalid code due to SRA

rguenth at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue May 17 15:58:00 GMT 2016


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.


More information about the Gcc-bugs mailing list