Skip to content

Commit 6eb8265

Browse files
DCastagnajlebar
authored andcommitted
[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
1 parent 99d2582 commit 6eb8265

File tree

5 files changed

+68
-42
lines changed

5 files changed

+68
-42
lines changed

clang/include/clang/Basic/DiagnosticDriverKinds.td

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -627,8 +627,10 @@ def err_cc1_unbounded_vscale_min : Error<
627627
def err_drv_ssp_missing_offset_argument : Error<
628628
"'%0' is used without '-mstack-protector-guard-offset', and there is no default">;
629629

630-
def err_drv_only_one_offload_target_supported_in : Error<
631-
"Only one offload target is supported in %0.">;
630+
def err_drv_only_one_offload_target_supported : Error<
631+
"only one offload target is supported">;
632632
def err_drv_invalid_or_unsupported_offload_target : Error<
633-
"Invalid or unsupported offload target: '%0'.">;
633+
"invalid or unsupported offload target: '%0'">;
634+
def err_drv_cuda_offload_only_emit_bc : Error<
635+
"CUDA offload target is supported only along with --emit-llvm">;
634636
}

clang/include/clang/Driver/Options.td

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,8 +1143,7 @@ defm autolink : BoolFOption<"autolink",
11431143
// languages and accept other values such as CPU/GPU architectures,
11441144
// offload kinds and target aliases.
11451145
def offload_EQ : CommaJoined<["--"], "offload=">, Flags<[NoXarchOption]>,
1146-
HelpText<"Specify comma-separated list of offloading target triples"
1147-
" (HIP only)">;
1146+
HelpText<"Specify comma-separated list of offloading target triples (CUDA and HIP only)">;
11481147

11491148
// C++ Coroutines TS
11501149
defm coroutines_ts : BoolFOption<"coroutines-ts",

clang/lib/Driver/Driver.cpp

Lines changed: 54 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -103,39 +103,58 @@ using namespace clang;
103103
using namespace llvm::opt;
104104

