When targeting AMD GPUs, the LLVM assembler (and linker) are used.

Two days ago LLVM changed the default for theAMDHSA code object version (COV) from 4 to 5. In principle, we do not care which COV is used as long as it works; unfortunately, "mkoffload.cc" also generates an object file directly, bypassing the AMD GPU compiler as it copies debugging data to that file. That object file must have the same COV version (ELF ABI version) as compiler + llvm-mc assembler generated files. In order to ensure those are the same, this patch forces the use of COV 4 instead of using the default. Once GCC requires LLVM >= 14 instead of LLVM >= 13.0.1 we could change it. (Assuming that COV 5 is sufficiently stable in LLVM 14.) - But for now COV 4 will do.
If you wonder how this LLVM issue shows up, simply compile any OpenMP
or OpenACC program with AMD GPU offloading and enable debugging ("-g"),
e.g.
  gcc -fopenmp -g test.f90 -foffload=amdgcn-amdhsa 
-foffload-options=-march=gfx908

With LLVM main (to become LLVM 18), you will then get the error:

  ld: error: incompatible ABI version: /tmp/ccAKx5cz.mkoffload.dbg.o

OK for mainline?

Tobias
gcn/gcn-hsa.h: Always pass --amdhsa-code-object-version= in ASM_SPEC

Since LLVM commit 082f87c9d418 (Pull Req. #79038; will become LLVM 18)
  "[AMDGPU] Change default AMDHSA Code Object version to 5"
the default - when no --amdhsa-code-object-version= is used - was bumped.

Using --amdhsa-code-object-version=5 is supported (with unknown limitations)
since LLVM 14. GCC required for proper support at least LLVM 13.0.1 such
that explicitly using COV5 is not possible.

Unfortunately, the COV number matters for debugging ("-g") as mkoffload.cc
extracts debugging data from the host's object file and writes into an
an AMD GPU object file it creates. And all object files linked together
must have the same ABI version. 

gcc/ChangeLog:

	* config/gcn/gcn-hsa.h (ABI_VERSION_SPEC): New; creates the
	"--amdhsa-code-object-version=" argument.
	(ASM_SPEC): Use it; replace previous version of it.

Signed-off-by: Tobias Burnus <tbur...@baylibre.com>

diff --git a/gcc/config/gcn/gcn-hsa.h b/gcc/config/gcn/gcn-hsa.h
index f5de0d2969f..e5b93f7d9e5 100644
--- a/gcc/config/gcn/gcn-hsa.h
+++ b/gcc/config/gcn/gcn-hsa.h
@@ -75,6 +75,21 @@ extern unsigned int gcn_local_sym_hash (const char *name);
    supported for gcn.  */
 #define GOMP_SELF_SPECS ""
 
+/* Explicitly set the ABI version; in principle, we could use just the
+   default; however, when debugging symbols are turned on, mkoffload.cc
+   writes a new AMD GPU object file and the ABI version needs to be the
+   same. - LLVM <= 17 defaults to 4 while LLVM >= 18 defaults to 5.
+   GCC supports LLVM >= 13.0.1 and only LLVM >= 14 supports version 5.
+   Note that Fiji is only suppored with LLVM <= 17 as version 3 i no longer
+   supported in LLVM >= 18.  */
+#define ABI_VERSION_SPEC "march=fiji:--amdhsa-code-object-version=3;" \
+			 "!march=*|march=*:--amdhsa-code-object-version=4"
+
+/* Note that the XNACK and SRAM-ECC settings must match those in mkoffload.cc
+   as the latter creates new ELF object file when debugging is enabled and
+   the ELF flags (e_flags) of that generated file must be identical to those
+   generated by the compiler.  */
+
 #define NO_XNACK "march=fiji:;march=gfx1030:;march=gfx1100:;" \
     /* These match the defaults set in gcn.cc.  */ \
     "!mxnack*|mxnack=default:%{march=gfx900|march=gfx906|march=gfx908:-mattr=-xnack};"
@@ -88,7 +103,7 @@ extern unsigned int gcn_local_sym_hash (const char *name);
 /* Use LLVM assembler and linker options.  */
 #define ASM_SPEC  "-triple=amdgcn--amdhsa "  \
 		  "%{march=*:-mcpu=%*} " \
-		  "%{!march=*|march=fiji:--amdhsa-code-object-version=3} " \
+		  "%{" ABI_VERSION_SPEC "} " \
 		  "%{" NO_XNACK XNACKOPT "} " \
 		  "%{" NO_SRAM_ECC SRAMOPT "} " \
 		  "%{march=gfx1030|march=gfx1100:-mattr=+wavefrontsize64} " \

Reply via email to