[clang] [HIP][SPIRV] Enable the SPIRV backend instead of the translator through an experimental flag. (PR #162282)

Manuel Carrasco via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 16 02:25:41 PDT 2025


https://github.com/mgcarrasco updated https://github.com/llvm/llvm-project/pull/162282

>From e89ce89521602f651495cf936e016d8f0c926974 Mon Sep 17 00:00:00 2001
From: Manuel Carrasco <Manuel.Carrasco at amd.com>
Date: Tue, 7 Oct 2025 06:05:21 -0700
Subject: [PATCH 1/5] [HIP][SPIRV] Enable the SPIRV backend instead of the
 translator through an experimental flag.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: Juan Manuel Martinez CaamaƱo <juamarti at amd.com>
---
 clang/include/clang/Driver/Options.td        | 14 ++++++++
 clang/lib/Driver/ToolChains/HIPAMD.cpp       | 36 +++++++++++++++-----
 clang/test/Driver/amdgpu-spirv-backend-opt.c | 12 +++++++
 3 files changed, 53 insertions(+), 9 deletions(-)
 create mode 100644 clang/test/Driver/amdgpu-spirv-backend-opt.c

diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index ec38231f906eb..37dbb820ce22f 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5483,6 +5483,20 @@ defm wavefrontsize64 : SimpleMFlag<"wavefrontsize64",
 defm amdgpu_precise_memory_op
     : SimpleMFlag<"amdgpu-precise-memory-op", "Enable", "Disable",
                   " precise memory mode (AMDGPU only)">;
+def amdgpu_use_experimental_spirv_backend
+    : Flag<["-"], "amdgpu-use-experimental-spirv-backend">,
+      Group<m_amdgpu_Features_Group>,
+      Flags<[HelpHidden]>,
+      Visibility<[ClangOption]>,
+      HelpText<"Use experimental SPIRV backend for AMDGPU compilation (AMDGPU "
+               "only)">;
+def no_amdgpu_use_experimental_spirv_backend
+    : Flag<["-"], "no-amdgpu-use-experimental-spirv-backend">,
+      Group<m_amdgpu_Features_Group>,
+      Flags<[HelpHidden]>,
+      Visibility<[ClangOption]>,
+      HelpText<"Do not use experimental SPIRV backend for AMDGPU compilation "
+               "(AMDGPU only)">;
 
 def munsafe_fp_atomics : Flag<["-"], "munsafe-fp-atomics">,
   Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, Alias<fatomic_ignore_denormal_mode>;
diff --git a/clang/lib/Driver/ToolChains/HIPAMD.cpp b/clang/lib/Driver/ToolChains/HIPAMD.cpp
index c0c8afec07264..aeccf381c7a63 100644
--- a/clang/lib/Driver/ToolChains/HIPAMD.cpp
+++ b/clang/lib/Driver/ToolChains/HIPAMD.cpp
@@ -175,15 +175,33 @@ void AMDGCN::Linker::constructLinkAndEmitSpirvCommand(
 
   constructLlvmLinkCommand(C, JA, Inputs, LinkedBCFile, Args);
 
-  // Emit SPIR-V binary.
-  llvm::opt::ArgStringList TrArgs{
-      "--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"};
-  SPIRV::constructTranslateCommand(C, *this, JA, Output, LinkedBCFile, TrArgs);
+  bool UseSPIRVBackend = Args.hasFlag(
+      options::OPT_amdgpu_use_experimental_spirv_backend,
+      options::OPT_no_amdgpu_use_experimental_spirv_backend, /*Default=*/false);
+
+  // Emit SPIR-V binary either using the SPIRV backend or the translator.
+  if (UseSPIRVBackend) {
+    llvm::opt::ArgStringList CmdArgs;
+    const char *Triple =
+        C.getArgs().MakeArgString("-triple=spirv64-amd-amdhsa");
+    CmdArgs.append({"-cc1", Triple, "-emit-obj", LinkedBCFile.getFilename(),
+                    "-o", Output.getFilename()});
+    const char *Exec = getToolChain().getDriver().getClangProgramPath();
+    C.addCommand(std::make_unique<Command>(JA, *this,
+                                           ResponseFileSupport::None(), Exec,
+                                           CmdArgs, LinkedBCFile, Output));
+  } else {
+    // Use the SPIRV translator for code gen.
+    llvm::opt::ArgStringList TrArgs{
+        "--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"};
+    SPIRV::constructTranslateCommand(C, *this, JA, Output, LinkedBCFile,
+                                     TrArgs);
+  }
 }
 
 // For amdgcn the inputs of the linker job are device bitcode and output is
diff --git a/clang/test/Driver/amdgpu-spirv-backend-opt.c b/clang/test/Driver/amdgpu-spirv-backend-opt.c
new file mode 100644
index 0000000000000..0435ad9dad6d1
--- /dev/null
+++ b/clang/test/Driver/amdgpu-spirv-backend-opt.c
@@ -0,0 +1,12 @@
+// COM: This test case validates the behavior of -amdgpu-use-experimental-spirv-backend
+
+// COM: Test that -amdgpu-use-experimental-spirv-backend calls clang -cc1 with the SPIRV triple.
+// RUN: %clang -x hip %s --cuda-device-only --offload-arch=amdgcnspirv -amdgpu-use-experimental-spirv-backend -nogpuinc -nogpulib -### 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-BACKEND
+// CHECK-SPIRV-BACKEND: "{{.*}}clang{{.*}}" "-cc1" "{{.*-triple=spirv64-amd-amdhsa}}"
+
+// COM: Test that -no-amdgpu-use-experimental-spirv-backend calls the SPIRV translator
+// RUN: %clang -x hip %s --cuda-device-only --offload-arch=amdgcnspirv -no-amdgpu-use-experimental-spirv-backend -nogpuinc -nogpulib -### 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-TRANSLATOR
+// CHECK-SPIRV-TRANSLATOR: "{{.*llvm-spirv.*}}" "{{--spirv-max-version=[0-9]+\.[0-9]}}"
+
+// COM: Test that by default we use the translator
+// RUN: %clang -x hip %s --cuda-device-only --offload-arch=amdgcnspirv -nogpuinc -nogpulib -### 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-TRANSLATOR

>From 8d56d95ebc8f5ce620b08eb7af516a645364af9c Mon Sep 17 00:00:00 2001
From: Manuel Carrasco <Manuel.Carrasco at amd.com>
Date: Fri, 10 Oct 2025 01:49:49 -0700
Subject: [PATCH 2/5] Switch to hip prefix for new flags.

---
 clang/include/clang/Driver/Options.td        | 26 +++++++++-----------
 clang/lib/Driver/ToolChains/HIPAMD.cpp       |  4 +--
 clang/test/Driver/amdgpu-spirv-backend-opt.c | 12 ---------
 clang/test/Driver/hip-spirv-backend-opt.c    | 12 +++++++++
 4 files changed, 26 insertions(+), 28 deletions(-)
 delete mode 100644 clang/test/Driver/amdgpu-spirv-backend-opt.c
 create mode 100644 clang/test/Driver/hip-spirv-backend-opt.c

diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 37dbb820ce22f..7da478e5e71d6 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1421,6 +1421,18 @@ def fhip_emit_relocatable : Flag<["-"], "fhip-emit-relocatable">,
   HelpText<"Compile HIP source to relocatable">;
 def fno_hip_emit_relocatable : Flag<["-"], "fno-hip-emit-relocatable">,
   HelpText<"Do not override toolchain to compile HIP source to relocatable">;
+def hip_use_experimental_spirv_backend
+    : Flag<["-"], "hip-use-experimental-spirv-backend">,
+      Group<hip_Group>,
+      Flags<[HelpHidden]>,
+      HelpText<"Use experimental SPIRV backend for HIP compilation (HIP "
+               "only)">;
+def no_hip_use_experimental_spirv_backend
+    : Flag<["-"], "no-hip-use-experimental-spirv-backend">,
+      Group<hip_Group>,
+      Flags<[HelpHidden]>,
+      HelpText<"Do not use experimental SPIRV backend for HIP compilation "
+               "(HIP only)">;
 }
 
 // Clang specific/exclusive options for OpenACC.
