diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -607,36 +607,43 @@ continue; } - // Currently, we only pass the input files to the linker, we do not pass - // any libraries that may be valid only for the host. - if (!II.isFilename()) - continue; - // The 'nvlink' application performs RDC-mode linking when given a '.o' // file and device linking when given a '.cubin' file. We always want to // perform device linking, so just rename any '.o' files. // FIXME: This should hopefully be removed if NVIDIA updates their tooling. - auto InputFile = getToolChain().getInputFilename(II); - if (llvm::sys::path::extension(InputFile) != ".cubin") { - // If there are no actions above this one then this is direct input and we - // can copy it. Otherwise the input is internal so a `.cubin` file should - // exist. - if (II.getAction() && II.getAction()->getInputs().size() == 0) { - const char *CubinF = - Args.MakeArgString(getToolChain().getDriver().GetTemporaryPath( - llvm::sys::path::stem(InputFile), "cubin")); - if (std::error_code EC = - llvm::sys::fs::copy_file(InputFile, C.addTempFile(CubinF))) - continue; + if (II.isFilename()) { + auto InputFile = getToolChain().getInputFilename(II); + if (llvm::sys::path::extension(InputFile) != ".cubin") { + // If there are no actions above this one then this is direct input and + // we can copy it. Otherwise the input is internal so a `.cubin` file + // should exist. + if (II.getAction() && II.getAction()->getInputs().size() == 0) { + const char *CubinF = + Args.MakeArgString(getToolChain().getDriver().GetTemporaryPath( + llvm::sys::path::stem(InputFile), "cubin")); + if (std::error_code EC = + llvm::sys::fs::copy_file(InputFile, C.addTempFile(CubinF))) + continue; - CmdArgs.push_back(CubinF); + CmdArgs.push_back(CubinF); + } else { + SmallString<256> Filename(InputFile); + llvm::sys::path::replace_extension(Filename, "cubin"); + CmdArgs.push_back(Args.MakeArgString(Filename)); + } } else { - SmallString<256> Filename(InputFile); - llvm::sys::path::replace_extension(Filename, "cubin"); - CmdArgs.push_back(Args.MakeArgString(Filename)); + CmdArgs.push_back(Args.MakeArgString(InputFile)); } - } else { - CmdArgs.push_back(Args.MakeArgString(InputFile)); + continue; + } else if (!II.isNothing()) { + // This option is commonly passed by LLVM by default, but isn't supported + // by nvlink. + if (llvm::any_of(II.getInputArg().getValues(), [](StringRef Arg) { + return Arg.equals("--color-diagnostics"); + })) + continue; + // Render any remaining arguments as input to nvlink. + II.getInputArg().renderAsInput(Args, CmdArgs); } } diff --git a/clang/test/Driver/cuda-cross-compiling.c b/clang/test/Driver/cuda-cross-compiling.c --- a/clang/test/Driver/cuda-cross-compiling.c +++ b/clang/test/Driver/cuda-cross-compiling.c @@ -77,3 +77,12 @@ // RUN: | FileCheck -check-prefix=LOWERING %s // LOWERING: -cc1" "-triple" "nvptx64-nvidia-cuda" {{.*}} "-mllvm" "--nvptx-lower-global-ctor-dtor" + +// +// Test passing arguments directly to nvlink. +// +// RUN: %clang -target nvptx64-nvidia-cuda -Wl,-v -Wl,--color-diagnostics -### %s 2>&1 \ +// RUN: | FileCheck -check-prefix=LINKER-ARGS %s + +// LINKER-ARGS: nvlink{{.*}}"-v" +// LINKER-ARGS-NOT: nvlink{{.*}}"--color-diagnostics"