linjamaki created this revision.
Herald added subscribers: Naghasan, dexonsmith, dang, Anastasia, yaxunl, 
jholewinski.
linjamaki updated this revision to Diff 375783.
linjamaki added a comment.
linjamaki updated this revision to Diff 375786.
linjamaki added reviewers: yaxunl, bader.
linjamaki published this revision for review.
Herald added a reviewer: jdoerfert.
Herald added subscribers: cfe-commits, sstefan1.
Herald added a project: clang.

Style fixes.


linjamaki added a comment.

Remove noisy change.


This patch enables SPIR-V binary emission for HIP device code via the
HIPSPV tool chain.

- ‘--offload’ option, which is envisioned in [1], is added for specifying 
offload targets. This option is used to override default device target 
(amdgcn-amd-amdhsa) for HIP compilation for emitting device code as SPIR-V 
binary. The option is handled in getHIPOffloadTargetTriple().

- getOffloadingDeviceToolChain() function (based on the design in the SYCL 
repository) is added to select HIPSPVToolChain when HIP offload target is 
‘spirv64’.

- The HIPActionBuilder is modified to produce LLVM IR at the backend phase. 
HIPSPV tool chain expects to receive HIP device code as LLVM IR so it can run 
external LLVM passes over them. HIPSPV TC is also responsible for emitting the 
SPIR-V binary.

- A Cuda GPU architecture ‘generic’ is added. The name is picked from the LLVM 
SPIR-V Backend. In the HIPSPV code path the architecture name is inserted to 
the bundle entry ID as target ID. Target ID is expected to be always present so 
a component in the target triple is not mistaken as target ID.

- Tests are added for checking the HIPSPV tool chain.

[1]: https://lists.llvm.org/pipermail/cfe-dev/2020-December/067362.html


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D110622

Files:
  clang/include/clang/Basic/Cuda.h
  clang/include/clang/Basic/DiagnosticDriverKinds.td
  clang/include/clang/Driver/Driver.h
  clang/include/clang/Driver/Options.td
  clang/lib/Basic/Cuda.cpp
  clang/lib/Basic/Targets/NVPTX.cpp
  clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
  clang/lib/Driver/Driver.cpp
  clang/test/Driver/Inputs/hipspv-dev-lib/a/a.bc
  clang/test/Driver/Inputs/hipspv-dev-lib/b/b.bc
  clang/test/Driver/Inputs/hipspv-dev-lib/hipspv-spirv64.bc
  clang/test/Driver/Inputs/hipspv/bin/.hipVersion
  clang/test/Driver/Inputs/hipspv/lib/hip-device-lib/hipspv-spirv64.bc
  clang/test/Driver/Inputs/hipspv/lib/libLLVMHipSpvPasses.so
  clang/test/Driver/Inputs/pass-plugin.so
  clang/test/Driver/hipspv-device-libs.hip
  clang/test/Driver/hipspv-pass-plugin.hip
  clang/test/Driver/hipspv-toolchain-rdc.hip
  clang/test/Driver/hipspv-toolchain.hip
  clang/test/Driver/invalid-offload-options.cpp

Index: clang/test/Driver/invalid-offload-options.cpp
===================================================================
--- /dev/null
+++ clang/test/Driver/invalid-offload-options.cpp
@@ -0,0 +1,18 @@
+// REQUIRES: clang-driver
+// REQUIRES: x86-registered-target
+// UNSUPPORTED: system-windows
+
+// RUN: %clang -### -x hip -target x86_64-linux-gnu --offload= \
+// RUN:   --hip-path=%S/Inputs/hipspv -nogpuinc -nogpulib %s \
+// RUN: 2>&1 | FileCheck --check-prefix=INVALID-TARGET %s
+// RUN: %clang -### -x hip -target x86_64-linux-gnu --offload=foo       \
+// RUN:   --hip-path=%S/Inputs/hipspv -nogpuinc -nogpulib %s \
+// RUN: 2>&1 | FileCheck --check-prefix=INVALID-TARGET %s
+
+// INVALID-TARGET: error: Invalid or unsupported offload target: '{{.*}}'
+
+// RUN: %clang -### -x hip -target x86_64-linux-gnu --offload=foo,bar \
+// RUN:   --hip-path=%S/Inputs/hipspv -nogpuinc -nogpulib %s \
+// RUN: 2>&1 | FileCheck --check-prefix=TOO-MANY-TARGETS %s
+
+// TOO-MANY-TARGETS: error: Only one offload target is supported in HIP.
Index: clang/test/Driver/hipspv-toolchain.hip
===================================================================
--- /dev/null
+++ clang/test/Driver/hipspv-toolchain.hip
@@ -0,0 +1,37 @@
+// REQUIRES: clang-driver
+// REQUIRES: x86-registered-target
+// UNSUPPORTED: system-windows
+
+// RUN: %clang -### -target x86_64-linux-gnu --offload=spirv64 \
+// RUN:   --hip-path=%S/Inputs/hipspv -nohipwrapperinc %s \
+// RUN: 2>&1 | FileCheck %s
+
+// CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "spirv64"
+// CHECK-SAME: "-aux-triple" "{{.*}}" "-emit-llvm-bc"
+// CHECK-SAME: "-fcuda-is-device"
+// CHECK-SAME: "-fcuda-allow-variadic-functions"
+// CHECK-SAME: "-mlink-builtin-bitcode" {{".*/hipspv/lib/hip-device-lib/hipspv-spirv64.bc"}}
+// CHECK-SAME: "-isystem" {{".*/hipspv/include"}}
+// CHECK-SAME: "-fhip-new-launch-api"
+// CHECK-SAME: "-o" [[DEV_BC:".*bc"]]
+// CHECK-SAME: "-x" "hip"
+
+// CHECK: {{".*llvm-link"}} [[DEV_BC]] "-o" [[LINK_BC:".*bc"]]
+
+// CHECK: {{".*opt"}} [[LINK_BC]] "-load-pass-plugin"
+// CHECK-SAME: {{".*/hipspv/lib/libLLVMHipSpvPasses.so"}}
+// CHECK-SAME: "-passes=hip-post-link-passes" "-o" [[LOWER_BC:".*bc"]]
+
+// CHECK: {{".*llvm-spirv"}} "-spirv-max-version=1.1" "--spirv-ext=+all"
+// CHECK-SAME: [[LOWER_BC]] "-o" "[[SPIRV_OUT:.*out]]"
+
+// CHECK: {{".*clang-offload-bundler"}} "-type=o" "-bundle-align=4096"
+// CHECK-SAME: "-targets=host-x86_64-unknown-linux,hip-spirv64----generic"
+// CHECK-SAME: "-inputs={{.*}},[[SPIRV_OUT]]" "-outputs=[[BUNDLE:.*hipfb]]"
+
+// CHECK: [[CLANG]] "-cc1" "-triple" {{".*"}} "-aux-triple" "spirv64"
+// CHECK-SAME: "-emit-obj"
+// CHECK-SAME: "-fcuda-include-gpubinary" "[[BUNDLE]]"
+// CHECK-SAME: "-o" [[OBJ_HOST:".*o"]] "-x" "hip"
+
+// CHECK: {{".*ld.*"}} {{.*}}[[OBJ_HOST]]
Index: clang/test/Driver/hipspv-toolchain-rdc.hip
===================================================================
--- /dev/null
+++ clang/test/Driver/hipspv-toolchain-rdc.hip
@@ -0,0 +1,63 @@
+// REQUIRES: clang-driver
+// REQUIRES: x86-registered-target
+// UNSUPPORTED: system-windows
+
+// RUN: %clang -### -x hip -target x86_64-linux-gnu --offload=spirv64 \
+// RUN:   -fgpu-rdc --hip-path=%S/Inputs/hipspv -nohipwrapperinc \
+// RUN:   %S/Inputs/hip_multiple_inputs/a.cu \
+// RUN:   %S/Inputs/hip_multiple_inputs/b.hip \
+// RUN: 2>&1 | FileCheck %s
+
+// Emit objects for host side path
+// CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "x86_64-unknown-linux-gnu"
+// CHECK-SAME: "-aux-triple" "spirv64"
+// CHECK-SAME: "-emit-obj"
+// CHECK-SAME: "-fgpu-rdc"
+// CHECK-SAME: {{.*}} "-o" [[A_OBJ_HOST:".*o"]] "-x" "hip"
+// CHECK-SAME: {{.*}} [[A_SRC:".*a.cu"]]
+
+// CHECK: [[CLANG]] "-cc1" "-triple" "x86_64-unknown-linux-gnu"
+// CHECK-SAME: "-aux-triple" "spirv64"
+// CHECK-SAME: "-emit-obj"
+// CHECK-SAME: "-fgpu-rdc"
+// CHECK-SAME: {{.*}} "-o" [[B_OBJ_HOST:".*o"]] "-x" "hip"
+// CHECK-SAME: {{.*}} [[B_SRC:".*b.hip"]]
+
+// Emit code (LLVM BC) for device side path.
+// CHECK: [[CLANG]] "-cc1" "-triple" "spirv64"
+// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu"
+// CHECK-SAME: "-emit-llvm-bc"
+// CHECK-SAME: "-fcuda-is-device" "-fcuda-allow-variadic-functions" "-fvisibility" "hidden"
+// CHECK-SAME: "-fapply-global-visibility-to-externs"
+// CHECK-SAME: "-fgpu-rdc"
+// CHECK-SAME: {{.*}} "-o" [[A_BC1:".*bc"]] "-x" "hip"
+// CHECK-SAME: {{.*}} [[A_SRC]]
+
+// CHECK: [[CLANG]] "-cc1" "-triple" "spirv64"
+// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu"
+// CHECK-SAME: "-emit-llvm-bc"
+// CHECK-SAME: "-fcuda-is-device" "-fcuda-allow-variadic-functions" "-fvisibility" "hidden"
+// CHECK-SAME: "-fapply-global-visibility-to-externs"
+// CHECK-SAME: "-fgpu-rdc"
+// CHECK-SAME: {{.*}} "-o" [[B_BC1:".*bc"]] "-x" "hip"
+// CHECK-SAME: {{.*}} [[B_SRC]]
+
+// Link device code, lower it with HIPSPV passes and emit SPIR-V binary.
+// CHECK: {{".*llvm-link.*"}} [[A_BC1]] [[B_BC1]] "-o" [[AB_LINK:".*bc"]]
+// CHECK: {{".*opt.*"}} [[AB_LINK]] "-load-pass-plugin"
+// CHECK-SAME: "{{.*}}/Inputs/hipspv/lib/libLLVMHipSpvPasses.so"
+// CHECK-SAME: "-o" [[AB_LOWER:".*bc"]]
+// CHECK: {{".*llvm-spirv"}} "-spirv-max-version=1.1" "--spirv-ext=+all"
+// CHECK-SAME: [[AB_LOWER]] "-o" "[[AB_SPIRV:.*out]]"
+
+// Construct fat binary object.
+// CHECK: [[BUNDLER:".*clang-offload-bundler"]] "-type=o" "-bundle-align=4096"
+// CHECK-SAME: "-targets={{.*}},hip-spirv64----generic"
+// CHECK-SAME: "-inputs=/dev/null,[[AB_SPIRV]]"
+// CHECK-SAME: "-outputs=[[AB_FATBIN:.*hipfb]]"
+// CHECK: {{".*llvm-mc.*"}} "-o" [[OBJBUNDLE:".*o"]] "{{.*}}.mcin"
+// CHECK-SAME: "--filetype=obj"
+
+// Output the executable
+// CHECK: {{".*ld.*"}} {{.*}}"-o" "a.out" {{.*}} [[A_OBJ_HOST]] [[B_OBJ_HOST]]
+// CHECK-SAME: [[OBJBUNDLE]]
Index: clang/test/Driver/hipspv-pass-plugin.hip
===================================================================
--- /dev/null
+++ clang/test/Driver/hipspv-pass-plugin.hip
@@ -0,0 +1,27 @@
+// REQUIRES: clang-driver
+// REQUIRES: x86-registered-target
+// UNSUPPORTED: system-windows
+
+// RUN: %clang -### -target x86_64-linux-gnu --offload=spirv64 \
+// RUN:  --hip-path=%S/Inputs/hipspv -nogpuinc %s \
+// RUN: 2>&1 | FileCheck --check-prefixes=FROM-HIP-PATH %s
+
+// RUN: %clang -### -target x86_64-linux-gnu --offload=spirv64 \
+// RUN: -nogpuinc -nogpulib --hipspv-pass-plugin=%S/Inputs/pass-plugin.so %s \
+// RUN: 2>&1 | FileCheck --check-prefixes=FROM-OPTION %s
+
+// RUN: %clang -### -target x86_64-linux-gnu --offload=spirv64 \
+// RUN: -nogpuinc -nogpulib --hipspv-pass-plugin=foo.so %s \
+// RUN: 2>&1 | FileCheck --check-prefixes=FROM-OPTION-INVALID %s
+
+// RUN: %clang -### -target x86_64-linux-gnu --offload=spirv64 \
+// RUN: -nogpuinc -nogpulib %s \
+// RUN: 2>&1 | FileCheck --check-prefixes=NO-PLUGIN %s
+
+// FROM-HIP-PATH: {{".*opt"}} {{".*.bc"}} "-load-pass-plugin"
+// FROM-HIP-PATH-SAME: {{".*/Inputs/hipspv/lib/libLLVMHipSpvPasses.so"}}
+// FROM-OPTION: {{".*opt"}} {{".*.bc"}} "-load-pass-plugin"
+// FROM-OPTION-SAME: {{".*/Inputs/pass-plugin.so"}}
+// FROM-OPTION-INVALID: error: no such file or directory: 'foo.so'
+// NO-PLUGIN-NOT: {{".*opt"}} {{".*.bc"}} "-load-pass-plugin"
+// NO-PLUGIN-NOT: {{".*/Inputs/hipspv/lib/libLLVMHipSpvPasses.so"}}
Index: clang/test/Driver/hipspv-device-libs.hip
===================================================================
--- /dev/null
+++ clang/test/Driver/hipspv-device-libs.hip
@@ -0,0 +1,28 @@
+// REQUIRES: clang-driver
+// REQUIRES: x86-registered-target
+// UNSUPPORTED: system-windows
+
+// RUN: %clang -### -target x86_64-linux-gnu --offload=spirv64 \
+// RUN:  --hip-path=%S/Inputs/hipspv %s \
+// RUN: 2>&1 | FileCheck --check-prefixes=ALL,HIP-PATH %s
+
+// Test --hip-device-lib-path
+// RUN: %clang -### -target x86_64-linux-gnu --offload=spirv64 \
+// RUN:  --hip-path=%S/Inputs/hipspv \
+// RUN:   --hip-device-lib-path=%S/Inputs/hipspv-dev-lib %s \
+// RUN: 2>&1 | FileCheck --check-prefixes=ALL,HIP-DEV-LIB-PATH %s
+
+// Test --hip-device-lib w/ --hip-device-lib-path and HIP_DEVICE_LIB_PATH.
+// RUN: env HIP_DEVICE_LIB_PATH=%S/Inputs/hipspv-dev-lib/a \
+// RUN:   %clang -### -target x86_64-linux-gnu --offload=spirv64 \
+// RUN:    --hip-path=%S/Inputs/hipspv \
+// RUN:    --hip-device-lib-path=%S/Inputs/hipspv-dev-lib/b \
+// RUN:    --hip-device-lib=a.bc --hip-device-lib=b.bc %s \
+// RUN: 2>&1 | FileCheck --check-prefixes=ALL,HIP-DEV-LIB %s
+
+// ALL: {{"[^"]*clang[^"]*"}}
+// HIP-PATH: "-mlink-builtin-bitcode" {{".*/hipspv/lib/hip-device-lib/hipspv-spirv64.bc"}}
+// HIP-DEV-LIB-PATH-NOT: "-mlink-builtin-bitcode" {{".*/hipspv/lib/hip-device-lib/hipspv-spirv64.bc"}}
+// HIP-DEV-LIB-PATH: "-mlink-builtin-bitcode" {{".*/hipspv-dev-lib/hipspv-spirv64.bc"}}
+// HIP-DEV-LIB: "-mlink-builtin-bitcode" {{".*/hipspv-dev-lib/a/a.bc"}}
+// HIP-DEV-LIB-SAME: "-mlink-builtin-bitcode" {{".*/hipspv-dev-lib/b/b.bc"}}
Index: clang/test/Driver/Inputs/hipspv/bin/.hipVersion
===================================================================
--- /dev/null
+++ clang/test/Driver/Inputs/hipspv/bin/.hipVersion
@@ -0,0 +1,2 @@
+HIP_VERSION_MAJOR=3
+HIP_VERSION_MINOR=6
Index: clang/lib/Driver/Driver.cpp
===================================================================
--- clang/lib/Driver/Driver.cpp
+++ clang/lib/Driver/Driver.cpp
@@ -24,6 +24,7 @@
 #include "ToolChains/Fuchsia.h"
 #include "ToolChains/Gnu.h"
 #include "ToolChains/HIPAMD.h"