105105
static llvm::Optional<llvm::Triple>
106-
getHIPOffloadTargetTriple(const Driver &D, const ArgList &Args) {
107-
if (Args.hasArg(options::OPT_offload_EQ)) {
108-
auto HIPOffloadTargets = Args.getAllArgValues(options::OPT_offload_EQ);
106+
getOffloadTargetTriple(const Driver &D, const ArgList &Args) {
107+
auto OffloadTargets = Args.getAllArgValues(options::OPT_offload_EQ);
108+
// Offload compilation flow does not support multiple targets for now. We
109+
// need the HIPActionBuilder (and possibly the CudaActionBuilder{,Base}too)
110+
// to support multiple tool chains first.
111+
switch (OffloadTargets.size()) {
112+
default:
113+
D.Diag(diag::err_drv_only_one_offload_target_supported);
114+
return llvm::None;
115+
case 0:
116+
D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << "";
117+
return llvm::None;
118+
case 1:
119+
break;
120+
}
121+
return llvm::Triple(OffloadTargets[0]);
122+
}
109123

110-
// HIP compilation flow does not support multiple targets for now. We need
111-
// the HIPActionBuilder (and possibly the CudaActionBuilder{,Base}too) to
112-
// support multiple tool chains first.
113-
switch (HIPOffloadTargets.size()) {
114-
default:
115-
D.Diag(diag::err_drv_only_one_offload_target_supported_in) << "HIP";
116-
return llvm::None;
117-
case 0:
118-
D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << "";
119-
return llvm::None;
120-
case 1:
121-
break;
122-
}
123-
llvm::Triple TT(HIPOffloadTargets[0]);
124-
if (TT.getArch() == llvm::Triple::amdgcn &&
125-
TT.getVendor() == llvm::Triple::AMD &&
126-
TT.getOS() == llvm::Triple::AMDHSA)
127-
return TT;
128-
if (TT.getArch() == llvm::Triple::spirv64 &&
129-
TT.getVendor() == llvm::Triple::UnknownVendor &&
130-
TT.getOS() == llvm::Triple::UnknownOS)
124+
static llvm::Optional<llvm::Triple>
125+
getNVIDIAOffloadTargetTriple(const Driver &D, const ArgList &Args,
126+
const llvm::Triple &HostTriple) {
127+
if (!Args.hasArg(options::OPT_offload_EQ)) {
128+
return llvm::Triple(HostTriple.isArch64Bit() ? "nvptx64-nvidia-cuda"
129+
: "nvptx-nvidia-cuda");
130+
}
131+
auto TT = getOffloadTargetTriple(D, Args);
132+
if (TT && (TT->getArch() == llvm::Triple::spirv32 ||
133+
TT->getArch() == llvm::Triple::spirv64)) {
134+
if (Args.hasArg(options::OPT_emit_llvm))
131135
return TT;
132-
D.Diag(diag::err_drv_invalid_or_unsupported_offload_target)
133-
<< HIPOffloadTargets[0];
136+
D.Diag(diag::err_drv_cuda_offload_only_emit_bc);
134137
return llvm::None;
135138
}
136-
137-
static const llvm::Triple T("amdgcn-amd-amdhsa"); // Default HIP triple.
138-
return T;
139+
D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
140+
return llvm::None;
141+
}
142+
static llvm::Optional<llvm::Triple>
143+
getHIPOffloadTargetTriple(const Driver &D, const ArgList &Args) {
144+
if (!Args.hasArg(options::OPT_offload_EQ)) {
145+
return llvm::Triple("amdgcn-amd-amdhsa"); // Default HIP triple.
146+
}
147+
auto TT = getOffloadTargetTriple(D, Args);
148+
if (!TT)
149+
return llvm::None;
150+
if (TT->getArch() == llvm::Triple::amdgcn &&
151+
TT->getVendor() == llvm::Triple::AMD &&
152+
TT->getOS() == llvm::Triple::AMDHSA)
153+
return TT;
154+
if (TT->getArch() == llvm::Triple::spirv64)
155+
return TT;
156+
D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << TT->str();
157+
return llvm::None;
139158
}
140159

141160
// static
@@ -719,17 +738,17 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
719738
if (IsCuda) {
720739
const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>();
721740
const llvm::Triple &HostTriple = HostTC->getTriple();
722-
StringRef DeviceTripleStr;
723741
auto OFK = Action::OFK_Cuda;
724-
DeviceTripleStr =
725-
HostTriple.isArch64Bit() ? "nvptx64-nvidia-cuda" : "nvptx-nvidia-cuda";
726-
llvm::Triple CudaTriple(DeviceTripleStr);
742+
auto CudaTriple =
743+
getNVIDIAOffloadTargetTriple(*this, C.getInputArgs(), HostTriple);
744+
if (!CudaTriple)
745+
return;
727746
// Use the CUDA and host triples as the key into the ToolChains map,
728747
// because the device toolchain we create depends on both.
729-
auto &CudaTC = ToolChains[CudaTriple.str() + "/" + HostTriple.str()];
748+
auto &CudaTC = ToolChains[CudaTriple->str() + "/" + HostTriple.str()];
730749
if (!CudaTC) {
731750
CudaTC = std::make_unique<toolchains::CudaToolChain>(
732-
*this, CudaTriple, *HostTC, C.getInputArgs(), OFK);
751+
*this, *CudaTriple, *HostTC, C.getInputArgs(), OFK);
733752
}
734753
C.addOffloadDeviceToolChain(CudaTC.get(), OFK);
735754
} else if (IsHIP) {
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// REQUIRES: clang-driver
2+
3+
// RUN: %clang -### -emit-llvm --cuda-device-only \
4+
// RUN: -nocudalib -nocudainc --offload=spirv32-unknown-unknown -c %s 2>&1 | FileCheck %s
5+
6+
// CHECK: clang{{.*}}" "-cc1" "-triple" "spirv32-unknown-unknown" {{.*}} "-fcuda-is-device" {{.*}}

clang/test/Driver/invalid-offload-options.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// RUN: --hip-path=%S/Inputs/hipspv -nogpuinc -nogpulib %s \
1010
// RUN: 2>&1 | FileCheck --check-prefix=INVALID-TARGET %s
1111

12-
// INVALID-TARGET: error: Invalid or unsupported offload target: '{{.*}}'
12+
// INVALID-TARGET: error: invalid or unsupported offload target: '{{.*}}'
1313

1414
// In the future we should be able to specify multiple targets for HIP
1515
// compilation but currently it is not supported.
@@ -22,7 +22,7 @@
2222
// RUN: --hip-path=%S/Inputs/hipspv -nogpuinc -nogpulib %s \
2323
// RUN: 2>&1 | FileCheck --check-prefix=TOO-MANY-TARGETS %s
2424

25-
// TOO-MANY-TARGETS: error: Only one offload target is supported in HIP.
25+
// TOO-MANY-TARGETS: error: only one offload target is supported
2626

2727
// RUN: %clang -### -x hip -target x86_64-linux-gnu -nogpuinc -nogpulib \
2828
// RUN: --offload=amdgcn-amd-amdhsa --offload-arch=gfx900 %s \

0 commit comments

Comments
 (0)