Index: clang/lib/Driver/Driver.cpp =================================================================== --- clang/lib/Driver/Driver.cpp +++ clang/lib/Driver/Driver.cpp @@ -3100,12 +3100,16 @@ std::string FileName = IA->getInputArg().getAsString(Args); // Check if the type of the file is the same as the action. Do not // unbundle it if it is not. Do not unbundle .so files, for example, - // which are not object files. + // which are not object files. Files with extension ".lib" is classified + // as TY_Object but they are actually archives, therefore should not be + // unbundled. + const StringRef LibFileExt = ".lib"; if (IA->getType() == types::TY_Object && (!llvm::sys::path::has_extension(FileName) || types::lookupTypeForExtension( llvm::sys::path::extension(FileName).drop_front()) != - types::TY_Object)) + types::TY_Object || + llvm::sys::path::extension(FileName) == LibFileExt)) return ABRT_Inactive; for (auto Arch : GpuArchList) { Index: clang/lib/Driver/ToolChains/CommonArgs.cpp =================================================================== --- clang/lib/Driver/ToolChains/CommonArgs.cpp +++ clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1922,85 +1922,103 @@ return false; bool FoundAOB = false; - SmallVector AOBFileNames; std::string ArchiveOfBundles; - for (auto LPath : LibraryPaths) { - ArchiveOfBundles.clear(); - - llvm::Triple Triple(D.getTargetTriple()); - bool IsMSVC = Triple.isWindowsMSVCEnvironment(); - for (auto Prefix : {"/libdevice/", "/"}) { - if (IsMSVC) - AOBFileNames.push_back(Twine(LPath + Prefix + Lib + ".lib").str()); - AOBFileNames.push_back(Twine(LPath + Prefix + "lib" + Lib + ".a").str()); + + llvm::Triple Triple(D.getTargetTriple()); + bool IsMSVC = Triple.isWindowsMSVCEnvironment(); + auto Ext = IsMSVC ? ".lib" : ".a"; + if (Lib.endswith(Ext) && !Lib.startswith(":")) { + if (llvm::sys::fs::exists(Lib)) { + ArchiveOfBundles = Lib; + FoundAOB = true; } + } else { + for (auto LPath : LibraryPaths) { + ArchiveOfBundles.clear(); + SmallVector AOBFileNames; + + for (auto Prefix : {"/libdevice/", "/"}) { + if (Lib.startswith(":")) + AOBFileNames.push_back( + Twine(LPath + Prefix + Lib.drop_front()).str()); + else if (IsMSVC) + AOBFileNames.push_back(Twine(LPath + Prefix + Lib + Ext).str()); + else + AOBFileNames.push_back( + Twine(LPath + Prefix + "lib" + Lib + Ext).str()); + } - for (auto AOB : AOBFileNames) { - if (llvm::sys::fs::exists(AOB)) { - ArchiveOfBundles = AOB; - FoundAOB = true; - break; + for (auto AOB : AOBFileNames) { + if (llvm::sys::fs::exists(AOB)) { + ArchiveOfBundles = AOB; + FoundAOB = true; + break; + } } + if (FoundAOB) + break; } + } - if (!FoundAOB) - continue; + if (!FoundAOB) + return false; - StringRef Prefix = isBitCodeSDL ? "libbc-" : "lib"; - std::string OutputLib = D.GetTemporaryPath( - Twine(Prefix + Lib + "-" + Arch + "-" + TargetID).str(), "a"); + StringRef Prefix = isBitCodeSDL ? "libbc-" : "lib"; + std::string OutputLib = + D.GetTemporaryPath(Twine(Prefix + llvm::sys::path::filename(Lib) + "-" + + Arch + "-" + TargetID) + .str(), + "a"); + + C.addTempFile(C.getArgs().MakeArgString(OutputLib)); + + ArgStringList CmdArgs; + SmallString<128> DeviceTriple; + DeviceTriple += Action::GetOffloadKindName(JA.getOffloadingDeviceKind()); + DeviceTriple += '-'; + std::string NormalizedTriple = T.getToolChain().getTriple().normalize(); + DeviceTriple += NormalizedTriple; + if (!TargetID.empty()) { + DeviceTriple += '-'; + DeviceTriple += TargetID; + } - C.addTempFile(C.getArgs().MakeArgString(OutputLib)); + std::string UnbundleArg("-unbundle"); + std::string TypeArg("-type=a"); + std::string InputArg("-input=" + ArchiveOfBundles); + std::string OffloadArg("-targets=" + std::string(DeviceTriple)); + std::string OutputArg("-output=" + OutputLib); - ArgStringList CmdArgs; - SmallString<128> DeviceTriple; - DeviceTriple += Action::GetOffloadKindName(JA.getOffloadingDeviceKind()); - DeviceTriple += '-'; - std::string NormalizedTriple = T.getToolChain().getTriple().normalize(); - DeviceTriple += NormalizedTriple; - if (!TargetID.empty()) { - DeviceTriple += '-'; - DeviceTriple += TargetID; - } + const char *UBProgram = DriverArgs.MakeArgString( + T.getToolChain().GetProgramPath("clang-offload-bundler")); - std::string UnbundleArg("-unbundle"); - std::string TypeArg("-type=a"); - std::string InputArg("-input=" + ArchiveOfBundles); - std::string OffloadArg("-targets=" + std::string(DeviceTriple)); - std::string OutputArg("-output=" + OutputLib); - - const char *UBProgram = DriverArgs.MakeArgString( - T.getToolChain().GetProgramPath("clang-offload-bundler")); - - ArgStringList UBArgs; - UBArgs.push_back(C.getArgs().MakeArgString(UnbundleArg)); - UBArgs.push_back(C.getArgs().MakeArgString(TypeArg)); - UBArgs.push_back(C.getArgs().MakeArgString(InputArg)); - UBArgs.push_back(C.getArgs().MakeArgString(OffloadArg)); - UBArgs.push_back(C.getArgs().MakeArgString(OutputArg)); - - // Add this flag to not exit from clang-offload-bundler if no compatible - // code object is found in heterogenous archive library. - std::string AdditionalArgs("-allow-missing-bundles"); - UBArgs.push_back(C.getArgs().MakeArgString(AdditionalArgs)); - - // Add this flag to treat hip and hipv4 offload kinds as compatible with - // openmp offload kind while extracting code objects from a heterogenous - // archive library. Vice versa is also considered compatible. - std::string HipCompatibleArgs("-hip-openmp-compatible"); - UBArgs.push_back(C.getArgs().MakeArgString(HipCompatibleArgs)); - - C.addCommand(std::make_unique( - JA, T, ResponseFileSupport::AtFileCurCP(), UBProgram, UBArgs, Inputs, - InputInfo(&JA, C.getArgs().MakeArgString(OutputLib)))); - if (postClangLink) - CC1Args.push_back("-mlink-builtin-bitcode"); + ArgStringList UBArgs; + UBArgs.push_back(C.getArgs().MakeArgString(UnbundleArg)); + UBArgs.push_back(C.getArgs().MakeArgString(TypeArg)); + UBArgs.push_back(C.getArgs().MakeArgString(InputArg)); + UBArgs.push_back(C.getArgs().MakeArgString(OffloadArg)); + UBArgs.push_back(C.getArgs().MakeArgString(OutputArg)); - CC1Args.push_back(DriverArgs.MakeArgString(OutputLib)); - break; - } + // Add this flag to not exit from clang-offload-bundler if no compatible + // code object is found in heterogenous archive library. + std::string AdditionalArgs("-allow-missing-bundles"); + UBArgs.push_back(C.getArgs().MakeArgString(AdditionalArgs)); + + // Add this flag to treat hip and hipv4 offload kinds as compatible with + // openmp offload kind while extracting code objects from a heterogenous + // archive library. Vice versa is also considered compatible. + std::string HipCompatibleArgs("-hip-openmp-compatible"); + UBArgs.push_back(C.getArgs().MakeArgString(HipCompatibleArgs)); + + C.addCommand(std::make_unique( + JA, T, ResponseFileSupport::AtFileCurCP(), UBProgram, UBArgs, Inputs, + InputInfo(&JA, C.getArgs().MakeArgString(OutputLib)))); + if (postClangLink) + CC1Args.push_back("-mlink-builtin-bitcode"); + + CC1Args.push_back(DriverArgs.MakeArgString(OutputLib)); - return FoundAOB; + return true; } // Wrapper function used by driver for adding SDLs during link phase. @@ -2100,6 +2118,14 @@ SDLNames.insert(SDLName); } + llvm::Triple Triple(D.getTargetTriple()); + auto Ext = Triple.isWindowsMSVCEnvironment() ? ".lib" : ".a"; + + for (auto Input : DriverArgs.getAllArgValues(options::OPT_INPUT)) { + if (StringRef(Input).endswith(Ext)) + SDLNames.insert(Input); + } + // The search stops as soon as an SDL file is found. The driver then provides // the full filename of the SDL to the llvm-link or clang-nvlink-wrapper // command. If no SDL is found after searching each LINKPATH with Index: clang/test/Driver/hip-link-bundle-archive.hip =================================================================== --- clang/test/Driver/hip-link-bundle-archive.hip +++ clang/test/Driver/hip-link-bundle-archive.hip @@ -7,7 +7,17 @@ // RUN: %clang -### --offload-arch=gfx906 --offload-arch=gfx1030 \ // RUN: --target=x86_64-unknown-linux-gnu \ // RUN: -nogpulib %s -fgpu-rdc -L%T -lhipBundled \ -// RUN: 2>&1 | FileCheck -check-prefix=GNU %s +// RUN: 2>&1 | FileCheck -check-prefixes=GNU,GNU-L %s + +// RUN: %clang -### --offload-arch=gfx906 --offload-arch=gfx1030 \ +// RUN: --target=x86_64-unknown-linux-gnu \ +// RUN: -nogpulib %s -fgpu-rdc -L%T -l:libhipBundled.a \ +// RUN: 2>&1 | FileCheck -check-prefixes=GNU,GNU-LA %s + +// RUN: %clang -### --offload-arch=gfx906 --offload-arch=gfx1030 \ +// RUN: --target=x86_64-unknown-linux-gnu \ +// RUN: -nogpulib %s -fgpu-rdc %T/libhipBundled.a \ +// RUN: 2>&1 | FileCheck -check-prefixes=GNU,GNU-A %s // RUN: touch %T/hipBundled2.lib // RUN: %clang -### --offload-arch=gfx906 --offload-arch=gfx1030 \ @@ -15,14 +25,26 @@ // RUN: -nogpulib %s -fgpu-rdc -L%T -lhipBundled2 \ // RUN: 2>&1 | FileCheck -check-prefix=MSVC %s +// RUN: %clang -### --offload-arch=gfx906 --offload-arch=gfx1030 \ +// RUN: --target=x86_64-pc-windows-msvc \ +// RUN: -nogpulib %s -fgpu-rdc -L%T -l:hipBundled2.lib \ +// RUN: 2>&1 | FileCheck -check-prefix=MSVC %s + +// RUN: %clang -### --offload-arch=gfx906 --offload-arch=gfx1030 \ +// RUN: --target=x86_64-pc-windows-msvc \ +// RUN: -nogpulib %s -fgpu-rdc %T/hipBundled2.lib \ +// RUN: 2>&1 | FileCheck -check-prefix=MSVC %s + // GNU: "{{.*}}clang-offload-bundler" "-unbundle" "-type=a" "-input={{.*}}libhipBundled.a" "-targets=hip-amdgcn-amd-amdhsa-gfx1030" "-output=[[A1030:.*\.a]]" "-allow-missing-bundles" // GNU: "{{.*}}lld{{.*}}" {{.*}}"-plugin-opt=mcpu=gfx1030" {{.*}} "[[A1030]]" // GNU: "{{.*}}clang-offload-bundler" "-unbundle" "-type=a" "-input={{.*}}libhipBundled.a" "-targets=hip-amdgcn-amd-amdhsa-gfx906" "-output=[[A906:.*\.a]]" "-allow-missing-bundles" // GNU: "{{.*}}lld{{.*}}" {{.*}}"-plugin-opt=mcpu=gfx906" {{.*}} "[[A906]]" -// GNU: "{{.*}}ld{{.*}}" {{.*}}"-o" "a.out" {{.*}}"-lhipBundled" +// GNU-L: "{{.*}}ld{{.*}}" {{.*}}"-o" "a.out" {{.*}}"-lhipBundled" +// GNU-LA: "{{.*}}ld{{.*}}" {{.*}}"-o" "a.out" {{.*}}"-l:libhipBundled.a" +// GNU-A: "{{.*}}ld{{.*}}" {{.*}}"-o" "a.out" "{{.*}}libhipBundled.a" // MSVC: "{{.*}}clang-offload-bundler" "-unbundle" "-type=a" "-input={{.*}}hipBundled2.lib" "-targets=hip-amdgcn-amd-amdhsa-gfx1030" "-output=[[A1030:.*\.a]]" "-allow-missing-bundles" // MSVC: "{{.*}}lld{{.*}}" {{.*}}"-plugin-opt=mcpu=gfx1030" {{.*}} "[[A1030]]" // MSVC: "{{.*}}clang-offload-bundler" "-unbundle" "-type=a" "-input={{.*}}hipBundled2.lib" "-targets=hip-amdgcn-amd-amdhsa-gfx906" "-output=[[A906:.*\.a]]" "-allow-missing-bundles" // MSVC: "{{.*}}lld{{.*}}" {{.*}}"-plugin-opt=mcpu=gfx906" {{.*}} "[[A906]]" -// MSVC: "{{.*}}link{{.*}}" {{.*}}"-out:a.exe" {{.*}}"hipBundled2.lib" +// MSVC: "{{.*}}link{{.*}}" {{.*}}"-out:a.exe" {{.*}}hipBundled2.lib"