aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/gcn
diff options
context:
space:
mode:
authorTobias Burnus <tburnus@baylibre.com>2025-02-10 18:24:34 +0100
committerTobias Burnus <tburnus@baylibre.com>2025-02-10 18:24:34 +0100
commit4ce8ad684b90606a74f0cccfd9455184046c6c4e (patch)
tree525f5a4fb6b5f965d7d29da0931716c09a5cc44c /gcc/config/gcn
parent7037fdf6bd0a4eea4a436b432265d6b7cc481737 (diff)
downloadgcc-4ce8ad684b90606a74f0cccfd9455184046c6c4e.zip
gcc-4ce8ad684b90606a74f0cccfd9455184046c6c4e.tar.gz
gcc-4ce8ad684b90606a74f0cccfd9455184046c6c4e.tar.bz2
[gcn] mkoffload.cc: Print fatal error if -march has no multilib but generic has
Assume that a distro has configured, e.g., a gfx9-generic multilib but not for gfx902. In that case, mkoffload would fail to link with "error: incompatible mach". With this commit, an error is printed suggesting to try the associated generic architecture instead. The behavior is unchanged if there is a multilib available for the specific ISA or when there is also no multilib for the generic ICA. Note: The build of generic multilibs are currently not enabled by default; they also require the linker/assembler of LLVM 19 or newer and, in particular, for the execution a future ROCm release. (The next one? In any case, 6.3.2 does not support generic ISAs, yet.) gcc/ChangeLog: * config/gcn/mkoffload.cc (enum elf_arch_code): Add EF_AMDGPU_MACH_AMDGCN_NONE. (elf_arch): Use enum elf_arch_code as type. (tool_cleanup): Silence warning by removing tailing '.' from error. (get_arch_name): Return enum elf_arch_code. (check_for_missing_lib): New; print fatal error if the multilib is not available but it is for the associate generic ISA. (main): Call it.
Diffstat (limited to 'gcc/config/gcn')
-rw-r--r--gcc/config/gcn/mkoffload.cc101
1 files changed, 94 insertions, 7 deletions
diff --git a/gcc/config/gcn/mkoffload.cc b/gcc/config/gcn/mkoffload.cc
index 92e8fe7..fbd68a6 100644
--- a/gcc/config/gcn/mkoffload.cc
+++ b/gcc/config/gcn/mkoffload.cc
@@ -53,6 +53,7 @@
/* Extract the EF_AMDGPU_MACH_AMDGCN_GFXnnn from the def file. */
enum elf_arch_code {
+ EF_AMDGPU_MACH_AMDGCN_NONE = -1, /* For generic handling. */
#define GCN_DEVICE(name, NAME, ELF_ARCH, ...) \
EF_AMDGPU_MACH_AMDGCN_ ## NAME = ELF_ARCH,
#include "gcn-devices.def"
@@ -135,9 +136,8 @@ static struct obstack files_to_cleanup;
enum offload_abi offload_abi = OFFLOAD_ABI_UNSET;
const char *offload_abi_host_opts = NULL;
-uint32_t elf_arch = EF_AMDGPU_MACH_AMDGCN_GFX900; // Default GPU architecture.
+enum elf_arch_code elf_arch = EF_AMDGPU_MACH_AMDGCN_GFX900; // Default GPU architecture.
uint32_t elf_flags = EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4;
-
static int gcn_stack_size = 0; /* Zero means use default. */
/* Delete tempfiles. */
@@ -782,7 +782,7 @@ compile_native (const char *infile, const char *outfile, const char *compiler,
obstack_ptr_grow (&argv_obstack, ".c");
if (!offload_abi_host_opts)
fatal_error (input_location,
- "%<-foffload-abi-host-opts%> not specified.");
+ "%<-foffload-abi-host-opts%> not specified");
obstack_ptr_grow (&argv_obstack, offload_abi_host_opts);
obstack_ptr_grow (&argv_obstack, infile);
obstack_ptr_grow (&argv_obstack, "-c");
@@ -796,16 +796,15 @@ compile_native (const char *infile, const char *outfile, const char *compiler,
obstack_free (&argv_obstack, NULL);
}
-static int
+static enum elf_arch_code
get_arch (const char *str, const char *with_arch_str)
{
/* Use the def file to map the name to the elf_arch_code. */
if (!str) ;
#define GCN_DEVICE(name, NAME, ELF, ...) \
else if (strcmp (str, #name) == 0) \
- return ELF;
+ return (enum elf_arch_code) ELF;
#include "gcn-devices.def"
-#undef GCN_DEVICE
/* else */
error ("unrecognized argument in option %<-march=%s%>", str);
@@ -839,7 +838,91 @@ get_arch (const char *str, const char *with_arch_str)
exit (FATAL_EXIT_CODE);
- return 0;
+ return EF_AMDGPU_MACH_AMDGCN_NONE;
+}
+
+static const char*
+get_arch_name (enum elf_arch_code arch_code)
+{
+ switch (arch_code)
+ {
+#define GCN_DEVICE(name, NAME, ELF, ...) \
+ case EF_AMDGPU_MACH_AMDGCN_ ## NAME: \
+ return #name;
+#include "../../gcc/config/gcn/gcn-devices.def"
+ default: return NULL;
+ }
+}
+
+/* If an generic arch exists and for the chosen arch no (multi)lib is
+ available, print a fatal error - and suggest to compile for the generic
+ version instead. */
+
+static void
+check_for_missing_lib (enum elf_arch_code elf_arch,
+ enum elf_arch_code default_arch)
+{
+ enum elf_arch_code generic_arch;
+ switch (elf_arch)
+ {
+#define GCN_DEVICE(name, NAME, ELF, ISA, XNACK, SRAM, WAVE64, CU, \
+ MAX_ISA_VGPRS, GEN_VER, ARCH_FAM, GEN_MACH, ...) \
+ case EF_AMDGPU_MACH_AMDGCN_ ## NAME: \
+ generic_arch = EF_AMDGPU_MACH_AMDGCN_ ## GEN_MACH; break;
+#include "../../gcc/config/gcn/gcn-devices.def"
+ default: generic_arch = EF_AMDGPU_MACH_AMDGCN_NONE;
+ }
+
+ /* If not generic or the default arch, the library version exists. */
+ if (generic_arch == EF_AMDGPU_MACH_AMDGCN_NONE || elf_arch == default_arch)
+ return;
+
+ /* Search gcn_arch in the multilib config, which might look like
+ "march=gfx900/march=gfx906". */
+ const char *p = multilib_options;
+ const char *q = NULL;
+ const char *isa_name = get_arch_name (elf_arch);
+ while ((q = strstr (p, isa_name)) != NULL)
+ {
+ if (multilib_options + strlen ("march=") <= q
+ && startswith (&q[-strlen ("march=")], "march="))
+ {
+ const char r = q[strlen (isa_name)];
+ if (r != '\0' && r != '/')
+ continue;
+ break;
+ }
+ p++;
+ }
+
+ /* Specified -march= exists in the multilib. */
+ if (q != NULL)
+ return;
+
+ /* If no lib, try to find one for the generic arch. */
+ const char *gen_name = get_arch_name (generic_arch);
+ if (generic_arch != default_arch)
+ {
+ p = multilib_options;
+ while ((q = strstr (p, gen_name)) != NULL)
+ {
+ if (multilib_options + strlen ("march=") <= q
+ && startswith (&q[-strlen ("march=")], "march="))
+ {
+ const char r = q[strlen (gen_name)];
+ if (r != '\0' && r != '/')
+ continue;
+ break;
+ }
+ p++;
+ }
+ if (q == NULL)
+ return;
+ }
+ fatal_error (UNKNOWN_LOCATION,
+ "GCC was built without library support for %<-march=%s%>; "
+ "consider compiling for the associated generic architecture "
+ "%<-march=%s%> instead", isa_name, gen_name);
}
int
@@ -864,6 +947,7 @@ main (int argc, char **argv)
elf_arch = get_arch (configure_default_options[0].value, NULL);
break;
}
+ enum elf_arch_code default_arch = elf_arch;
obstack_init (&files_to_cleanup);
if (atexit (mkoffload_cleanup) != 0)
@@ -998,6 +1082,8 @@ main (int argc, char **argv)
}
}
+ check_for_missing_lib (elf_arch, default_arch);
+
if (!(fopenacc ^ fopenmp))
fatal_error (input_location,
"either %<-fopenacc%> or %<-fopenmp%> must be set");
@@ -1056,6 +1142,7 @@ main (int argc, char **argv)
case ELF: if (GEN_VER) SET_GENERIC_VERSION (elf_flags, GEN_VER); break;
#include "gcn-devices.def"
#undef GCN_DEVICE
+ case EF_AMDGPU_MACH_AMDGCN_NONE: gcc_unreachable ();
}
/* Build arguments for compiler pass. */