diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp --- a/llvm/lib/Linker/IRMover.cpp +++ b/llvm/lib/Linker/IRMover.cpp @@ -20,6 +20,7 @@ #include "llvm/IR/TypeFinder.h" #include "llvm/Object/ModuleSymbolTable.h" #include "llvm/Support/Error.h" +#include "llvm/Support/Path.h" #include "llvm/Transforms/Utils/Cloning.h" #include using namespace llvm; @@ -1443,21 +1444,47 @@ if (DstM.getDataLayout().isDefault()) DstM.setDataLayout(SrcM->getDataLayout()); - if (SrcM->getDataLayout() != DstM.getDataLayout()) { - emitWarning("Linking two modules of different data layouts: '" + - SrcM->getModuleIdentifier() + "' is '" + - SrcM->getDataLayoutStr() + "' whereas '" + - DstM.getModuleIdentifier() + "' is '" + - DstM.getDataLayoutStr() + "'\n"); - } - // Copy the target triple from the source to dest if the dest's is empty. if (DstM.getTargetTriple().empty() && !SrcM->getTargetTriple().empty()) DstM.setTargetTriple(SrcM->getTargetTriple()); Triple SrcTriple(SrcM->getTargetTriple()), DstTriple(DstM.getTargetTriple()); - if (!SrcM->getTargetTriple().empty()&& + // During CUDA compilation we have to link with the bitcode supplied with + // CUDA. libdevice bitcode either has no data layout set (pre-CUDA-11), or has + // the layout that is different from the one used by LLVM/clang (it does not + // include i128). Issuing a warning is not very helpful as there's not much + // the user can do about it. + bool EnableDLWarning = true; + bool EnableTripleWarning = true; + if (SrcTriple.isNVPTX() && DstTriple.isNVPTX()) { + std::string ModuleId = SrcM->getModuleIdentifier(); + StringRef FileName = llvm::sys::path::filename(ModuleId); + bool SrcIsLibDevice = + FileName.startswith("libdevice") && FileName.endswith(".10.bc"); + bool SrcHasLibDeviceDL = + (SrcM->getDataLayoutStr().empty() || + SrcM->getDataLayoutStr() == "e-i64:64-v16:16-v32:32-n16:32:64"); + // libdevice bitcode uses nvptx64-nvidia-gpulibs or just + // 'nvptx-unknown-unknown' triple (before CUDA-10.x) and is compatible with + // all NVPTX variants. + bool SrcHasLibDeviceTriple = (SrcTriple.getVendor() == Triple::NVIDIA && + SrcTriple.getOSName() == "gpulibs") || + (SrcTriple.getVendorName() == "unknown" && + SrcTriple.getOSName() == "unknown"); + EnableTripleWarning = !(SrcIsLibDevice && SrcHasLibDeviceTriple); + EnableDLWarning = !(SrcIsLibDevice && SrcHasLibDeviceDL); + } + + if (EnableDLWarning && (SrcM->getDataLayout() != DstM.getDataLayout())) { + emitWarning("Linking two modules of different data layouts: '" + + SrcM->getModuleIdentifier() + "' is '" + + SrcM->getDataLayoutStr() + "' whereas '" + + DstM.getModuleIdentifier() + "' is '" + + DstM.getDataLayoutStr() + "'\n"); + } + + if (EnableTripleWarning && !SrcM->getTargetTriple().empty() && !SrcTriple.isCompatibleWith(DstTriple)) emitWarning("Linking two modules of different target triples: '" + SrcM->getModuleIdentifier() + "' is '" +