+#include "ToolChains/HIPSPV.h"
 #include "ToolChains/Haiku.h"
 #include "ToolChains/Hexagon.h"
 #include "ToolChains/Hurd.h"
@@ -98,8 +99,34 @@
 using namespace clang;
 using namespace llvm::opt;
 
-static llvm::Triple getHIPOffloadTargetTriple() {
-  static const llvm::Triple T("amdgcn-amd-amdhsa");
+static llvm::Optional<llvm::Triple>
+getHIPOffloadTargetTriple(const Driver &D, const ArgList &Args) {
+  if (Arg *HIPOffloadTargets = Args.getLastArg(options::OPT_offload_EQ)) {
+    switch (HIPOffloadTargets->getNumValues()) {
+    default:
+      D.Diag(diag::err_drv_only_one_offload_target_supported_in) << "HIP";
+      return llvm::None;
+    case 0:
+      D.Diag(diag::err_drv_invalid_or_unsupported_offload_target) << "";
+      return llvm::None;
+    case 1:
+      break;
+    }
+    llvm::Triple TT(HIPOffloadTargets->getValue());
+    if (TT.getArch() == llvm::Triple::amdgcn &&
+        TT.getVendor() == llvm::Triple::AMD &&
+        TT.getOS() == llvm::Triple::AMDHSA)
+      return TT;
+    if (TT.getArch() == llvm::Triple::spirv64 &&
+        TT.getVendor() == llvm::Triple::UnknownVendor &&
+        TT.getOS() == llvm::Triple::UnknownOS)
+      return TT;
+    D.Diag(diag::err_drv_invalid_or_unsupported_offload_target)
+        << HIPOffloadTargets->getValue();
+    return llvm::None;
+  }
+
+  static const llvm::Triple T("amdgcn-amd-amdhsa"); // Default HIP triple.
   return T;
 }
 
@@ -681,17 +708,14 @@
     C.addOffloadDeviceToolChain(CudaTC.get(), OFK);
   } else if (IsHIP) {
     const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>();
-    const llvm::Triple &HostTriple = HostTC->getTriple();
     auto OFK = Action::OFK_HIP;
-    llvm::Triple HIPTriple = getHIPOffloadTargetTriple();
-    // Use the HIP and host triples as the key into the ToolChains map,
-    // because the device toolchain we create depends on both.
-    auto &HIPTC = ToolChains[HIPTriple.str() + "/" + HostTriple.str()];
-    if (!HIPTC) {
-      HIPTC = std::make_unique<toolchains::HIPAMDToolChain>(
-          *this, HIPTriple, *HostTC, C.getInputArgs());
-    }
-    C.addOffloadDeviceToolChain(HIPTC.get(), OFK);
+    auto HIPTriple = getHIPOffloadTargetTriple(*this, C.getInputArgs());
+    if (!HIPTriple)
+      return;
+    auto *HIPTC = &getOffloadingDeviceToolChain(C.getInputArgs(), *HIPTriple,
+                                                *HostTC, OFK);
+    assert(HIPTC && "Could not create offloading device tool chain.");
+    C.addOffloadDeviceToolChain(HIPTC, OFK);
   }
 
   //
