[clang] [Clang] Clean up OpenMP offload toolchain generation (PR #145549)
Joseph Huber via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 24 09:46:39 PDT 2025
https://github.com/jhuber6 created https://github.com/llvm/llvm-project/pull/145549
Summary:
Small cleanup prior to some larger changes in this area. I want to move
the offload arch detection to be done solely here.
This might change the order the targets show up in but shouldn't affect
anything else. Will look into that.
>From 156da4b1b5a359e7c680c17b911f944cc640c9bc Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Tue, 24 Jun 2025 11:45:00 -0500
Subject: [PATCH] [Clang] Clean up OpenMP offload toolchain generation
Summary:
Small cleanup prior to some larger changes in this area. I want to move
the offload arch detection to be done solely here.
This might change the order the targets show up in but shouldn't affect
anything else. Will look into that.
---
clang/lib/Driver/Driver.cpp | 116 ++++++++++++++----------------
clang/test/Driver/offload-Xarch.c | 4 +-
2 files changed, 55 insertions(+), 65 deletions(-)
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 2d055ffa17a8f..fd7fce114eca2 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -1044,82 +1044,72 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
<< OpenMPTargets->getAsString(C.getInputArgs());
return;
}
- for (StringRef T : OpenMPTargets->getValues())
- OpenMPTriples.insert(T);
+ for (StringRef T : OpenMPTargets->getValues()) {
+ llvm::Triple TT(ToolChain::getOpenMPTriple(T));
+ std::string NormalizedName = TT.normalize();
+
+ // Make sure we don't have a duplicate triple.
+ auto [TripleIt, Inserted] =
+ FoundNormalizedTriples.try_emplace(NormalizedName, T);
+ if (!Inserted) {
+ Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
+ << T << TripleIt->second;
+ continue;
+ }
+
+ // If the specified target is invalid, emit a diagnostic.
+ if (TT.getArch() == llvm::Triple::UnknownArch) {
+ Diag(clang::diag::err_drv_invalid_omp_target) << T;
+ continue;
+ }
+
+ auto &TC = getOffloadToolChain(C.getInputArgs(), Action::OFK_OpenMP, TT,
+ C.getDefaultToolChain().getTriple());
+ C.addOffloadDeviceToolChain(&TC, Action::OFK_OpenMP);
+ }
} else if (C.getInputArgs().hasArg(options::OPT_offload_arch_EQ) &&
((!IsHIP && !IsCuda) || UseLLVMOffload)) {
const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>();
- auto AMDTriple = getHIPOffloadTargetTriple(*this, C.getInputArgs());
- auto NVPTXTriple = getNVIDIAOffloadTargetTriple(*this, C.getInputArgs(),
- HostTC->getTriple());
+ llvm::Triple AMDTriple("amdgcn-amd-amdhsa");
+ llvm::Triple NVPTXTriple("nvptx64-nvidia-cuda");
// Attempt to deduce the offloading triple from the set of architectures.
// We can only correctly deduce NVPTX / AMDGPU triples currently.
- // We need to temporarily create these toolchains so that we can access
- // tools for inferring architectures.
- llvm::DenseSet<StringRef> Archs;
- for (const std::optional<llvm::Triple> &TT : {NVPTXTriple, AMDTriple}) {
- if (!TT)
- continue;
-
- auto &TC =
- getOffloadToolChain(C.getInputArgs(), Action::OFK_OpenMP, *TT,
- C.getDefaultToolChain().getTriple());
- for (StringRef Arch :
- getOffloadArchs(C, C.getArgs(), Action::OFK_OpenMP, &TC, true))
- Archs.insert(Arch);
- }
+ for (const llvm::Triple &TT : {AMDTriple, NVPTXTriple}) {
+ auto &TC = getOffloadToolChain(C.getInputArgs(), Action::OFK_OpenMP, TT,
+ C.getDefaultToolChain().getTriple());
+
+ llvm::DenseSet<StringRef> Archs =
+ getOffloadArchs(C, C.getArgs(), Action::OFK_OpenMP, &TC, true);
+ llvm::DenseSet<StringRef> ArchsForTarget;
+ for (StringRef Arch : Archs) {
+ bool IsNVPTX = IsNVIDIAOffloadArch(
+ StringToOffloadArch(getProcessorFromTargetID(NVPTXTriple, Arch)));
+ bool IsAMDGPU = IsAMDOffloadArch(
+ StringToOffloadArch(getProcessorFromTargetID(AMDTriple, Arch)));
+ if (!IsNVPTX && !IsAMDGPU && !Arch.equals_insensitive("native")) {
+ Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
+ << Arch;
+ return;
+ }
- for (StringRef Arch : Archs) {
- if (NVPTXTriple && IsNVIDIAOffloadArch(StringToOffloadArch(
- getProcessorFromTargetID(*NVPTXTriple, Arch)))) {
- DerivedArchs[NVPTXTriple->getTriple()].insert(Arch);
- } else if (AMDTriple &&
- IsAMDOffloadArch(StringToOffloadArch(
- getProcessorFromTargetID(*AMDTriple, Arch)))) {
- DerivedArchs[AMDTriple->getTriple()].insert(Arch);
- } else {
- Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch) << Arch;
- return;
+ if (TT.isNVPTX() && IsNVPTX) {
+ ArchsForTarget.insert(Arch);
+ } else if (TT.isAMDGPU() && IsAMDGPU) {
+ ArchsForTarget.insert(Arch);
+ }
+ }
+ if (!ArchsForTarget.empty()) {
+ C.addOffloadDeviceToolChain(&TC, Action::OFK_OpenMP);
+ KnownArchs[&TC] = ArchsForTarget;
}
}
// If the set is empty then we failed to find a native architecture.
- if (Archs.empty()) {
+ auto TCRange = C.getOffloadToolChains(Action::OFK_OpenMP);
+ if (TCRange.first == TCRange.second)
Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch)
<< "native";
- return;
- }
-
- for (const auto &TripleAndArchs : DerivedArchs)
- OpenMPTriples.insert(TripleAndArchs.first());
- }
-
- for (StringRef Val : OpenMPTriples) {
- llvm::Triple TT(ToolChain::getOpenMPTriple(Val));
- std::string NormalizedName = TT.normalize();
-
- // Make sure we don't have a duplicate triple.
- auto [TripleIt, Inserted] =
- FoundNormalizedTriples.try_emplace(NormalizedName, Val);
- if (!Inserted) {
- Diag(clang::diag::warn_drv_omp_offload_target_duplicate)
- << Val << TripleIt->second;
- continue;
- }
-
- // If the specified target is invalid, emit a diagnostic.
- if (TT.getArch() == llvm::Triple::UnknownArch) {
- Diag(clang::diag::err_drv_invalid_omp_target) << Val;
- continue;
- }
-
- auto &TC = getOffloadToolChain(C.getInputArgs(), Action::OFK_OpenMP, TT,
- C.getDefaultToolChain().getTriple());
- C.addOffloadDeviceToolChain(&TC, Action::OFK_OpenMP);
- auto It = DerivedArchs.find(TT.getTriple());
- if (It != DerivedArchs.end())
- KnownArchs[&TC] = It->second;
}
} else if (C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ)) {
Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
diff --git a/clang/test/Driver/offload-Xarch.c b/clang/test/Driver/offload-Xarch.c
index 73943f3e9c7f8..6a17e1b8f3d24 100644
--- a/clang/test/Driver/offload-Xarch.c
+++ b/clang/test/Driver/offload-Xarch.c
@@ -20,12 +20,12 @@
// RUN: | FileCheck -check-prefix=OPENMP %s
// OPENMP: # "x86_64-unknown-linux-gnu" - "clang", inputs: ["[[INPUT:.+]]"], output: "[[HOST_BC:.+]]"
-// OPENMP: # "amdgcn-amd-amdhsa" - "clang", inputs: ["[[INPUT]]", "[[HOST_BC]]"], output: "[[GFX1030_BC:.+]]"
-// OPENMP: # "amdgcn-amd-amdhsa" - "clang", inputs: ["[[INPUT]]", "[[HOST_BC]]"], output: "[[GFX90A_BC:.+]]"
// OPENMP: # "nvptx64-nvidia-cuda" - "clang", inputs: ["[[INPUT]]", "[[HOST_BC]]"], output: "[[SM52_PTX:.+]]"
// OPENMP: # "nvptx64-nvidia-cuda" - "NVPTX::Assembler", inputs: ["[[SM52_PTX]]"], output: "[[SM52_CUBIN:.+]]"
// OPENMP: # "nvptx64-nvidia-cuda" - "clang", inputs: ["[[INPUT]]", "[[HOST_BC]]"], output: "[[SM60_PTX:.+]]"
// OPENMP: # "nvptx64-nvidia-cuda" - "NVPTX::Assembler", inputs: ["[[SM60_PTX]]"], output: "[[SM60_CUBIN:.+]]"
+// OPENMP: # "amdgcn-amd-amdhsa" - "clang", inputs: ["[[INPUT]]", "[[HOST_BC]]"], output: "[[GFX1030_BC:.+]]"
+// OPENMP: # "amdgcn-amd-amdhsa" - "clang", inputs: ["[[INPUT]]", "[[HOST_BC]]"], output: "[[GFX90A_BC:.+]]"
// OPENMP: # "x86_64-unknown-linux-gnu" - "Offload::Packager", inputs: ["[[GFX1030_BC]]", "[[GFX90A_BC]]", "[[SM52_CUBIN]]", "[[SM60_CUBIN]]"], output: "[[BINARY:.+]]"
// OPENMP: # "x86_64-unknown-linux-gnu" - "clang", inputs: ["[[HOST_BC]]", "[[BINARY]]"], output: "[[HOST_OBJ:.+]]"
// OPENMP: # "x86_64-unknown-linux-gnu" - "Offload::Linker", inputs: ["[[HOST_OBJ]]"], output: "a.out"
More information about the cfe-commits
mailing list