@@ -103,39 +103,58 @@ using namespace clang;
103
103
using namespace llvm ::opt;
104
104
105
105
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
+ }
109
123
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))
131
135
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);
134
137
return llvm::None;
135
138
}
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;
139
158
}
140
159
141
160
// static
@@ -719,17 +738,17 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
719
738
if (IsCuda) {
720
739
const ToolChain *HostTC = C.getSingleOffloadToolChain <Action::OFK_Host>();
721
740
const llvm::Triple &HostTriple = HostTC->getTriple ();
722
- StringRef DeviceTripleStr;
723
741
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 ;
727
746
// Use the CUDA and host triples as the key into the ToolChains map,
728
747
// 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 ()];
730
749
if (!CudaTC) {
731
750
CudaTC = std::make_unique<toolchains::CudaToolChain>(
732
- *this , CudaTriple, *HostTC, C.getInputArgs (), OFK);
751
+ *this , * CudaTriple, *HostTC, C.getInputArgs (), OFK);
733
752
}
734
753
C.addOffloadDeviceToolChain (CudaTC.get (), OFK);
735
754
} else if (IsHIP) {
0 commit comments