Index: include/clang/Driver/Action.h =================================================================== --- include/clang/Driver/Action.h +++ include/clang/Driver/Action.h @@ -88,6 +88,7 @@ // The device offloading tool chains - one bit for each programming model. OFK_Cuda = 0x02, OFK_OpenMP = 0x04, + OFK_HIP = 0x08, }; static const char *getClassName(ActionClass AC); Index: lib/Driver/Action.cpp =================================================================== --- lib/Driver/Action.cpp +++ lib/Driver/Action.cpp @@ -96,6 +96,8 @@ return "device-cuda"; case OFK_OpenMP: return "device-openmp"; + case OFK_HIP: + return "device-hip"; // TODO: Add other programming models here. } @@ -104,8 +106,13 @@ return {}; std::string Res("host"); + assert(!((ActiveOffloadKindMask & OFK_Cuda) && + (ActiveOffloadKindMask & OFK_HIP)) && + "Cannot offload CUDA and HIP at the same time"); if (ActiveOffloadKindMask & OFK_Cuda) Res += "-cuda"; + if (ActiveOffloadKindMask & OFK_HIP) + Res += "-hip"; if (ActiveOffloadKindMask & OFK_OpenMP) Res += "-openmp"; @@ -142,6 +149,8 @@ return "cuda"; case OFK_OpenMP: return "openmp"; + case OFK_HIP: + return "hip"; // TODO: Add other programming models here. } Index: lib/Driver/Compilation.cpp =================================================================== --- lib/Driver/Compilation.cpp +++ lib/Driver/Compilation.cpp @@ -196,10 +196,10 @@ if (FailingCommands.empty()) return false; - // CUDA can have the same input source code compiled multiple times so do not - // compiled again if there are already failures. It is OK to abort the CUDA - // pipeline on errors. - if (A->isOffloading(Action::OFK_Cuda)) + // CUDA/HIP can have the same input source code compiled multiple times so do + // not compiled again if there are already failures. It is OK to abort the + // CUDA pipeline on errors. + if (A->isOffloading(Action::OFK_Cuda) || A->isOffloading(Action::OFK_HIP)) return true; for (const auto &CI : FailingCommands) Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -132,6 +132,11 @@ else if (JA.isDeviceOffloading(Action::OFK_Cuda)) Work(*C.getSingleOffloadToolChain()); + if (JA.isHostOffloading(Action::OFK_HIP)) + Work(*C.getSingleOffloadToolChain()); + else if (JA.isDeviceOffloading(Action::OFK_HIP)) + Work(*C.getSingleOffloadToolChain()); + if (JA.isHostOffloading(Action::OFK_OpenMP)) { auto TCs = C.getOffloadToolChains(); for (auto II = TCs.first, IE = TCs.second; II != IE; ++II) @@ -3099,13 +3104,14 @@ // Check number of inputs for sanity. We need at least one input. assert(Inputs.size() >= 1 && "Must have at least one input."); const InputInfo &Input = Inputs[0]; - // CUDA compilation may have multiple inputs (source file + results of + // CUDA/HIP compilation may have multiple inputs (source file + results of // device-side compilations). OpenMP device jobs also take the host IR as a // second input. All other jobs are expected to have exactly one // input. bool IsCuda = JA.isOffloading(Action::OFK_Cuda); + bool IsHIP = JA.isOffloading(Action::OFK_HIP); bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP); - assert((IsCuda || (IsOpenMPDevice && Inputs.size() == 2) || + assert((IsCuda || IsHIP || (IsOpenMPDevice && Inputs.size() == 2) || Inputs.size() == 1) && "Unable to handle multiple inputs."); @@ -3117,10 +3123,10 @@ bool IsWindowsMSVC = RawTriple.isWindowsMSVCEnvironment(); bool IsIAMCU = RawTriple.isOSIAMCU(); - // Adjust IsWindowsXYZ for CUDA compilations. Even when compiling in device - // mode (i.e., getToolchain().getTriple() is NVPTX, not Windows), we need to - // pass Windows-specific flags to cc1. - if (IsCuda) { + // Adjust IsWindowsXYZ for CUDA/HIP compilations. Even when compiling in + // device mode (i.e., getToolchain().getTriple() is NVPTX/AMDGCN, not + // Windows), we need to pass Windows-specific flags to cc1. + if (IsCuda || IsHIP) { IsWindowsMSVC |= AuxTriple && AuxTriple->isWindowsMSVCEnvironment(); IsWindowsGNU |= AuxTriple && AuxTriple->isWindowsGNUEnvironment(); IsWindowsCygnus |= AuxTriple && AuxTriple->isWindowsCygwinEnvironment(); @@ -3144,18 +3150,21 @@ Args.ClaimAllArgs(options::OPT_MJ); } - if (IsCuda) { - // We have to pass the triple of the host if compiling for a CUDA device and - // vice-versa. + if (IsCuda || IsHIP) { + // We have to pass the triple of the host if compiling for a CUDA/HIP device + // and vice-versa. std::string NormalizedTriple; - if (JA.isDeviceOffloading(Action::OFK_Cuda)) + if (JA.isDeviceOffloading(Action::OFK_Cuda) || + JA.isDeviceOffloading(Action::OFK_HIP)) NormalizedTriple = C.getSingleOffloadToolChain() ->getTriple() .normalize(); else - NormalizedTriple = C.getSingleOffloadToolChain() - ->getTriple() - .normalize(); + NormalizedTriple = + (IsCuda ? C.getSingleOffloadToolChain() + : C.getSingleOffloadToolChain()) + ->getTriple() + .normalize(); CmdArgs.push_back("-aux-triple"); CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));