diff --git a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp --- a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp @@ -289,10 +289,22 @@ const OptTable &Opts = getDriver().getOpts(); - if (DeviceOffloadKind != Action::OFK_OpenMP) { - for (Arg *A : Args) { - DAL->append(A); + if (DeviceOffloadKind == Action::OFK_OpenMP) { + for (Arg *A : Args) + if (!llvm::is_contained(*DAL, A)) + DAL->append(A); + + std::string Arch = DAL->getLastArgValue(options::OPT_march_EQ).str(); + if (Arch.empty()) { + checkSystemForAMDGPU(Args, *this, Arch); + DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ), Arch); } + + return DAL; + } + + for (Arg *A : Args) { + DAL->append(A); } if (!BoundArch.empty()) { diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -512,7 +512,7 @@ // Create a new file to write the linked device image to. SmallString<128> TempFile; if (std::error_code EC = sys::fs::createTemporaryFile( - TheTriple.getArchName() + "-" + Arch, "cubin", TempFile)) + "lto-" + TheTriple.getArchName() + "-" + Arch, "cubin", TempFile)) return createFileError(TempFile, EC); TempFiles.push_back(static_cast(TempFile)); @@ -590,6 +590,50 @@ return static_cast(TempFile); } } // namespace nvptx +namespace amdgcn { +Expected link(ArrayRef InputFiles, + ArrayRef LinkerArgs, Triple TheTriple, + StringRef Arch) { + // AMDGPU uses the lld binary to link device object files. + ErrorOr LLDPath = + sys::findProgramByName("lld", sys::path::parent_path(LinkerExecutable)); + if (!LLDPath) + LLDPath = sys::findProgramByName("lld"); + if (!LLDPath) + return createStringError(LLDPath.getError(), + "Unable to find 'lld' in path"); + + // Create a new file to write the linked device image to. + SmallString<128> TempFile; + if (std::error_code EC = sys::fs::createTemporaryFile( + TheTriple.getArchName() + "-" + Arch + "-image", "out", TempFile)) + return createFileError(TempFile, EC); + TempFiles.push_back(static_cast(TempFile)); + + SmallVector CmdArgs; + CmdArgs.push_back(*LLDPath); + CmdArgs.push_back("-flavor"); + CmdArgs.push_back("gnu"); + CmdArgs.push_back("--no-undefined"); + CmdArgs.push_back("-shared"); + CmdArgs.push_back("-o"); + CmdArgs.push_back(TempFile); + + // Copy system library paths used by the host linker. + for (StringRef Arg : LinkerArgs) + if (Arg.startswith("-L")) + CmdArgs.push_back(Arg); + + // Add extracted input files. + for (StringRef Input : InputFiles) + CmdArgs.push_back(Input); + + if (sys::ExecuteAndWait(*LLDPath, CmdArgs)) + return createStringError(inconvertibleErrorCode(), "'lld' failed"); + + return static_cast(TempFile); +} +} // namespace amdgcn Expected linkDevice(ArrayRef InputFiles, ArrayRef LinkerArgs, @@ -599,7 +643,7 @@ case Triple::nvptx64: return nvptx::link(InputFiles, LinkerArgs, TheTriple, Arch); case Triple::amdgcn: - // TODO: AMDGCN linking support. + return amdgcn::link(InputFiles, LinkerArgs, TheTriple, Arch); case Triple::x86: case Triple::x86_64: // TODO: x86 linking support.