[clang] 6eb8265 - [Driver] Add CUDA support for --offload param
Justin Lebar via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 28 14:51:28 PST 2022
Author: Daniele Castagna
Date: 2022-01-28T14:50:39-08:00
New Revision: 6eb826567af03c2b43cda78836b1065e12df84e4
URL: https://github.com/llvm/llvm-project/commit/6eb826567af03c2b43cda78836b1065e12df84e4
DIFF: https://github.com/llvm/llvm-project/commit/6eb826567af03c2b43cda78836b1065e12df84e4.diff
LOG: [Driver] Add CUDA support for --offload param
The --offload option was added in D110622 to "override the default
device target". When it landed it supported only HIP. This patch
extends that option to support SPIR-V targets for CUDA.
Reviewed By: tra
Differential Revision: https://reviews.llvm.org/D117137
Added:
clang/test/Driver/cuda-device-triple.cu
Modified:
clang/include/clang/Basic/DiagnosticDriverKinds.td
clang/include/clang/Driver/Options.td
clang/lib/Driver/Driver.cpp
clang/test/Driver/invalid-offload-options.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index e635be6b6d1bc..3efedbe0f6428 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -627,8 +627,10 @@ def err_cc1_unbounded_vscale_min : Error<
def err_drv_ssp_missing_offset_argument : Error<
"'%0' is used without '-mstack-protector-guard-offset', and there is no default">;
-def err_drv_only_one_offload_target_supported_in : Error<
- "Only one offload target is supported in %0.">;
+def err_drv_only_one_offload_target_supported : Error<
+ "only one offload target is supported">;
def err_drv_invalid_or_unsupported_offload_target : Error<
- "Invalid or unsupported offload target: '%0'.">;
+ "invalid or unsupported offload target: '%0'">;
+def err_drv_cuda_offload_only_emit_bc : Error<
+ "CUDA offload target is supported only along with --emit-llvm">;
}
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index fbdac93a8313d..52f05f392db2c 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1143,8 +1143,7 @@ defm autolink : BoolFOption<"autolink",
// languages and accept other values such as CPU/GPU architectures,
// offload kinds and target aliases.
def offload_EQ : CommaJoined<["--"], "offload=">, Flags<[NoXarchOption]>,
- HelpText<"Specify comma-separated list of offloading target triples"
- " (HIP only)">;
+ HelpText<"Specify comma-separated list of offloading target triples (CUDA and HIP only)">;
// C++ Coroutines TS
defm coroutines_ts : BoolFOption<"coroutines-ts",
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 2e4ebc10e9ba3..61c2289f83e9c 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -103,39 +103,58 @@ using namespace clang;
using namespace llvm::opt;
static llvm::Optional<llvm::Triple>
-getHIPOffloadTargetTriple(const Driver &D, const ArgList &Args) {
- if (Args.hasArg(options::OPT_offload_EQ)) {
- auto HIPOffloadTargets = Args.getAllArgValues(options::OPT_offload_EQ);
+getOffloadTargetTriple(const Driver &D, const ArgList &Args) {
+ auto OffloadTargets = Args.getAllArgValues(options::OPT_offload_EQ);
+ // Offload compilation flow does not support multiple targets for now. We
+ // need the HIPActionBuilder (and possibly the CudaActionBuilder{,Base}too)
+ // to support multiple tool chains first.
+ switch (OffloadTargets.size()) {
+ default:
+ D.Diag(diag::err_drv_only_one_offload_target_supported);
+ return llvm::None;
+ case 0:
+ D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << "";
+ return llvm::None;
+ case 1:
+ break;
+ }
+ return llvm::Triple(OffloadTargets[0]);
+}
- // HIP compilation flow does not support multiple targets for now. We need
- // the HIPActionBuilder (and possibly the CudaActionBuilder{,Base}too) to
- // support multiple tool chains first.
- switch (HIPOffloadTargets.size()) {
- default:
- D.Diag(diag::err_drv_only_one_offload_target_supported_in) << "HIP";
- return llvm::None;
- case 0:
- D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << "";
- return llvm::None;
- case 1:
- break;
- }
- llvm::Triple TT(HIPOffloadTargets[0]);
- if (TT.getArch() == llvm::Triple::amdgcn &&
- TT.getVendor() == llvm::Triple::AMD &&
- TT.getOS() == llvm::Triple::AMDHSA)
- return TT;
- if (TT.getArch() == llvm::Triple::spirv64 &&
- TT.getVendor() == llvm::Triple::UnknownVendor &&
- TT.getOS() == llvm::Triple::UnknownOS)
+static llvm::Optional<llvm::Triple>
+getNVIDIAOffloadTargetTriple(const Driver &D, const ArgList &Args,
+ const llvm::Triple &HostTriple) {
+ if (!Args.hasArg(options::OPT_offload_EQ)) {
+ return llvm::Triple(HostTriple.isArch64Bit() ? "nvptx64-nvidia-cuda"
+ : "nvptx-nvidia-cuda");
+ }
+ auto TT = getOffloadTargetTriple(D, Args);
+ if (TT && (TT->getArch() == llvm::Triple::spirv32 ||
+ TT->getArch() == llvm::Triple::spirv64)) {
+ if (Args.hasArg(options::OPT_emit_llvm))
return TT;
- D.Diag(diag::err_drv_invalid_or_unsupported_offload_target)
- << HIPOffloadTargets[0];
+ D.Diag(diag::err_drv_cuda_offload_only_emit_bc);
return llvm::None;
}
-
- static const llvm::Triple T("amdgcn-amd-amdhsa"); // Default HIP triple.
- return T;
+ D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
+ return llvm::None;
+}
+static llvm::Optional<llvm::Triple>
+getHIPOffloadTargetTriple(const Driver &D, const ArgList &Args) {
+ if (!Args.hasArg(options::OPT_offload_EQ)) {
+ return llvm::Triple("amdgcn-amd-amdhsa"); // Default HIP triple.
+ }
+ auto TT = getOffloadTargetTriple(D, Args);
+ if (!TT)
+ return llvm::None;
+ if (TT->getArch() == llvm::Triple::amdgcn &&
+ TT->getVendor() == llvm::Triple::AMD &&
+ TT->getOS() == llvm::Triple::AMDHSA)
+ return TT;
+ if (TT->getArch() == llvm::Triple::spirv64)
+ return TT;
+ D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
+ return llvm::None;
}
// static
@@ -719,17 +738,17 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
if (IsCuda) {
const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>();
const llvm::Triple &HostTriple = HostTC->getTriple();
- StringRef DeviceTripleStr;
auto OFK = Action::OFK_Cuda;
- DeviceTripleStr =
- HostTriple.isArch64Bit() ? "nvptx64-nvidia-cuda" : "nvptx-nvidia-cuda";
- llvm::Triple CudaTriple(DeviceTripleStr);
+ auto CudaTriple =
+ getNVIDIAOffloadTargetTriple(*this, C.getInputArgs(), HostTriple);
+ if (!CudaTriple)
+ return;
// Use the CUDA and host triples as the key into the ToolChains map,
// because the device toolchain we create depends on both.
- auto &CudaTC = ToolChains[CudaTriple.str() + "/" + HostTriple.str()];
+ auto &CudaTC = ToolChains[CudaTriple->str() + "/" + HostTriple.str()];
if (!CudaTC) {
CudaTC = std::make_unique<toolchains::CudaToolChain>(
- *this, CudaTriple, *HostTC, C.getInputArgs(), OFK);
+ *this, *CudaTriple, *HostTC, C.getInputArgs(), OFK);
}
C.addOffloadDeviceToolChain(CudaTC.get(), OFK);
} else if (IsHIP) {
diff --git a/clang/test/Driver/cuda-device-triple.cu b/clang/test/Driver/cuda-device-triple.cu
new file mode 100644
index 0000000000000..d8e464293d34e
--- /dev/null
+++ b/clang/test/Driver/cuda-device-triple.cu
@@ -0,0 +1,6 @@
+// REQUIRES: clang-driver
+
+// RUN: %clang -### -emit-llvm --cuda-device-only \
+// RUN: -nocudalib -nocudainc --offload=spirv32-unknown-unknown -c %s 2>&1 | FileCheck %s
+
+// CHECK: clang{{.*}}" "-cc1" "-triple" "spirv32-unknown-unknown" {{.*}} "-fcuda-is-device" {{.*}}
diff --git a/clang/test/Driver/invalid-offload-options.cpp b/clang/test/Driver/invalid-offload-options.cpp
index 1a684359297d8..dc01dcf122a70 100644
--- a/clang/test/Driver/invalid-offload-options.cpp
+++ b/clang/test/Driver/invalid-offload-options.cpp
@@ -9,7 +9,7 @@
// RUN: --hip-path=%S/Inputs/hipspv -nogpuinc -nogpulib %s \
// RUN: 2>&1 | FileCheck --check-prefix=INVALID-TARGET %s
-// INVALID-TARGET: error: Invalid or unsupported offload target: '{{.*}}'
+// INVALID-TARGET: error: invalid or unsupported offload target: '{{.*}}'
// In the future we should be able to specify multiple targets for HIP
// compilation but currently it is not supported.
@@ -22,7 +22,7 @@
// RUN: --hip-path=%S/Inputs/hipspv -nogpuinc -nogpulib %s \
// RUN: 2>&1 | FileCheck --check-prefix=TOO-MANY-TARGETS %s
-// TOO-MANY-TARGETS: error: Only one offload target is supported in HIP.
+// TOO-MANY-TARGETS: error: only one offload target is supported
// RUN: %clang -### -x hip -target x86_64-linux-gnu -nogpuinc -nogpulib \
// RUN: --offload=amdgcn-amd-amdhsa --offload-arch=gfx900 %s \
More information about the cfe-commits
mailing list