As noted by Matthias when bootstrapping with AMD GCN support [PR97827]:
Assembler source code generated by GCC might no longer assembly with
LLVM's 'mc' since LLVM 11.

The reason is that GCC generates on purpose first the section with
the flags, e.g. (via mergeable_constant_section)
   .section        .rodata.cst8,"aM",@progbits,8
and then for subsequent uses, it does not repeat the flags:
   .section        .rodata.cst8

GNU assembler warns (and with as >=2.35 gives an error) if the flags
do not match, but not if the attributes/flags are left in the other
same-named sections (as above) – just if they are specified and different.

LLVM since February (in git) and released with LLVM 11 (12 Oct 2020)
does a similar check – but without the no-error-if-no-flag exception:
  strtod.s:4472:2: error: changed section flags for .rodata.cst8, expected: 0x12
  strtod.s:4472:2: error: changed section entsize for .rodata.cst8, expected: 8


The solution done by the attached patch is to emit the full flags also
for SECTION_MERGE.

Side note: For AMD GCN, we rely on LLVM as "GNU as" does not handle
this target, yet; still, also in general, it makes sense to be
compatible with llvm-mc.

OK?

Tobias

References:
- GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97827
  with some analysis and quotes from LLVM MC and GNU AS
- Filled https://bugs.llvm.org/show_bug.cgi?id=48201 about this
  issue but no one commented on that issue so far
- Added to LLVM with commit https://reviews.llvm.org/D73999
- Some alignment was tried with GNU as (see all three links
  above) but the only "if (attr != 0)" then do check of
  gas/config/obj-elf.c was missed when implementing the
    if (Section->getType() != Type)
  in LLVM MC.

-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander 
Walter
varasm.c: Always output flags in merged .section for LLVM assembler compatibility [PR97827]

For compatibility with LLVM 11's 'mc' assembler, the flags have to be
repeated every time. See also LLVM Bug 48201 for this issue and
https://reviews.llvm.org/D73999 for the patch causing the issue.

gcc/
	PR target/97827
	* varasm.c (default_elf_asm_named_section): Always output all
	flags if SECTION_MERGE, even if already declared before.

diff --git a/gcc/varasm.c b/gcc/varasm.c
index ada99940f65..51a507393a8 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6738,9 +6738,11 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
   /* If we have already declared this section, we can use an
      abbreviated form to switch back to it -- unless this section is
      part of a COMDAT groups, in which case GAS requires the full
-     declaration every time.  */
+     declaration every time.  LLVM's MC linker requires that the
+     flags are identical, thus avoid the abbreviated form with MERGE.  */
   if (!(HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
-      && (flags & SECTION_DECLARED))
+      && (flags & SECTION_DECLARED)
+      && !(flags & SECTION_MERGE))
     {
       fprintf (asm_out_file, "\t.section\t%s\n", name);
       return;

Reply via email to