@@ -5483,20 +5495,6 @@ defm wavefrontsize64 : SimpleMFlag<"wavefrontsize64",
 defm amdgpu_precise_memory_op
     : SimpleMFlag<"amdgpu-precise-memory-op", "Enable", "Disable",
                   " precise memory mode (AMDGPU only)">;
-def amdgpu_use_experimental_spirv_backend
-    : Flag<["-"], "amdgpu-use-experimental-spirv-backend">,
-      Group<m_amdgpu_Features_Group>,
-      Flags<[HelpHidden]>,
-      Visibility<[ClangOption]>,
-      HelpText<"Use experimental SPIRV backend for AMDGPU compilation (AMDGPU "
-               "only)">;
-def no_amdgpu_use_experimental_spirv_backend
-    : Flag<["-"], "no-amdgpu-use-experimental-spirv-backend">,
-      Group<m_amdgpu_Features_Group>,
-      Flags<[HelpHidden]>,
-      Visibility<[ClangOption]>,
-      HelpText<"Do not use experimental SPIRV backend for AMDGPU compilation "
-               "(AMDGPU only)">;
 
 def munsafe_fp_atomics : Flag<["-"], "munsafe-fp-atomics">,
   Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, Alias<fatomic_ignore_denormal_mode>;
diff --git a/clang/lib/Driver/ToolChains/HIPAMD.cpp b/clang/lib/Driver/ToolChains/HIPAMD.cpp
index aeccf381c7a63..1b8a9af197ff7 100644
--- a/clang/lib/Driver/ToolChains/HIPAMD.cpp
+++ b/clang/lib/Driver/ToolChains/HIPAMD.cpp
@@ -176,8 +176,8 @@ void AMDGCN::Linker::constructLinkAndEmitSpirvCommand(
   constructLlvmLinkCommand(C, JA, Inputs, LinkedBCFile, Args);
 
   bool UseSPIRVBackend = Args.hasFlag(
-      options::OPT_amdgpu_use_experimental_spirv_backend,
-      options::OPT_no_amdgpu_use_experimental_spirv_backend, /*Default=*/false);
+      options::OPT_hip_use_experimental_spirv_backend,
+      options::OPT_no_hip_use_experimental_spirv_backend, /*Default=*/false);
 
   // Emit SPIR-V binary either using the SPIRV backend or the translator.
   if (UseSPIRVBackend) {
diff --git a/clang/test/Driver/amdgpu-spirv-backend-opt.c b/clang/test/Driver/amdgpu-spirv-backend-opt.c
deleted file mode 100644
index 0435ad9dad6d1..0000000000000
--- a/clang/test/Driver/amdgpu-spirv-backend-opt.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// COM: This test case validates the behavior of -amdgpu-use-experimental-spirv-backend
-
-// COM: Test that -amdgpu-use-experimental-spirv-backend calls clang -cc1 with the SPIRV triple.
-// RUN: %clang -x hip %s --cuda-device-only --offload-arch=amdgcnspirv -amdgpu-use-experimental-spirv-backend -nogpuinc -nogpulib -### 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-BACKEND
-// CHECK-SPIRV-BACKEND: "{{.*}}clang{{.*}}" "-cc1" "{{.*-triple=spirv64-amd-amdhsa}}"
-
-// COM: Test that -no-amdgpu-use-experimental-spirv-backend calls the SPIRV translator
-// RUN: %clang -x hip %s --cuda-device-only --offload-arch=amdgcnspirv -no-amdgpu-use-experimental-spirv-backend -nogpuinc -nogpulib -### 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-TRANSLATOR
-// CHECK-SPIRV-TRANSLATOR: "{{.*llvm-spirv.*}}" "{{--spirv-max-version=[0-9]+\.[0-9]}}"
-
-// COM: Test that by default we use the translator
-// RUN: %clang -x hip %s --cuda-device-only --offload-arch=amdgcnspirv -nogpuinc -nogpulib -### 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-TRANSLATOR
diff --git a/clang/test/Driver/hip-spirv-backend-opt.c b/clang/test/Driver/hip-spirv-backend-opt.c
new file mode 100644
index 0000000000000..7fe9819514066
--- /dev/null
+++ b/clang/test/Driver/hip-spirv-backend-opt.c
@@ -0,0 +1,12 @@
+// COM: This test case validates the behavior of -hip-use-experimental-spirv-backend
+
+// COM: Test that -hip-use-experimental-spirv-backend calls clang -cc1 with the SPIRV triple.
+// RUN: %clang -x hip %s --cuda-device-only --offload-arch=amdgcnspirv -hip-use-experimental-spirv-backend -nogpuinc -nogpulib -### 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-BACKEND
+// CHECK-SPIRV-BACKEND: "{{.*}}clang{{.*}}" "-cc1" "{{.*-triple=spirv64-amd-amdhsa}}"
+
+// COM: Test that -no-hip-use-experimental-spirv-backend calls the SPIRV translator
+// RUN: %clang -x hip %s --cuda-device-only --offload-arch=amdgcnspirv -no-hip-use-experimental-spirv-backend -nogpuinc -nogpulib -### 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-TRANSLATOR
+// CHECK-SPIRV-TRANSLATOR: "{{.*llvm-spirv.*}}" "{{--spirv-max-version=[0-9]+\.[0-9]}}"
+
+// COM: Test that by default we use the translator
+// RUN: %clang -x hip %s --cuda-device-only --offload-arch=amdgcnspirv -nogpuinc -nogpulib -### 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-TRANSLATOR

>From d69850dbefbde2309fdeeea88b248f1f5087028d Mon Sep 17 00:00:00 2001
From: Manuel Carrasco <Manuel.Carrasco at amd.com>
Date: Fri, 10 Oct 2025 07:33:33 -0700
Subject: [PATCH 3/5] Remove hip prefix.

---
 clang/include/clang/Driver/Options.td     | 14 ++++++--------
 clang/lib/Driver/ToolChains/HIPAMD.cpp    |  4 ++--
 clang/test/Driver/hip-spirv-backend-opt.c | 10 +++++-----
 3 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 7da478e5e71d6..c77a42ba033a9 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1421,18 +1421,16 @@ def fhip_emit_relocatable : Flag<["-"], "fhip-emit-relocatable">,
   HelpText<"Compile HIP source to relocatable">;
 def fno_hip_emit_relocatable : Flag<["-"], "fno-hip-emit-relocatable">,
   HelpText<"Do not override toolchain to compile HIP source to relocatable">;
-def hip_use_experimental_spirv_backend
-    : Flag<["-"], "hip-use-experimental-spirv-backend">,
+def use_experimental_spirv_backend
+    : Flag<["-"], "use-experimental-spirv-backend">,
       Group<hip_Group>,
       Flags<[HelpHidden]>,
-      HelpText<"Use experimental SPIRV backend for HIP compilation (HIP "
-               "only)">;
-def no_hip_use_experimental_spirv_backend
-    : Flag<["-"], "no-hip-use-experimental-spirv-backend">,
+      HelpText<"Use experimental SPIRV backend for compilation ">;
+def no_use_experimental_spirv_backend
+    : Flag<["-"], "no-use-experimental-spirv-backend">,
       Group<hip_Group>,
       Flags<[HelpHidden]>,
-      HelpText<"Do not use experimental SPIRV backend for HIP compilation "
-               "(HIP only)">;
+      HelpText<"Do not use experimental SPIRV backend for compilation ">;
 }
 
 // Clang specific/exclusive options for OpenACC.
