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.

Reply via email to