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.