While working with Uli on the PPC64 LE ELFv2 implementation, we
discovered that one of the changes to argument passing introduced new
regressions in the struct-layout part of the testsuite, which should
not have changed.

Uli tracked this down to a change in the mode for multi-register
parameters that caused a change in the traceback tables that changed
the size of the text section that changed the placement and alignment
of the data section.  The struct-layout tests were failing in the
initial alignment verification.

The tests use a type v16sf, which requires alignment of 512. GCC
aligns the default ".data" CSECT on AIX to 64 bits and the alignment
is not automatically increased to the largest alignment specified
within the CSECT.  GCC specified alignment of 512 for the symbol, but
the overall CSECT was less-strictly aligned, so the alignment was not
satisfied and some tests passed due to luck.

The tests only failed when compiled with C++ and not C. GCC annotates
uninitialized C variables as COMMON, but G++ does not. The AIX XCOFF
common section adopts the alignment of the strictest symbol.

AIX XCOFF was intended to always use the equivalent of GCC
-fdata-sections where each symbol is placed in its own CSECT.  This
patch places variables more strictly aligned than BIGGEST_ALIGNMENT
into their own, named sections to achieve the necessary alignment
without increasing the alignment of the entire, default data CSECT.

With this change, all struct-layout tests pass on AIX.

Bootstrapped on powerpc-ibm-aix7.1.0.0.

Thanks, David


    * config/rs6000/rs6000.c (IN_NAMED_SECTION): New macro.
    (rs6000_xcoff_select_section): Place decls with stricter alignment
    into named sections.
    (rs6000_xcoff_unique_section): Allow unique sections for
    uninitialized data with strict alignment.

Index: rs6000.c
===================================================================
--- rs6000.c    (revision 205307)
+++ rs6000.c    (working copy)
@@ -28588,10 +28588,23 @@
        name, suffix[smclass], flags & SECTION_ENTSIZE);
 }

+#define IN_NAMED_SECTION(DECL) \
+  ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \
+   && DECL_SECTION_NAME (DECL) != NULL_TREE)
+
 static section *
 rs6000_xcoff_select_section (tree decl, int reloc,
-                 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
+                 unsigned HOST_WIDE_INT align)
 {
+  /* Place variables with alignment stricter than BIGGEST_ALIGNMENT into
+     named section.  */
+  if (align > BIGGEST_ALIGNMENT)
+    {
+      resolve_unique_section (decl, reloc, true);
+      if (IN_NAMED_SECTION (decl))
+    return get_named_section (decl, NULL, reloc);
+    }
+
   if (decl_readonly_section (decl, reloc))
     {
       if (TREE_PUBLIC (decl))
@@ -28629,10 +28642,12 @@
 {
   const char *name;

-  /* Use select_section for private and uninitialized data.  */
+  /* Use select_section for private data and uninitialized data with
+     alignment <= BIGGEST_ALIGNMENT.  */
   if (!TREE_PUBLIC (decl)
       || DECL_COMMON (decl)
-      || DECL_INITIAL (decl) == NULL_TREE
+      || (DECL_INITIAL (decl) == NULL_TREE
+      && DECL_ALIGN (decl) <= BIGGEST_ALIGNMENT)
       || DECL_INITIAL (decl) == error_mark_node
       || (flag_zero_initialized_in_bss
       && initializer_zerop (DECL_INITIAL (decl))))

Reply via email to