#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 <utility>
using namespace llvm;
if (DstM.getDataLayout().isDefault())
DstM.setDataLayout(SrcM->getDataLayout());
- if (SrcM->getDataLayout() != DstM.getDataLayout()) {
+ // 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());
+
+ // 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.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()&&
+ if (EnableTripleWarning && !SrcM->getTargetTriple().empty() &&
!SrcTriple.isCompatibleWith(DstTriple))
emitWarning("Linking two modules of different target triples: '" +
SrcM->getModuleIdentifier() + "' is '" +
--- /dev/null
+; Prepare bitcode files.
+; RUN: rm -rf %t && mkdir -p %t
+; RUN: llvm-as %s -o %t/main.bc
+; RUN: llvm-as %p/Inputs/libdevice-cuda-9.ll -o %t/libdevice.compute_35.10.bc
+; RUN: llvm-as %p/Inputs/libdevice-cuda-10.ll -o %t/libdevice.10.bc
+; RUN: llvm-as %p/Inputs/libdevice-cuda-11.ll -o %t/libdevice.11.10.bc
+; RUN: llvm-as %p/Inputs/libdevice-cuda-9.ll -o %t/correct-libdevice-wrong-filename.bc
+; RUN: llvm-as %p/Inputs/not-a-libdevice.ll -o %t/libdevice-with-wrong-info.bc
+
+; No warnings expected when we link with libdevice variants
+; RUN: llvm-link %t/main.bc %t/libdevice.compute_35.10.bc -S 2>&1 \
+; RUN: | FileCheck --check-prefixes COMMON,NOWARN %s
+; RUN: llvm-link %t/main.bc %t/libdevice.10.bc -S 2>&1 \
+; RUN: | FileCheck --check-prefixes COMMON,NOWARN %s
+; RUN: llvm-link %t/main.bc %t/libdevice.11.10.bc -S 2>&1 \
+; RUN: | FileCheck --check-prefixes COMMON,NOWARN %s
+
+; But make sure we still issue warnings if we see unexpected filename, or
+; unexpected triple or datalayout within a libdevice filename.
+; RUN: llvm-link %t/main.bc %t/correct-libdevice-wrong-filename.bc -S 2>&1 \
+; RUN: | FileCheck --check-prefixes COMMON,WARN-TRIPLE %s
+; RUN: llvm-link %t/main.bc %t/libdevice-with-wrong-info.bc -S 2>&1 \
+; RUN: | FileCheck --check-prefixes COMMON,WARN-TRIPLE,WARN-DL %s
+
+
+target triple = "nvptx64-nvidia-cuda"
+target datalayout = "e-i64:64-i128:128-v16:16-v32:32-n16:32:64"
+
+; WARN-TRIPLE-DAG: warning: Linking two modules of different target triples:
+; WARN-DL-DAG: warning: Linking two modules of different data layouts:
+
+; NOWARN-NOT: warning:
+; COMMON-DAG: target triple = "nvptx64-nvidia-cuda"
+; NOWARN-NOT: warning: