[Bug c++/56564] movdqa on possibly-8-byte-aligned struct with -O3

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Mar 8 11:21:00 GMT 2013


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56564

--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> 2013-03-08 11:20:19 UTC ---
This is due to ix86_data_alignment, which has:

  /* x86-64 ABI requires arrays greater than 16 bytes to be aligned
     to 16byte boundary.  */
  if (TARGET_64BIT)
    {
      if (AGGREGATE_TYPE_P (type)
           && TYPE_SIZE (type)
           && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
           && (TREE_INT_CST_LOW (TYPE_SIZE (type)) >= 128
               || TREE_INT_CST_HIGH (TYPE_SIZE (type))) && align < 128)
        return 128;
    }

The comment and wording of
http://refspecs.linuxfoundation.org/elf/x86_64-abi-0.95.pdf
seems to be inconsistent with what the code does.
The comment and 0.95 version of the psABI only talks about arrays:
"An array uses the same alignment as its elements, except that a local or
global
array variable that requires at least 16 bytes, or a C99 local or global
variable-length array variable, always has alignment of at least 16 bytes."
but AGGREGATE_TYPE_P isn't solely about array local/global variables, but any
aggregates (arrays, structs, unions, ...).  ep apparently has size of 16 and
the above code aligns it to 16 bytes, but icc probably aligns it just to 8
bytes, as the maximum alignment of its members.  Now, changing the above to
only look at arrays would probably cause more harm than good, because while
code compiled by fixed gcc would be compatible with icc, it would be
incompatible with code compiled by older gcc.  Guess if we want to change
something, we'd need to change it in a way that such aggregates (non-array
ones) of size 16 and above are still 16-byte aligned, but if the variable isn't
known to bind locally, don't increase DECL_ALIGN of the var, so that no
optimizers actually rely on it.



More information about the Gcc-bugs mailing list