diff --git a/clang/lib/Driver/ToolChains/HIPAMD.cpp b/clang/lib/Driver/ToolChains/HIPAMD.cpp
index 1b8a9af197ff7..927f3c0abfea3 100644
--- a/clang/lib/Driver/ToolChains/HIPAMD.cpp
+++ b/clang/lib/Driver/ToolChains/HIPAMD.cpp
@@ -176,8 +176,8 @@ void AMDGCN::Linker::constructLinkAndEmitSpirvCommand(
   constructLlvmLinkCommand(C, JA, Inputs, LinkedBCFile, Args);
 
   bool UseSPIRVBackend = Args.hasFlag(
-      options::OPT_hip_use_experimental_spirv_backend,
-      options::OPT_no_hip_use_experimental_spirv_backend, /*Default=*/false);
+      options::OPT_use_experimental_spirv_backend,
+      options::OPT_no_use_experimental_spirv_backend, /*Default=*/false);
 
   // Emit SPIR-V binary either using the SPIRV backend or the translator.
   if (UseSPIRVBackend) {
diff --git a/clang/test/Driver/hip-spirv-backend-opt.c b/clang/test/Driver/hip-spirv-backend-opt.c
index 7fe9819514066..ade3dee2a5b1c 100644
--- a/clang/test/Driver/hip-spirv-backend-opt.c
+++ b/clang/test/Driver/hip-spirv-backend-opt.c
@@ -1,11 +1,11 @@
-// COM: This test case validates the behavior of -hip-use-experimental-spirv-backend
+// COM: This test case validates the behavior of -use-experimental-spirv-backend
 
-// COM: Test that -hip-use-experimental-spirv-backend calls clang -cc1 with the SPIRV triple.
-// RUN: %clang -x hip %s --cuda-device-only --offload-arch=amdgcnspirv -hip-use-experimental-spirv-backend -nogpuinc -nogpulib -### 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-BACKEND
+// COM: Test that -use-experimental-spirv-backend calls clang -cc1 with the SPIRV triple.
+// RUN: %clang -x hip %s --cuda-device-only --offload-arch=amdgcnspirv -use-experimental-spirv-backend -nogpuinc -nogpulib -### 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-BACKEND
 // CHECK-SPIRV-BACKEND: "{{.*}}clang{{.*}}" "-cc1" "{{.*-triple=spirv64-amd-amdhsa}}"
 
-// COM: Test that -no-hip-use-experimental-spirv-backend calls the SPIRV translator
-// RUN: %clang -x hip %s --cuda-device-only --offload-arch=amdgcnspirv -no-hip-use-experimental-spirv-backend -nogpuinc -nogpulib -### 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-TRANSLATOR
+// COM: Test that -no-use-experimental-spirv-backend calls the SPIRV translator
+// RUN: %clang -x hip %s --cuda-device-only --offload-arch=amdgcnspirv -no-use-experimental-spirv-backend -nogpuinc -nogpulib -### 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-TRANSLATOR
 // CHECK-SPIRV-TRANSLATOR: "{{.*llvm-spirv.*}}" "{{--spirv-max-version=[0-9]+\.[0-9]}}"
 
 // COM: Test that by default we use the translator

>From 13d77d9bbeae162a5ed3681a503c5f4dee16c69c Mon Sep 17 00:00:00 2001
From: Manuel Carrasco <Manuel.Carrasco at amd.com>
Date: Fri, 10 Oct 2025 07:34:25 -0700
Subject: [PATCH 4/5] Remove "COM:".

---
 clang/test/Driver/hip-spirv-backend-opt.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/test/Driver/hip-spirv-backend-opt.c b/clang/test/Driver/hip-spirv-backend-opt.c
index ade3dee2a5b1c..57b8d678951f6 100644
--- a/clang/test/Driver/hip-spirv-backend-opt.c
+++ b/clang/test/Driver/hip-spirv-backend-opt.c
@@ -1,12 +1,12 @@
-// COM: This test case validates the behavior of -use-experimental-spirv-backend
+// This test case validates the behavior of -use-experimental-spirv-backend
 
-// COM: Test that -use-experimental-spirv-backend calls clang -cc1 with the SPIRV triple.
+// Test that -use-experimental-spirv-backend calls clang -cc1 with the SPIRV triple.
 // RUN: %clang -x hip %s --cuda-device-only --offload-arch=amdgcnspirv -use-experimental-spirv-backend -nogpuinc -nogpulib -### 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-BACKEND
 // CHECK-SPIRV-BACKEND: "{{.*}}clang{{.*}}" "-cc1" "{{.*-triple=spirv64-amd-amdhsa}}"
 
-// COM: Test that -no-use-experimental-spirv-backend calls the SPIRV translator
+// Test that -no-use-experimental-spirv-backend calls the SPIRV translator
 // RUN: %clang -x hip %s --cuda-device-only --offload-arch=amdgcnspirv -no-use-experimental-spirv-backend -nogpuinc -nogpulib -### 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-TRANSLATOR
 // CHECK-SPIRV-TRANSLATOR: "{{.*llvm-spirv.*}}" "{{--spirv-max-version=[0-9]+\.[0-9]}}"
 
-// COM: Test that by default we use the translator
+// Test that by default we use the translator
 // RUN: %clang -x hip %s --cuda-device-only --offload-arch=amdgcnspirv -nogpuinc -nogpulib -### 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-TRANSLATOR

>From 08b951260fa309c72a86afd04dcbe92a9a8b1a49 Mon Sep 17 00:00:00 2001
From: Manuel Carrasco <Manuel.Carrasco at amd.com>
Date: Thu, 16 Oct 2025 02:21:09 -0700
Subject: [PATCH 5/5] Invoke the SPIRV backend directly and add
 -ccc-print-phases and -ccc-print-bindings test cases.

---
 clang/include/clang/Driver/Types.def          |  1 +
 clang/lib/Driver/Driver.cpp                   | 40 +++++++++++++------
 clang/lib/Driver/ToolChains/Clang.cpp         |  2 +
 clang/lib/Driver/ToolChains/HIPAMD.cpp        | 36 +++++------------
 .../test/Driver/hip-spirv-backend-bindings.c  |  4 ++
 clang/test/Driver/hip-spirv-backend-opt.c     |  2 +-
 clang/test/Driver/hip-spirv-backend-phases.c  |  9 +++++
 7 files changed, 54 insertions(+), 40 deletions(-)
 create mode 100644 clang/test/Driver/hip-spirv-backend-bindings.c
 create mode 100644 clang/test/Driver/hip-spirv-backend-phases.c

diff --git a/clang/include/clang/Driver/Types.def b/clang/include/clang/Driver/Types.def
index 76944ec656917..7060ab20fa34c 100644
--- a/clang/include/clang/Driver/Types.def
+++ b/clang/include/clang/Driver/Types.def
@@ -78,6 +78,7 @@ TYPE("c++-module-cpp-output",    PP_CXXModule, INVALID,         "iim",    phases
 TYPE("ada",                      Ada,          INVALID,         nullptr,  phases::Compile, phases::Backend, phases::Assemble, phases::Link)
 TYPE("assembler",                PP_Asm,       INVALID,         "s",      phases::Assemble, phases::Link)
 TYPE("assembler-with-cpp",       Asm,          PP_Asm,          "S",      phases::Preprocess, phases::Assemble, phases::Link)
+TYPE("spv",                      SPV,          INVALID,         "spv",  phases::Backend)
 
 // Note: The `phases::Preprocess` phase is added to ".i" (i.e. Fortran
 // pre-processed) files. The reason is that the pre-processor "phase" has to be
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 85a1335785542..55650d8b3033f 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -3672,29 +3672,45 @@ class OffloadingActionBuilder final {
             // compiler phases, including backend and assemble phases.
             ActionList AL;
             Action *BackendAction = nullptr;
+            bool AssembleAndLink = true;
             if (ToolChains.front()->getTriple().isSPIRV() ||
                 (ToolChains.front()->getTriple().isAMDGCN() &&
                  GpuArchList[I] == StringRef("amdgcnspirv"))) {
-              // Emit LLVM bitcode for SPIR-V targets. SPIR-V device tool chain
-              // (HIPSPVToolChain or HIPAMDToolChain) runs post-link LLVM IR
-              // passes.
-              types::ID Output = Args.hasArg(options::OPT_S)
+
+              bool UseSPIRVBackend =
+                  Args.hasFlag(options::OPT_use_experimental_spirv_backend,
+                               options::OPT_no_use_experimental_spirv_backend,
+                               /*Default=*/false);
+
+              types::ID Output = UseSPIRVBackend ? types::TY_SPV
+                                 : Args.hasArg(options::OPT_S)
                                      ? types::TY_LLVM_IR
                                      : types::TY_LLVM_BC;
+
               BackendAction =
                   C.MakeAction<BackendJobAction>(CudaDeviceActions[I], Output);
+
+              if (UseSPIRVBackend) {
+                AssembleAndLink = false;
+              }
+
             } else
               BackendAction = C.getDriver().ConstructPhaseAction(
                   C, Args, phases::Backend, CudaDeviceActions[I],
                   AssociatedOffloadKind);
-            auto AssembleAction = C.getDriver().ConstructPhaseAction(
-                C, Args, phases::Assemble, BackendAction,
-                AssociatedOffloadKind);
-            AL.push_back(AssembleAction);
-            // Create a link action to link device IR with device library
-            // and generate ISA.
-            CudaDeviceActions[I] =
-                C.MakeAction<LinkJobAction>(AL, types::TY_Image);
+
+            if (AssembleAndLink) {
+              auto AssembleAction = C.getDriver().ConstructPhaseAction(
+                  C, Args, phases::Assemble, BackendAction,
+                  AssociatedOffloadKind);
+              AL.push_back(AssembleAction);
+              // Create a link action to link device IR with device library
+              // and generate ISA.
+              CudaDeviceActions[I] =
+                  C.MakeAction<LinkJobAction>(AL, types::TY_Image);
+            } else {
+              CudaDeviceActions[I] = BackendAction;
+            }
           }
 
           // OffloadingActionBuilder propagates device arch until an offload
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index d326a81feb762..08fff9b2a0d13 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5197,6 +5197,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
       rewriteKind = RK_Fragile;
     } else if (JA.getType() == types::TY_CIR) {
       CmdArgs.push_back("-emit-cir");
+    } else if (JA.getType() == types::TY_SPV) {
+      CmdArgs.push_back("-emit-obj");
     } else {
       assert(JA.getType() == types::TY_PP_Asm && "Unexpected output type!");
     }
diff --git a/clang/lib/Driver/ToolChains/HIPAMD.cpp b/clang/lib/Driver/ToolChains/HIPAMD.cpp
index 927f3c0abfea3..58b54730a5210 100644
--- a/clang/lib/Driver/ToolChains/HIPAMD.cpp
+++ b/clang/lib/Driver/ToolChains/HIPAMD.cpp
@@ -175,33 +175,15 @@ void AMDGCN::Linker::constructLinkAndEmitSpirvCommand(
 
   constructLlvmLinkCommand(C, JA, Inputs, LinkedBCFile, Args);
 
-  bool UseSPIRVBackend = Args.hasFlag(
-      options::OPT_use_experimental_spirv_backend,
-      options::OPT_no_use_experimental_spirv_backend, /*Default=*/false);
-
-  // Emit SPIR-V binary either using the SPIRV backend or the translator.
-  if (UseSPIRVBackend) {
-    llvm::opt::ArgStringList CmdArgs;
-    const char *Triple =
-        C.getArgs().MakeArgString("-triple=spirv64-amd-amdhsa");
-    CmdArgs.append({"-cc1", Triple, "-emit-obj", LinkedBCFile.getFilename(),
-                    "-o", Output.getFilename()});
-    const char *Exec = getToolChain().getDriver().getClangProgramPath();
-    C.addCommand(std::make_unique<Command>(JA, *this,
-                                           ResponseFileSupport::None(), Exec,
-                                           CmdArgs, LinkedBCFile, Output));
-  } else {
-    // Use the SPIRV translator for code gen.
-    llvm::opt::ArgStringList TrArgs{
-        "--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"};
-    SPIRV::constructTranslateCommand(C, *this, JA, Output, LinkedBCFile,
-                                     TrArgs);
-  }
+  // Use the SPIRV translator for code gen.
+  llvm::opt::ArgStringList TrArgs{
+      "--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"};
+  SPIRV::constructTranslateCommand(C, *this, JA, Output, LinkedBCFile, TrArgs);
 }
 
 // For amdgcn the inputs of the linker job are device bitcode and output is
diff --git a/clang/test/Driver/hip-spirv-backend-bindings.c b/clang/test/Driver/hip-spirv-backend-bindings.c
new file mode 100644
index 0000000000000..028e53a2a9f9a
--- /dev/null
+++ b/clang/test/Driver/hip-spirv-backend-bindings.c
@@ -0,0 +1,4 @@
+// RUN: %clang -x hip %s --cuda-device-only --offload-arch=amdgcnspirv -use-experimental-spirv-backend -nogpuinc -nogpulib -ccc-print-bindings 2>&1 | FileCheck %s 
+
+// CHECK: # "spirv64-amd-amdhsa" - "clang", inputs: ["{{.*}}.c"], output: "[[SPV_FILE:.*.spv]]"
+// CHECK: # "spirv64-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[SPV_FILE]]"], output: "{{.*.hipfb}}"
diff --git a/clang/test/Driver/hip-spirv-backend-opt.c b/clang/test/Driver/hip-spirv-backend-opt.c
index 57b8d678951f6..d27755161ea84 100644
--- a/clang/test/Driver/hip-spirv-backend-opt.c
+++ b/clang/test/Driver/hip-spirv-backend-opt.c
@@ -2,7 +2,7 @@
 
 // Test that -use-experimental-spirv-backend calls clang -cc1 with the SPIRV triple.
 // RUN: %clang -x hip %s --cuda-device-only --offload-arch=amdgcnspirv -use-experimental-spirv-backend -nogpuinc -nogpulib -### 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-BACKEND
-// CHECK-SPIRV-BACKEND: "{{.*}}clang{{.*}}" "-cc1" "{{.*-triple=spirv64-amd-amdhsa}}"
+// CHECK-SPIRV-BACKEND: "{{.*}}clang{{.*}}" "-cc1" "{{.*-triple}}" "{{spirv64-amd-amdhsa}}"
 
 // Test that -no-use-experimental-spirv-backend calls the SPIRV translator
 // RUN: %clang -x hip %s --cuda-device-only --offload-arch=amdgcnspirv -no-use-experimental-spirv-backend -nogpuinc -nogpulib -### 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-TRANSLATOR
diff --git a/clang/test/Driver/hip-spirv-backend-phases.c b/clang/test/Driver/hip-spirv-backend-phases.c
new file mode 100644
index 0000000000000..ed75b6dcab74d
--- /dev/null
+++ b/clang/test/Driver/hip-spirv-backend-phases.c
@@ -0,0 +1,9 @@
+// RUN: %clang -x hip %s --cuda-device-only --offload-arch=amdgcnspirv -use-experimental-spirv-backend -nogpuinc -nogpulib -ccc-print-phases 2>&1 | FileCheck %s 
+
+// CHECK: [[P0:[0-9]+]]: input, "{{.*}}.c", hip, (device-hip, amdgcnspirv)
+// CHECK: [[P1:[0-9]+]]: preprocessor, {[[P0]]}, hip-cpp-output, (device-hip, amdgcnspirv)
+// CHECK: [[P2:[0-9]+]]: compiler, {[[P1]]}, ir, (device-hip, amdgcnspirv)
+// CHECK: [[P3:[0-9]+]]: backend, {[[P2]]}, spv, (device-hip, amdgcnspirv)
+// CHECK: [[P4:[0-9]+]]: offload, "device-hip (spirv64-amd-amdhsa:amdgcnspirv)" {[[P3]]}, spv
+// CHECK: [[P5:[0-9]+]]: linker, {[[P4]]}, hip-fatbin, (device-hip, )
+// CHECK: [[P6:[0-9]+]]: offload, "device-hip (spirv64-amd-amdhsa:)" {[[P5]]}, hip-fatbin



More information about the cfe-commits mailing list