Hello,

running the ABI compatibility test suite against another compiler showed
strange effects caused by code in ADJUST_FIELD_ALIGN on rs6000:

#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
  ((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE)    \
   ? 128                                                               \
   : (TARGET_64BIT                                                     \
      && TARGET_ALIGN_NATURAL == 0                                     \
      && TYPE_MODE (strip_array_types (TREE_TYPE (FIELD))) == DFmode)  \
   ? MIN ((COMPUTED), 32)                                               \
   : (COMPUTED))

The first test for VECTOR_TYPE if TARGET_ALTIVEC causes the trouble.
This has been present (in slight variations) ever since Altivec support
was first merged by Aldy Hernandez back in 2001:
https://gcc.gnu.org/ml/gcc-cvs/2001-11/msg00148.html

Note that at this time, both ADJUST_FIELD_ALIGN and ROUND_TYPE_ALIGN
contained that check.  The check was later removed from ROUND_TYPE_ALIGN
in the following patch intended to fix PR 17961:
https://gcc.gnu.org/ml/gcc-patches/2005-06/msg00920.html

The check has no effect in most usual cases anyway, since Altivec vectors
already carry a default alignment of 16 bytes.  However, the check *does*
affect non-Altivec vectors created via attribute((vector_size)) with a
size != 16.  When any of those is used as element of a struct, GCC on
PowerPC will ignore the normal alignment and always force 16 byte alignment.
(An explicit attribute((aligned)) however, is still respected.)  This
behavior seems to have been unintended.

In off-line discussions, we came to the conclusion that this check
should have been removed from ADJUST_FIELD_ALIGN at the same time
as it was removed from ROUND_TYPE_ALIGN.  This patch implements this.

Note that the check has been copied over time into the instances of
ADJUST_FIELD_ALIGN in sysv4.h, linux64.h, and freebsd64.h.  For
consistency, the patch removes the check in all these places.

Tested on powerpc64-linux and powerp64le-linux; built a cross-cc1
for powerpc64-freebsd6.

OK for mainline?
[ It may also be useful to backport to the currently open branches,
but the bug was already present in many releases that are no longer
maintained ... ]

Bye,
Ulrich


Index: gcc/config/rs6000/freebsd64.h
===================================================================
--- gcc/config/rs6000/freebsd64.h       (revision 212147)
+++ gcc/config/rs6000/freebsd64.h       (working copy)
@@ -365,13 +365,10 @@
 #define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO)
 
 /* PowerPC64 Linux word-aligns FP doubles when -malign-power is given.  */
-#undef  ADJUST_FIELD_ALIGN
 #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
-  ((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE)     \
-   ? 128                                                                \
-   : (TARGET_64BIT                                                      \
-      && TARGET_ALIGN_NATURAL == 0                                      \
-      && TYPE_MODE (strip_array_types (TREE_TYPE (FIELD))) == DFmode)   \
+  ((TARGET_64BIT                                                       \
+    && TARGET_ALIGN_NATURAL == 0                                       \
+    && TYPE_MODE (strip_array_types (TREE_TYPE (FIELD))) == DFmode)    \
    ? MIN ((COMPUTED), 32)                                               \
    : (COMPUTED))
 
Index: gcc/config/rs6000/linux64.h
===================================================================
--- gcc/config/rs6000/linux64.h (revision 212147)
+++ gcc/config/rs6000/linux64.h (working copy)
@@ -244,13 +244,10 @@
   do { if (TARGET_64BIT) output_profile_hook (LABEL); } while (0)
 
 /* PowerPC64 Linux word-aligns FP doubles when -malign-power is given.  */
-#undef  ADJUST_FIELD_ALIGN
 #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
-  ((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE)    \
-   ? 128                                                               \
-   : (TARGET_64BIT                                                     \
-      && TARGET_ALIGN_NATURAL == 0                                     \
-      && TYPE_MODE (strip_array_types (TREE_TYPE (FIELD))) == DFmode)  \
+  ((TARGET_64BIT                                                       \
+    && TARGET_ALIGN_NATURAL == 0                                       \
+    && TYPE_MODE (strip_array_types (TREE_TYPE (FIELD))) == DFmode)    \
    ? MIN ((COMPUTED), 32)                                              \
    : (COMPUTED))
 
Index: gcc/config/rs6000/sysv4.h
===================================================================
--- gcc/config/rs6000/sysv4.h   (revision 212147)
+++ gcc/config/rs6000/sysv4.h   (working copy)
@@ -289,12 +289,6 @@
 #define ABI_STACK_BOUNDARY \
   ((TARGET_EABI && !TARGET_ALTIVEC && !TARGET_ALTIVEC_ABI) ? 64 : 128)
 
-/* An expression for the alignment of a structure field FIELD if the
-   alignment computed in the usual way is COMPUTED.  */
-#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)                                  \
-       ((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE)     \
-        ? 128 : COMPUTED)
-
 #undef  BIGGEST_FIELD_ALIGNMENT
 
 /* Use ELF style section commands.  */
-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  ulrich.weig...@de.ibm.com

Reply via email to