AIX word-aligns floating point doubles. This behavior also extends to double _Complex, which had been overlooked when compiler support for double _Complex was added.
This patch adds DCmode to the modes whose alignment is adjusted and adds a testcase to confirm the correct alignment. Bootstrapped on powerpc-ibm-aix7.2.3.0. gcc/ChangeLog: 2021-03-10 David Edelsohn <dje....@gmail.com> PR target/99492 * config/rs6000/aix.h (ADJUST_FIELD_ALIGN): Add check for DCmode. * config/rs6000/rs6000.c (rs6000_special_round_type_align): Same. gcc/testsuite/ChangeLog: 2021-03-10 David Edelsohn <dje....@gmail.com> PR target/99492 * gcc.target/powerpc/pr99492.c: New testcase. diff --git a/gcc/config/rs6000/aix.h b/gcc/config/rs6000/aix.h index 5e8743ab782..2db50c8007f 100644 --- a/gcc/config/rs6000/aix.h +++ b/gcc/config/rs6000/aix.h @@ -224,7 +224,8 @@ /* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints. */ #define ADJUST_FIELD_ALIGN(FIELD, TYPE, COMPUTED) \ ((TARGET_ALIGN_NATURAL == 0 \ - && TYPE_MODE (strip_array_types (TYPE)) == DFmode) \ + && (TYPE_MODE (strip_array_types (TYPE)) == DFmode \ + || TYPE_MODE (strip_array_types (TYPE)) == DCmode)) \ ? MIN ((COMPUTED), 32) \ : (COMPUTED)) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index c89fb6e124a..35ecf5ac9ab 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -7855,7 +7855,8 @@ rs6000_special_round_type_align (tree type, unsigned int computed, while (TREE_CODE (type) == ARRAY_TYPE) type = TREE_TYPE (type); - if (type != error_mark_node && TYPE_MODE (type) == DFmode) + if (type != error_mark_node + && (TYPE_MODE (type) == DFmode || TYPE_MODE (type) == DCmode)) align = MAX (align, 64); } diff --git a/gcc/testsuite/gcc.target/powerpc/pr99492.c b/gcc/testsuite/gcc.target/powerpc/pr99492.c new file mode 100644 index 00000000000..ae36cb3baf7 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr99492.c @@ -0,0 +1,50 @@ +/* { dg-do run { target { powerpc*-ibm-aix* } } } */ +/* { dg-options "" } */ + +void abort (void); + +struct A { + double _Complex a[64]; +}; + +struct B { + double b[64]; +}; + +struct C { + char c1; + double _Complex c2; +}; + +struct D { + char c1; + double c2; +}; + +int main() { + if (__alignof(double _Complex) != 8) + abort(); + + if (__alignof(struct A) != 8) + abort; + + if (__alignof(struct C) != 4) + abort; + + if (__builtin_offsetof(struct C, c2) != 4) + abort(); + + + if (__alignof(double) != 8) + abort(); + + if (__alignof(struct B) != 8) + abort(); + + if (__alignof(struct D) != 4) + abort(); + + if (__builtin_offsetof(struct D, c2) != 4) + abort(); + + return 0; +}