Eric Botcazou wrote:
Technically this is incorrect since AGGREGATE_TYPE_P includes ARRAY_TYPE
and ARRAY_TYPE doesn't have TYPE_FIELDS.  I doubt we could reach that
case though (unless there's a language that allows passing arrays by value).

Ada passes small array types by the method specified by the pass_by_reference hook (and large array types by reference).

Ok, thanks. Here's a revised patch that handles array types. Again I've tested on both trunk (bootstrap + check-gcc) and gcc-5-branch (profiledbootstrap now succeeding + check-gcc). Jakub's pr65956.c testcase also now passes.

The new code lacks a testcase; from what Eric says, it's possible we can write one using Ada, but I don't know any Ada myself, so I think any testcase should follow in a separate patch.

Neither have I managed to run a check-ada yet, as I don't presently have a working Ada compiler with which to bootstrap gcc's Ada frontend. Working on this now.

--Alan

gcc/ChangeLog:

        * config/arm/arm.c (arm_needs_doubleword_align) : Drop any outer
        alignment attribute, exploring one level down for records and arrays.
commit f8bd310d65f2b8fd8d7e1151a4a1f84489738029
Author: Alan Lawrence <alan.lawre...@arm.com>
Date:   Wed Jun 3 18:22:36 2015 +0100

    arm_needs_doubleword_align: explore one level for aggregates, also arrays.

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index e79a369..e12198a 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -6151,8 +6151,23 @@ arm_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype,
 static bool
 arm_needs_doubleword_align (machine_mode mode, const_tree type)
 {
-  return (GET_MODE_ALIGNMENT (mode) > PARM_BOUNDARY
-	  || (type && TYPE_ALIGN (type) > PARM_BOUNDARY));
+  if (!type)
+    return PARM_BOUNDARY < GET_MODE_ALIGNMENT (mode);
+
+  /* Scalar and vector types: Use natural alignment, i.e. of base type.  */
+  if (!AGGREGATE_TYPE_P (type))
+    return TYPE_ALIGN (TYPE_MAIN_VARIANT (type)) > PARM_BOUNDARY;
+
+  /* Array types: Use member alignment of element type.  */
+  if (TREE_CODE (type) == ARRAY_TYPE)
+    return TYPE_ALIGN (TREE_TYPE (type)) > PARM_BOUNDARY;
+
+  /* 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)
+      return true;
+
+  return false;
 }
 
 

Reply via email to