https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77728
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |alan.lawrence.arm at gmail dot com | |, ramana at gcc dot gnu.org, | |rearnsha at gcc dot gnu.org --- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Ugh, this seems to be a major ABI issue. The following patch ought to fix that: --- gcc/config/arm.c.jj 2017-04-11 19:06:53.000000000 +0200 +++ gcc/config/arm.c 2017-04-12 10:50:29.030494109 +0200 @@ -6472,7 +6472,7 @@ arm_needs_doubleword_align (machine_mode /* Record/aggregate types: Use greatest member alignment of any member. */ for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) - if (DECL_ALIGN (field) > PARM_BOUNDARY) + if (TREE_CODE (field) == FIELD_DECL && DECL_ALIGN (field) > PARM_BOUNDARY) return true; return false; at least the assembly (ignoring label numbers) for the comdat sections is then identical, for the second TU it is actually identical also with the assembly generated with unpatched compiler. The problem is that TYPE_FIELDS in C++ don't contain just FIELD_DECLs, but lots of other stuff, e.g. TYPE_DECLs, CONST_DECLs, FUNCTION_DECLs. And apparently in between the __gnu_cxx::__normal_iterator<std::pair<unsigned long long, unsigned long long>*, std::vector<std::pair<unsigned long long, unsigned long long>, std::allocator<std::pair<unsigned long long, unsigned long long> > > > type ends up with the value_type typedef in one of the TUs with DECL_ALIGN of 8, in another one of 64 and that causes the difference. Don't know exactly why that happens, there is C++ template instantiation and type canonicalization in play. Now, AAPCS latest version seems to say: "A Composite Type is a collection of one or more Fundamental Data Types that are handled as a single entity at the procedure call level. A Composite Type can be any of: - An aggregate, where the members are laid out sequentially in memory" ... "- The natural alignment of a composite type is the maximum of each of the member alignments of the 'top-level' members of the composite type i.e. before any alignment adjustment of the entire composite is applied" The important question here is whether "member" in the above text for C++ classes just stands for non-static data members (i.e. FIELD_DECLs) or if it stands for any members of the class. I hope it talks just about the FIELD_DECLs, talking say about static data members or member functions "laid out sequentially in memory" doesn't make any sense, in that case the above would be a bugfix to make GCC match the AAPCS wording. If not, the question is what other compilers do, and whether it is supportable at all that way. The patch changes ABI e.g. for: struct A { int i; static int k __attribute__((aligned (8))); }; A foo (int x, A y) { return y; } The difference between unpatched and patched compiler is: - mov r0, r2 + mov r0, r1 clang 4.0.0 (trunk 291659) generates the same code as patched gcc.