@@ -2733,8 +2757,12 @@
       // Default to sm_20 which is the lowest common denominator for
       // supported GPUs.  sm_20 code should work correctly, if
       // suboptimally, on all newer GPUs.
-      if (GpuArchList.empty())
-        GpuArchList.push_back(DefaultCudaArch);
+      if (GpuArchList.empty()) {
+        if (ToolChains.front()->getTriple().isSPIRV())
+          GpuArchList.push_back(CudaArch::Generic);
+        else
+          GpuArchList.push_back(DefaultCudaArch);
+      }
 
       return Error;
     }
@@ -2898,8 +2926,11 @@
 
     StringRef getCanonicalOffloadArch(StringRef IdStr) override {
       llvm::StringMap<bool> Features;
-      auto ArchStr =
-          parseTargetID(getHIPOffloadTargetTriple(), IdStr, &Features);
+      // getHIPOffloadTargetTriple() is known to return valid value as it has
+      // been called successfully in the CreateOffloadingDeviceToolChains().
+      auto ArchStr = parseTargetID(
+          *getHIPOffloadTargetTriple(C.getDriver(), C.getInputArgs()), IdStr,
+          &Features);
       if (!ArchStr) {
         C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << IdStr;
         C.setContainsError();
@@ -2953,9 +2984,19 @@
             // When LTO is not enabled, we follow the conventional
             // compiler phases, including backend and assemble phases.
             ActionList AL;
-            auto BackendAction = C.getDriver().ConstructPhaseAction(
-                C, Args, phases::Backend, CudaDeviceActions[I],
-                AssociatedOffloadKind);
+            Action *BackendAction = nullptr;
+            if (ToolChains.front()->getTriple().isSPIRV()) {
+              // Emit LLVM bitcode for SPIR-V targets. SPIR-V device tool chain
+              // (HIPSPVToolChain) runs post-link LLVM IR passes.
+              types::ID Output = Args.hasArg(options::OPT_S)
+                                     ? types::TY_LLVM_IR
+                                     : types::TY_LLVM_BC;
+              BackendAction =
+                  C.MakeAction<BackendJobAction>(CudaDeviceActions[I], Output);
+            } else
+              BackendAction = C.getDriver().ConstructPhaseAction(
+                  C, Args, phases::Backend, CudaDeviceActions[I],
+                  AssociatedOffloadKind);
             auto AssembleAction = C.getDriver().ConstructPhaseAction(
                 C, Args, phases::Assemble, BackendAction,
                 AssociatedOffloadKind);
@@ -5398,6 +5439,38 @@
   return *TC;
 }
 
+const ToolChain &Driver::getOffloadingDeviceToolChain(
+    const ArgList &Args, const llvm::Triple &Target, const ToolChain &HostTC,
+    const Action::OffloadKind &TargetDeviceOffloadKind) const {
+  // Use device / host triples as the key into the ToolChains map because the
+  // device ToolChain we create depends on both.
+  auto &TC = ToolChains[Target.str() + "/" + HostTC.getTriple().str()];
+  if (!TC) {
+    // Categorized by offload kind > arch rather than OS > arch like
+    // the normal getToolChain call, as it seems a reasonable way to categorize
+    // things.
+    switch (TargetDeviceOffloadKind) {
+    case Action::OFK_HIP: {
+      if (Target.getArch() == llvm::Triple::amdgcn &&
+          Target.getVendor() == llvm::Triple::AMD &&
+          Target.getOS() == llvm::Triple::AMDHSA)
+        TC = std::make_unique<toolchains::HIPAMDToolChain>(*this, Target,
+                                                           HostTC, Args);
+      else if (Target.getArch() == llvm::Triple::spirv64 &&
+               Target.getVendor() == llvm::Triple::UnknownVendor &&
+               Target.getOS() == llvm::Triple::UnknownOS)
+        TC = std::make_unique<toolchains::HIPSPVToolChain>(*this, Target,
+                                                           HostTC, Args);
+      break;
+    }
+    default:
+      break;
+    }
+  }
+
+  return *TC;
+}
+
 bool Driver::ShouldUseClangCompiler(const JobAction &JA) const {
   // Say "no" if there is not exactly one input of a type clang understands.
   if (JA.size() != 1 ||
Index: clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
===================================================================
--- clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
+++ clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
@@ -3894,6 +3894,7 @@
       case CudaArch::GFX1033:
       case CudaArch::GFX1034:
       case CudaArch::GFX1035:
+      case CudaArch::Generic:
       case CudaArch::UNUSED:
       case CudaArch::UNKNOWN:
         break;
Index: clang/lib/Basic/Targets/NVPTX.cpp
===================================================================
--- clang/lib/Basic/Targets/NVPTX.cpp
+++ clang/lib/Basic/Targets/NVPTX.cpp
@@ -214,6 +214,7 @@
       case CudaArch::GFX1033:
       case CudaArch::GFX1034:
       case CudaArch::GFX1035:
+      case CudaArch::Generic:
       case CudaArch::LAST:
         break;
       case CudaArch::UNUSED:
Index: clang/lib/Basic/Cuda.cpp
===================================================================
--- clang/lib/Basic/Cuda.cpp
+++ clang/lib/Basic/Cuda.cpp
@@ -120,6 +120,7 @@
     GFX(1033), // gfx1033
     GFX(1034), // gfx1034
     GFX(1035), // gfx1035
+    {CudaArch::Generic, "generic", "compute_spirv"},
     // clang-format on
 };
 #undef SM
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1132,6 +1132,9 @@
   NegFlag<SetFalse, [CC1Option], "Disable generation of linker directives for automatic library linking">,
   PosFlag<SetTrue>>;
 
+def offload_EQ : CommaJoined<["--"], "offload=">, Flags<[NoXarchOption]>,
+  HelpText<"Specify comma-separated list of offloading targets.">;
+
 // C++ Coroutines TS
 defm coroutines_ts : BoolFOption<"coroutines-ts",
   LangOpts<"Coroutines">, Default<cpp20.KeyPath>,
Index: clang/include/clang/Driver/Driver.h
===================================================================
--- clang/include/clang/Driver/Driver.h
+++ clang/include/clang/Driver/Driver.h
@@ -595,6 +595,21 @@
 
   /// @}
 
+  /// Retrieves a ToolChain for a particular device \p Target triple
+  ///
+  /// \param[in] HostTC is the host ToolChain paired with the device
+  ///
+  /// \param[in] Action (e.g. OFK_Cuda/OFK_OpenMP/OFK_SYCL) is an Offloading
+  /// action that is optionally passed to a ToolChain (used by CUDA, to specify
+  /// if it's used in conjunction with OpenMP)
+  ///
+  /// Will cache ToolChains for the life of the driver object, and create them
+  /// on-demand.
+  const ToolChain &getOffloadingDeviceToolChain(
+      const llvm::opt::ArgList &Args, const llvm::Triple &Target,
+      const ToolChain &HostTC,
+      const Action::OffloadKind &TargetDeviceOffloadKind) const;
+
   /// Get bitmasks for which option flags to include and exclude based on
   /// the driver mode.
   std::pair<unsigned, unsigned> getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const;
Index: clang/include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -598,4 +598,9 @@
   "generated arguments parse failed in round-trip">;
 def err_cc1_round_trip_mismatch : Error<
   "generated arguments do not match in round-trip">;
+
+def err_drv_only_one_offload_target_supported_in : Error<
+  "Only one offload target is supported in %0.">;
+def err_drv_invalid_or_unsupported_offload_target : Error<
+  "Invalid or unsupported offload target: '%0'.">;
 }
Index: clang/include/clang/Basic/Cuda.h
===================================================================
--- clang/include/clang/Basic/Cuda.h
+++ clang/include/clang/Basic/Cuda.h
@@ -94,6 +94,7 @@
   GFX1033,
   GFX1034,
   GFX1035,
+  Generic, // For SPIR-V target.
   LAST,
 };
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to