[lld] [ELF] Support NVPTX bitcode in LTO output modes (PR #200679)
Lukas Stephan via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 3 07:09:08 PDT 2026
https://github.com/kulst updated https://github.com/llvm/llvm-project/pull/200679
>From 1600368a2326778ed33e65a39c7640e63b0d6412 Mon Sep 17 00:00:00 2001
From: kulst <60887784+kulst at users.noreply.github.com>
Date: Sun, 31 May 2026 17:11:34 +0200
Subject: [PATCH] [ELF] Support NVPTX bitcode in LTO output modes
lld currently rejects nvptx and nvptx64 bitcode inputs because
getBitcodeMachineKind() cannot infer an ELF machine type from the
target triple.
Map nvptx and nvptx64 bitcode modules to EM_CUDA so that they can
participate in lld's LTO pipeline.
This allows lld to perform LTO over NVPTX LLVM bitcode and emit
the resulting assembly or LLVM IR using the existing
--lto-emit-asm and --lto-emit-llvm modes.
Since NVPTX does not support normal ELF output, restrict EM_CUDA
inputs to LTO output modes and emit an error unless
--lto-emit-asm or --lto-emit-llvm is specified.
EM_CUDA is used only as an identifier for the LTO pipeline; this
change does not add support for producing CUDA ELF files.
---
lld/ELF/Driver.cpp | 5 +++++
lld/ELF/InputFiles.cpp | 3 +++
lld/test/ELF/lto/nvptx-bitcode.ll | 23 +++++++++++++++++++++++
lld/test/lit.cfg.py | 1 +
4 files changed, 32 insertions(+)
create mode 100644 lld/test/ELF/lto/nvptx-bitcode.ll
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 7ec7dfcae6bca..18a0ff757cf52 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -399,6 +399,11 @@ static void checkOptions(Ctx &ctx) {
ctx.arg.zCetReport != ReportPolicy::None)
ErrAlways(ctx) << "-z cet-report only supported on X86 and X86_64";
+ if (ctx.arg.emachine == EM_CUDA && !ctx.arg.ltoEmitAsm && !ctx.arg.emitLLVM) {
+ ErrAlways(ctx) << "CUDA bitcode inputs are only supported with "
+ "--lto-emit-asm or --lto-emit-llvm";
+ }
+
if (ctx.arg.pie && ctx.arg.shared)
ErrAlways(ctx) << "-shared and -pie may not be used together";
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 2f544f0fe0958..0412aa46c8c23 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -1783,6 +1783,9 @@ static uint16_t getBitcodeMachineKind(Ctx &ctx, StringRef path,
return t.isOSIAMCU() ? EM_IAMCU : EM_386;
case Triple::x86_64:
return EM_X86_64;
+ case Triple::nvptx:
+ case Triple::nvptx64:
+ return EM_CUDA;
default:
ErrAlways(ctx) << path
<< ": could not infer e_machine from bitcode target triple "
diff --git a/lld/test/ELF/lto/nvptx-bitcode.ll b/lld/test/ELF/lto/nvptx-bitcode.ll
new file mode 100644
index 0000000000000..bb876a9088163
--- /dev/null
+++ b/lld/test/ELF/lto/nvptx-bitcode.ll
@@ -0,0 +1,23 @@
+; REQUIRES: nvptx
+
+; RUN: llvm-as %s -o %t.bc
+; RUN: ld.lld --lto-emit-asm --plugin-opt=-mcpu=sm_70 --plugin-opt=-mattr=+ptx70 %t.bc -o %t
+;
+; lld writes assembly output produced by LTO to a .lto.s side file.
+; RUN: FileCheck %s --check-prefix=PTX < %t.lto.s
+
+; RUN: ld.lld --lto-emit-llvm %t.bc -o %t.lto.bc
+; RUN: llvm-dis %t.lto.bc -o - | FileCheck %s --check-prefix=LLVM
+
+; RUN: not ld.lld %t.bc -o %t.out 2>&1 | FileCheck %s --check-prefix=ERR
+
+target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64"
+target triple = "nvptx64-nvidia-cuda"
+
+; PTX: .version 7.0
+; PTX: .target sm_70
+; PTX: .address_size 64
+
+; LLVM: target triple = "nvptx64-nvidia-cuda"
+
+; ERR: error: CUDA bitcode inputs are only supported with --lto-emit-asm or --lto-emit-llvm
diff --git a/lld/test/lit.cfg.py b/lld/test/lit.cfg.py
index 39c3d0aa36bfb..c16d1fa94b4e6 100644
--- a/lld/test/lit.cfg.py
+++ b/lld/test/lit.cfg.py
@@ -93,6 +93,7 @@
"LoongArch": "loongarch",
"Mips": "mips",
"MSP430": "msp430",
+ "NVPTX": "nvptx",
"PowerPC": "ppc",
"RISCV": "riscv",
"Sparc": "sparc",
More information about the llvm-commits
mailing list