Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -555,6 +555,8 @@ HelpText<"Do not include PTX for the follwing GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">; def cuda_gpu_arch_EQ : Joined<["--"], "cuda-gpu-arch=">, Flags<[DriverOption]>, HelpText<"CUDA GPU architecture (e.g. sm_35). May be specified more than once.">; +def hip_link : Flag<["--"], "hip-link">, + HelpText<"Link clang-offload-bundler bundles for HIP">; def no_cuda_gpu_arch_EQ : Joined<["--"], "no-cuda-gpu-arch=">, Flags<[DriverOption]>, HelpText<"Remove GPU architecture (e.g. sm_35) from the list of GPUs to compile for. " "'all' resets the list to its default value.">; Index: lib/Driver/Driver.cpp =================================================================== --- lib/Driver/Driver.cpp +++ lib/Driver/Driver.cpp @@ -537,24 +537,42 @@ InputList &Inputs) { // - // CUDA + // CUDA/HIP // // We need to generate a CUDA toolchain if any of the inputs has a CUDA type. - if (llvm::any_of(Inputs, [](std::pair &I) { - return types::isCuda(I.first); - })) { + // ToDo: Handle mixed CUDA/HIP input files and -x hip option. Diagnose + // CUDA on amdgcn and HIP on nvptx. + bool IsHIP = + (C.getInputArgs().hasArg(options::OPT_x) && + StringRef(C.getInputArgs().getLastArg(options::OPT_x)->getValue()) == + "hip") || + C.getInputArgs().hasArg(options::OPT_hip_link); + if (llvm::any_of(Inputs, + [](std::pair &I) { + return types::isCuda(I.first); + }) || + IsHIP) { const ToolChain *HostTC = C.getSingleOffloadToolChain(); const llvm::Triple &HostTriple = HostTC->getTriple(); - llvm::Triple CudaTriple(HostTriple.isArch64Bit() ? "nvptx64-nvidia-cuda" - : "nvptx-nvidia-cuda"); - // Use the CUDA and host triples as the key into the ToolChains map, because - // the device toolchain we create depends on both. + StringRef DeviceTripleStr; + auto OFK = IsHIP ? Action::OFK_HIP : Action::OFK_Cuda; + if (IsHIP) { + // HIP is only supported on amdgcn. + DeviceTripleStr = "amdgcn-amd-amdhsa"; + } else { + // CUDA is only supported on nvptx. + DeviceTripleStr = HostTriple.isArch64Bit() ? "nvptx64-nvidia-cuda" + : "nvptx-nvidia-cuda"; + } + llvm::Triple CudaTriple(DeviceTripleStr); + // Use the CUDA/HIP 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()]; if (!CudaTC) { CudaTC = llvm::make_unique( - *this, CudaTriple, *HostTC, C.getInputArgs(), Action::OFK_Cuda); + *this, CudaTriple, *HostTC, C.getInputArgs(), OFK); } - C.addOffloadDeviceToolChain(CudaTC.get(), Action::OFK_Cuda); + C.addOffloadDeviceToolChain(CudaTC.get(), OFK); } //