[llvm] 3af981b - [IRLinker] Suppress linker warnings when linking with CUDA libdevice.

Artem Belevich via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 1 10:45:23 PDT 2021


Author: Artem Belevich
Date: 2021-09-01T10:45:15-07:00
New Revision: 3af981b0659ffb2445dee60f1ec14ba417b7d9b1

URL: https://github.com/llvm/llvm-project/commit/3af981b0659ffb2445dee60f1ec14ba417b7d9b1
DIFF: https://github.com/llvm/llvm-project/commit/3af981b0659ffb2445dee60f1ec14ba417b7d9b1.diff

LOG: [IRLinker] Suppress linker warnings when linking with CUDA libdevice.

libdevice bitcode provided by NVIDIA is linked with clang/LLVM-generated IR
which uses nvptx*-nvidia-cuda triple. We need to mark them as compatible.

Differential Revision: https://reviews.llvm.org/D108835

Added: 
    llvm/test/Linker/Inputs/libdevice-cuda-10.ll
    llvm/test/Linker/Inputs/libdevice-cuda-11.ll
    llvm/test/Linker/Inputs/libdevice-cuda-9.ll
    llvm/test/Linker/Inputs/not-a-libdevice.ll
    llvm/test/Linker/cuda-libdevice.ll

Modified: 
    llvm/lib/Linker/IRMover.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp
index 7bc6f05859212..0e75854e2bc0b 100644
--- 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 <utility>
 using namespace llvm;
@@ -1443,7 +1444,39 @@ Error IRLinker::run() {
   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 
diff erent 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 
diff erent data layouts: '" +
                 SrcM->getModuleIdentifier() + "' is '" +
                 SrcM->getDataLayoutStr() + "' whereas '" +
@@ -1451,13 +1484,7 @@ Error IRLinker::run() {
                 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 
diff erent target triples: '" +
                 SrcM->getModuleIdentifier() + "' is '" +

diff  --git a/llvm/test/Linker/Inputs/libdevice-cuda-10.ll b/llvm/test/Linker/Inputs/libdevice-cuda-10.ll
new file mode 100644
index 0000000000000..0a969f4209707
--- /dev/null
+++ b/llvm/test/Linker/Inputs/libdevice-cuda-10.ll
@@ -0,0 +1,2 @@
+target triple = "nvptx64-nvidia-gpulibs"
+

diff  --git a/llvm/test/Linker/Inputs/libdevice-cuda-11.ll b/llvm/test/Linker/Inputs/libdevice-cuda-11.ll
new file mode 100644
index 0000000000000..3cbe968ba1cfc
--- /dev/null
+++ b/llvm/test/Linker/Inputs/libdevice-cuda-11.ll
@@ -0,0 +1,3 @@
+target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64"
+target triple = "nvptx64-nvidia-gpulibs"
+

diff  --git a/llvm/test/Linker/Inputs/libdevice-cuda-9.ll b/llvm/test/Linker/Inputs/libdevice-cuda-9.ll
new file mode 100644
index 0000000000000..f51ee61c83056
--- /dev/null
+++ b/llvm/test/Linker/Inputs/libdevice-cuda-9.ll
@@ -0,0 +1,2 @@
+target triple = "nvptx-unknown-unknown"
+

diff  --git a/llvm/test/Linker/Inputs/not-a-libdevice.ll b/llvm/test/Linker/Inputs/not-a-libdevice.ll
new file mode 100644
index 0000000000000..099792a7157f1
--- /dev/null
+++ b/llvm/test/Linker/Inputs/not-a-libdevice.ll
@@ -0,0 +1,2 @@
+target triple = "nvptx64-nvidia-nosuchthing"
+target datalayout = "e-i64:64-i128:128-v32:32-n16:32:64"

diff  --git a/llvm/test/Linker/cuda-libdevice.ll b/llvm/test/Linker/cuda-libdevice.ll
new file mode 100644
index 0000000000000..484e8339a136e
--- /dev/null
+++ b/llvm/test/Linker/cuda-libdevice.ll
@@ -0,0 +1,34 @@
+; 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 
diff erent target triples:
+; WARN-DL-DAG: warning: Linking two modules of 
diff erent data layouts:
+
+; NOWARN-NOT: warning:
+; COMMON-DAG: target triple = "nvptx64-nvidia-cuda"
+; NOWARN-NOT: warning:


        


More information about the llvm-commits mailing list