[clang] [HIP][SPIR-V] Ignore --no-lto for SPIR-V targets (PR #204609)
Dmitry Sidorov via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 18 07:33:19 PDT 2026
https://github.com/MrSidims created https://github.com/llvm/llvm-project/pull/204609
The patch adds a guard to workaround the issue, when HIP is compiled with multiple --offload-arch options, one of which is pointing to SPIR-V offloading. As SPIR-V has no 'no-lto' pipeline - we need to ignore 'no-lto' request for this target.
>From 282cb151c0b897629327550329d7b7882601fa45 Mon Sep 17 00:00:00 2001
From: Dmitry Sidorov <Dmitry.Sidorov at amd.com>
Date: Thu, 18 Jun 2026 07:14:15 -0500
Subject: [PATCH] [HIP][SPIR-V] Ignore --no-lto for SPIR-V targets
The patch adds a guard to workaround the issue, when HIP is compiled
with multiple --offload-arch options, one of which is pointing to SPIR-V
offloading. As SPIR-V has no 'no-lto' pipeline - we need to ignore
'no-lto' request for this target.
---
.../linker-wrapper-hip-no-rdc-amdgcnspirv.c | 23 +++++++++++++++++++
.../ClangLinkerWrapper.cpp | 6 +++--
2 files changed, 27 insertions(+), 2 deletions(-)
create mode 100644 clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper-hip-no-rdc-amdgcnspirv.c
diff --git a/clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper-hip-no-rdc-amdgcnspirv.c b/clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper-hip-no-rdc-amdgcnspirv.c
new file mode 100644
index 0000000000000..205735f730cb9
--- /dev/null
+++ b/clang/test/OffloadTools/clang-linker-wrapper/linker-wrapper-hip-no-rdc-amdgcnspirv.c
@@ -0,0 +1,23 @@
+// REQUIRES: amdgpu-registered-target
+// REQUIRES: spirv-registered-target
+
+// In a mixed non-RDC HIP compile, a global --no-lto must drive the concrete
+// arch onto the non-LTO pipeline while being ignored for SPIR-V.
+
+// RUN: %clang -cc1 %s -triple amdgcn-amd-amdhsa -emit-llvm-bc -o %t.amdgpu.bc
+// RUN: %clang -cc1 %s -triple spirv64-amd-amdhsa -emit-llvm-bc -o %t.spirv.bc
+// RUN: llvm-offload-binary -o %t.out \
+// RUN: --image=file=%t.amdgpu.bc,kind=hip,triple=amdgcn-amd-amdhsa,arch=gfx1200 \
+// RUN: --image=file=%t.spirv.bc,kind=hip,triple=spirv64-amd-amdhsa,arch=amdgcnspirv
+
+// RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run --no-lto \
+// RUN: --emit-fatbin-only --linker-path=/usr/bin/ld %t.out -o %t.hipfb 2>&1 \
+// RUN: | FileCheck %s
+
+// The concrete arch honors --no-lto
+// CHECK: clang{{.*}} --target=amdgcn-amd-amdhsa -mcpu=gfx1200 {{.*}}-x ir {{.*}}-flto=none
+
+// SPIR-V ignores the leaked --no-lto
+// CHECK: clang{{.*}} --target=spirv64-amd-amdhsa -march=amdgcnspirv
+// CHECK-NOT: -x ir
+// CHECK-NOT: -flto=none
diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index cfdd11e1d298d..a4a67eed7d47f 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -549,7 +549,9 @@ Expected<StringRef> clang(ArrayRef<StringRef> InputFiles, const ArgList &Args,
// the LTO link and defeat the non-LTO pipeline.
// FIXME: This is a stop-gap for non-RDC. Longer term, RDC and non-RDC should
// share a unified interface.
- if (Args.hasArg(OPT_no_lto))
+ // SPIR-V has no non-LTO pipeline so a --no-lto leaked from a concrete arch in
+ // a multi-target compile is ignored. Which is a workaround to remove.
+ if (Args.hasArg(OPT_no_lto) && !Triple.isSPIRV())
CmdArgs.append({"-x", "ir"});
for (StringRef InputFile : InputFiles)
CmdArgs.push_back(InputFile);
@@ -613,7 +615,7 @@ Expected<StringRef> clang(ArrayRef<StringRef> InputFiles, const ArgList &Args,
for (StringRef Arg : Args.getAllArgValues(OPT_compiler_arg_EQ))
CmdArgs.push_back(Args.MakeArgString(Arg));
- if (Args.hasArg(OPT_no_lto))
+ if (Args.hasArg(OPT_no_lto) && !Triple.isSPIRV())
CmdArgs.append({"-flto=none", "-Wno-unused-command-line-argument"});
if (Error Err = executeCommands(*ClangPath, CmdArgs))
More information about the cfe-commits
mailing list