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))))