https://github.com/jhuber6 updated 
https://github.com/llvm/llvm-project/pull/144576

>From 92db44cf46098f9171b06d0251b632eb1ff6d5e6 Mon Sep 17 00:00:00 2001
From: Joseph Huber <hube...@outlook.com>
Date: Tue, 17 Jun 2025 12:58:14 -0500
Subject: [PATCH] [Clang] Add standalone AMDGPU SPIR-V toolchain

Summary:
The AMDGPU toolchain uses a different set of tools than the standard
SPIR-V toolchain. The linker wrapper prefers to invoke a linker via a
clang toolchain. To make that work we introduce
`--target=spirv64-amd-amdhsa` so that it creates the linking phases that
HIP prefers. Additionally, this can be used to make LLVM-IR / SPIR-V
from C/C++ that can be linked with the HIP output.
---
 clang/lib/Driver/Driver.cpp             | 16 +++++++++++-----
 clang/lib/Driver/ToolChains/HIPAMD.cpp  | 14 ++++++++++++++
 clang/lib/Driver/ToolChains/HIPAMD.h    |  9 +++++++++
 clang/test/Driver/spirv-amd-toolchain.c | 19 +++++++++++++++++++
 4 files changed, 53 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/Driver/spirv-amd-toolchain.c

diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 060f76fb653c9..cd93456dfa5cd 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -6849,11 +6849,17 @@ const ToolChain &Driver::getToolChain(const ArgList 
&Args,
       TC = std::make_unique<toolchains::NVPTXToolChain>(*this, Target, Args);
       break;
     case llvm::Triple::AMDHSA: {
-      bool DL =
-          usesInput(Args, types::isOpenCL) || usesInput(Args, types::isLLVMIR);
-      TC = DL ? std::make_unique<toolchains::ROCMToolChain>(*this, Target, 
Args)
-              : std::make_unique<toolchains::AMDGPUToolChain>(*this, Target,
-                                                              Args);
+      if (Target.getArch() == llvm::Triple::spirv64) {
+        TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*this, Target,
+                                                             Args);
+      } else {
+        bool DL = usesInput(Args, types::isOpenCL) ||
+                  usesInput(Args, types::isLLVMIR);
+        TC = DL ? std::make_unique<toolchains::ROCMToolChain>(*this, Target,
+                                                              Args)
+                : std::make_unique<toolchains::AMDGPUToolChain>(*this, Target,
+                                                                Args);
+      }
       break;
     }
     case llvm::Triple::AMDPAL:
diff --git a/clang/lib/Driver/ToolChains/HIPAMD.cpp 
b/clang/lib/Driver/ToolChains/HIPAMD.cpp
index a8f2b09b1b20f..7b47dcf366e05 100644
--- a/clang/lib/Driver/ToolChains/HIPAMD.cpp
+++ b/clang/lib/Driver/ToolChains/HIPAMD.cpp
@@ -417,3 +417,17 @@ void HIPAMDToolChain::checkTargetID(
     getDriver().Diag(clang::diag::err_drv_bad_target_id)
         << *PTID.OptionalTargetID;
 }
+
+SPIRVAMDToolChain::SPIRVAMDToolChain(const Driver &D,
+                                     const llvm::Triple &Triple,
+                                     const ArgList &Args)
+    : ROCMToolChain(D, Triple, Args) {
+  // Lookup binaries into the driver directory, this is used to
+  // discover the clang-offload-bundler executable.
+  getProgramPaths().push_back(getDriver().Dir);
+}
+
+Tool *SPIRVAMDToolChain::buildLinker() const {
+  assert(getTriple().getArch() == llvm::Triple::spirv64);
+  return new tools::AMDGCN::Linker(*this);
+}
diff --git a/clang/lib/Driver/ToolChains/HIPAMD.h 
b/clang/lib/Driver/ToolChains/HIPAMD.h
index c31894e22c5c8..3630b11cd8b1a 100644
--- a/clang/lib/Driver/ToolChains/HIPAMD.h
+++ b/clang/lib/Driver/ToolChains/HIPAMD.h
@@ -97,6 +97,15 @@ class LLVM_LIBRARY_VISIBILITY HIPAMDToolChain final : public 
ROCMToolChain {
   Tool *buildLinker() const override;
 };
 
+class LLVM_LIBRARY_VISIBILITY SPIRVAMDToolChain final : public ROCMToolChain {
+public:
+  SPIRVAMDToolChain(const Driver &D, const llvm::Triple &Triple,
+                    const llvm::opt::ArgList &Args);
+
+protected:
+  Tool *buildLinker() const override;
+};
+
 } // end namespace toolchains
 } // end namespace driver
 } // end namespace clang
diff --git a/clang/test/Driver/spirv-amd-toolchain.c 
b/clang/test/Driver/spirv-amd-toolchain.c
new file mode 100644
index 0000000000000..c9417400a9378
--- /dev/null
+++ b/clang/test/Driver/spirv-amd-toolchain.c
@@ -0,0 +1,19 @@
+// RUN: %clang -### -ccc-print-phases --target=spirv64-amd-amdhsa %s 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=PHASES
+// PHASES: 0: input, "[[INPUT:.+]]", c
+// PHASES: 1: preprocessor, {0}, cpp-output
+// PHASES: 2: compiler, {1}, ir
+// PHASES: 3: backend, {2}, assembler
+// PHASES: 4: assembler, {3}, object
+// PHASES: 5: linker, {4}, image
+
+// RUN: %clang -### -ccc-print-bindings --target=spirv64-amd-amdhsa %s 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=BINDINGS
+// BINDINGS: # "spirv64-amd-amdhsa" - "clang", inputs: ["[[INPUT:.+]]"], 
output: "[[OUTPUT:.+]]"
+// BINDINGS: # "spirv64-amd-amdhsa" - "AMDGCN::Linker", inputs: 
["[[OUTPUT]]"], output: "a.out"
+
+// RUN: %clang -### --target=spirv64-amd-amdhsa %s -nogpulib -nogpuinc 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=INVOCATION
+// INVOCATION: "-cc1" "-triple" "spirv64-amd-amdhsa" {{.*}} "-o" 
"[[OUTPUT:.+]]" "-x" "c"
+// INVOCATION: "{{.*}}llvm-link" "-o" "a.out" "[[OUTPUT]]"
+// INVOCATION: "{{.*}}llvm-spirv" "--spirv-max-version=1.6" "--spirv-ext=+all" 
"--spirv-allow-unknown-intrinsics" "--spirv-lower-const-expr" 
"--spirv-preserve-auxdata" "--spirv-debug-info-version=nonsemantic-shader-200" 
"a.out" "-o" "a.out"

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to