-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[clang][Driver] Support for the SPIR-V backend when compiling HIP #167543
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang][Driver] Support for the SPIR-V backend when compiling HIP #167543
Conversation
|
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-driver Author: Manuel Carrasco (mgcarrasco) ChangesThis PR enables the SPIR-V backend in the new driver via When the SPIR-V backend must be called in When Patch is 26.45 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/167543.diff 7 Files Affected:
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 0a414c685eae6..c129ac3f6db84 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -1423,6 +1423,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 use_spirv_backend
+ : Flag<["-"], "use-spirv-backend">,
+ Group<hip_Group>,
+ Flags<[HelpHidden]>,
+ HelpText<"Use the SPIRV backend for compilation ">;
+def no_use_spirv_backend
+ : Flag<["-"], "no-use-spirv-backend">,
+ Group<hip_Group>,
+ Flags<[HelpHidden]>,
+ HelpText<"Do not use the SPIRV backend for compilation ">;
}
// Clang specific/exclusive options for OpenACC.
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 9fd64d4aac514..729dc48d15a9f 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -4999,15 +4999,24 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
// Compiling HIP in device-only non-RDC mode requires linking each action
// individually.
for (Action *&A : DeviceActions) {
- // Special handling for the HIP SPIR-V toolchain because it doesn't use
- // the SPIR-V backend yet doesn't report the output as an object.
bool IsAMDGCNSPIRV = A->getOffloadingToolChain() &&
A->getOffloadingToolChain()->getTriple().getOS() ==
llvm::Triple::OSType::AMDHSA &&
A->getOffloadingToolChain()->getTriple().isSPIRV();
+ bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
+ options::OPT_no_use_spirv_backend,
+ /*Default=*/false);
+
+ // Special handling for the HIP SPIR-V toolchain in device-only.
+ // The translator path has a linking step, whereas the SPIR-V backend path
+ // does not to avoid any external dependency such as spirv-link. The
+ // linking step is skipped for the SPIR-V backend path.
+ bool IsAMDGCNSPIRVWithBackend = IsAMDGCNSPIRV && UseSPIRVBackend;
+
if ((A->getType() != types::TY_Object && !IsAMDGCNSPIRV &&
A->getType() != types::TY_LTO_BC) ||
- HIPRelocatableObj || !HIPNoRDC || !offloadDeviceOnly())
+ HIPRelocatableObj || !HIPNoRDC || !offloadDeviceOnly() ||
+ (IsAMDGCNSPIRVWithBackend && offloadDeviceOnly()))
continue;
ActionList LinkerInput = {A};
A = C.MakeAction<LinkJobAction>(LinkerInput, types::TY_Image);
@@ -5210,20 +5219,43 @@ Action *Driver::ConstructPhaseAction(
Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
return C.MakeAction<BackendJobAction>(Input, Output);
}
- if (Args.hasArg(options::OPT_emit_llvm) ||
- TargetDeviceOffloadKind == Action::OFK_SYCL ||
- (((Input->getOffloadingToolChain() &&
- Input->getOffloadingToolChain()->getTriple().isAMDGPU()) ||
- TargetDeviceOffloadKind == Action::OFK_HIP) &&
- ((Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
- false) ||
- (Args.hasFlag(options::OPT_offload_new_driver,
- options::OPT_no_offload_new_driver, false) &&
- (!offloadDeviceOnly() ||
- (Input->getOffloadingToolChain() &&
- TargetDeviceOffloadKind == Action::OFK_HIP &&
- Input->getOffloadingToolChain()->getTriple().isSPIRV())))) ||
- TargetDeviceOffloadKind == Action::OFK_OpenMP))) {
+
+ bool IsEmitLLVM = Args.hasArg(options::OPT_emit_llvm);
+ bool IsSYCL = TargetDeviceOffloadKind == Action::OFK_SYCL;
+
+ auto OffloadingToolChain = Input->getOffloadingToolChain();
+ bool IsAMDGPU =
+ OffloadingToolChain && OffloadingToolChain->getTriple().isAMDGPU();
+ bool IsRDC =
+ Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, false);
+ bool IsNewOffloadDriver =
+ Args.hasFlag(options::OPT_offload_new_driver,
+ options::OPT_no_offload_new_driver, false);
+ bool IsHIP = TargetDeviceOffloadKind == Action::OFK_HIP;
+ bool IsSPIRV =
+ OffloadingToolChain && OffloadingToolChain->getTriple().isSPIRV();
+ bool IsAMDGPUOrHIP = IsAMDGPU || IsHIP;
+ bool IsHIPToSPIRV = IsHIP && IsSPIRV;
+ bool IsOpenMP = TargetDeviceOffloadKind == Action::OFK_OpenMP;
+
+ bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
+ options::OPT_no_use_spirv_backend,
+ /*Default=*/false);
+
+ // If offloadDeviceOnly(), we call the SPIRV backend unless LLVM bitcode was
+ // requested explicitly or RDC is set. If !offloadDeviceOnly, we emit LLVM
+ // bitcode, and clang-linker-wrapper will compile it to SPIRV.
+ bool UseSPIRVBackendForHipDeviceOnlyNoRDC =
+ IsHIPToSPIRV && UseSPIRVBackend && offloadDeviceOnly() && !IsRDC;
+
+ bool IsLLVMBitcodeOutput =
+ IsEmitLLVM || IsSYCL ||
+ (IsAMDGPUOrHIP && !UseSPIRVBackendForHipDeviceOnlyNoRDC &&
+ ((IsRDC ||
+ (IsNewOffloadDriver && (!offloadDeviceOnly() || IsHIPToSPIRV))) ||
+ IsOpenMP));
+
+ if (IsLLVMBitcodeOutput) {
types::ID Output =
Args.hasArg(options::OPT_S) &&
(TargetDeviceOffloadKind == Action::OFK_None ||
@@ -5236,6 +5268,22 @@ Action *Driver::ConstructPhaseAction(
: types::TY_LLVM_BC;
return C.MakeAction<BackendJobAction>(Input, Output);
}
+
+ // The SPIRV backend compilation path for HIP must avoid external
+ // dependencies. The default compilation path assembles and links its
+ // output, but the SPIRV assembler and linker are external tools. This code
+ // ensures the backend emits binary SPIRV directly to bypass those steps and
+ // avoid failures. Without -save-temps, the compiler may already skip
+ // assembling and linking. With -save-temps, these steps must be explicitly
+ // disabled, as done here. We also force skipping these steps regardless of
+ // -save-temps to avoid relying on optimizations (unless -S is set).
+ bool IsBinarySPIRVOutput =
+ UseSPIRVBackendForHipDeviceOnlyNoRDC && !Args.hasArg(options::OPT_S);
+ if (IsBinarySPIRVOutput) {
+ // The current HIP bundling expects the type to be types::TY_Image
+ return C.MakeAction<BackendJobAction>(Input, types::TY_Image);
+ }
+
return C.MakeAction<BackendJobAction>(Input, types::TY_PP_Asm);
}
case phases::Assemble:
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 2791b1e57877e..639b70e0902fa 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5057,6 +5057,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.ClaimAllArgs(options::OPT_femit_dwarf_unwind_EQ);
}
+ bool IsAMDSPIRVForHIPDevice =
+ IsHIPDevice && getToolChain().getTriple().isSPIRV() &&
+ getToolChain().getTriple().getVendor() == llvm::Triple::AMD;
+
if (isa<AnalyzeJobAction>(JA)) {
assert(JA.getType() == types::TY_Plist && "Invalid output type.");
CmdArgs.push_back("-analyze");
@@ -5154,6 +5158,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_Image && IsAMDSPIRVForHIPDevice) {
+ CmdArgs.push_back("-emit-obj");
} else {
assert(JA.getType() == types::TY_PP_Asm && "Unexpected output type!");
}
@@ -9074,7 +9080,9 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
OPT_fno_lto,
OPT_flto,
OPT_flto_partitions_EQ,
- OPT_flto_EQ};
+ OPT_flto_EQ,
+ OPT_use_spirv_backend};
+
const llvm::DenseSet<unsigned> LinkerOptions{OPT_mllvm, OPT_Zlinker_input};
auto ShouldForwardForToolChain = [&](Arg *A, const ToolChain &TC) {
// Don't forward -mllvm to toolchains that don't support LLVM.
diff --git a/clang/lib/Driver/ToolChains/HIPAMD.cpp b/clang/lib/Driver/ToolChains/HIPAMD.cpp
index 0fbfa090ed9d3..492cfe7fe8063 100644
--- a/clang/lib/Driver/ToolChains/HIPAMD.cpp
+++ b/clang/lib/Driver/ToolChains/HIPAMD.cpp
@@ -159,10 +159,9 @@ void AMDGCN::Linker::constructLldCommand(Compilation &C, const JobAction &JA,
// For SPIR-V the inputs for the job are device AMDGCN SPIR-V flavoured bitcode
// and the output is either a compiled SPIR-V binary or bitcode (-emit-llvm). It
-// calls llvm-link and then the llvm-spirv translator. Once the SPIR-V BE will
-// be promoted from experimental, we will switch to using that. TODO: consider
-// if we want to run any targeted optimisations over IR here, over generic
-// SPIR-V.
+// calls llvm-link and then the llvm-spirv translator or the SPIR-V BE.
+// TODO: consider if we want to run any targeted optimisations over IR here,
+// over generic SPIR-V.
void AMDGCN::Linker::constructLinkAndEmitSpirvCommand(
Compilation &C, const JobAction &JA, const InputInfoList &Inputs,
const InputInfo &Output, const llvm::opt::ArgList &Args) const {
@@ -173,17 +172,40 @@ void AMDGCN::Linker::constructLinkAndEmitSpirvCommand(
const char *LinkedBCFilePath = HIP::getTempFile(C, LinkedBCFilePrefix, "bc");
InputInfo LinkedBCFile(&JA, LinkedBCFilePath, Output.getBaseInput());
+ bool UseSPIRVBackend =
+ Args.hasFlag(options::OPT_use_spirv_backend,
+ options::OPT_no_use_spirv_backend, /*Default=*/false);
+
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);
+ if (UseSPIRVBackend) {
+ // This code handles the case in the new driver when --offload-device-only
+ // is unset and clang-linker-wrapper forwards the bitcode that must be
+ // compiled to SPIR-V.
+
+ llvm::opt::ArgStringList CmdArgs;
+ const char *Triple =
+ C.getArgs().MakeArgString("-triple=spirv64-amd-amdhsa");
+
+ CmdArgs.append({"-cc1", Triple, "-emit-obj", "-disable-llvm-optzns",
+ 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 {
+ // Emit SPIR-V binary using the translator
+ 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..e1adc4ec07465
--- /dev/null
+++ b/clang/test/Driver/hip-spirv-backend-bindings.c
@@ -0,0 +1,54 @@
+// RUN: %clang --offload-new-driver --target=x86_64-unknown-linux-gnu --offload-arch=amdgcnspirv \
+// RUN: -nogpuinc -nogpulib -x hip %s -save-temps \
+// RUN: -use-spirv-backend -ccc-print-bindings \
+// RUN: 2>&1 | FileCheck %s --check-prefixes=CHECK-SPIRV-BASE,CHECK-SPIRV
+
+// RUN: %clang --offload-new-driver --target=x86_64-unknown-linux-gnu --offload-arch=amdgcnspirv \
+// RUN: -nogpuinc -nogpulib -x hip %s -save-temps \
+// RUN: -use-spirv-backend -fgpu-rdc -ccc-print-bindings \
+// RUN: 2>&1 | FileCheck %s --check-prefixes=CHECK-SPIRV-BASE,CHECK-SPIRV-RDC
+
+// CHECK-SPIRV-BASE: # "spirv64-amd-amdhsa" - "clang", inputs: ["[[INPUT:.+]]"], output: "[[HIPI:.+\.hipi]]"
+// CHECK-SPIRV-BASE: # "spirv64-amd-amdhsa" - "clang", inputs: ["[[HIPI]]"], output: "[[SPV_BC:.+\.bc]]"
+// CHECK-SPIRV-BASE: # "spirv64-amd-amdhsa" - "clang", inputs: ["[[SPV_BC]]"], output: "[[SPV_BC:.+\.bc]]"
+// CHECK-SPIRV-BASE: # "x86_64-unknown-linux-gnu" - "Offload::Packager", inputs: ["[[SPV_BC]]"], output: "[[HIP_OUT:.+\.out]]"
+// CHECK-SPIRV-BASE: # "x86_64-unknown-linux-gnu" - "clang", inputs: ["[[INPUT]]"], output: "[[HIPI:.+\.hipi]]"
+// CHECK-SPIRV-BASE: # "x86_64-unknown-linux-gnu" - "clang", inputs: ["[[HIPI]]", "[[HIP_OUT]]"], output: "[[x86_BC:.+\.bc]]"
+// CHECK-SPIRV-BASE: # "x86_64-unknown-linux-gnu" - "clang", inputs: ["[[x86_BC]]"], output: "[[x86_S:.+\.s]]"
+// CHECK-SPIRV-BASE: # "x86_64-unknown-linux-gnu" - "clang::as", inputs: ["[[x86_S]]"], output: "[[x86_O:.+\.o]]"
+// CHECK-SPIRV-RDC: # "x86_64-unknown-linux-gnu" - "Offload::Linker", inputs: ["[[x86_O]]"], output: "{{.+\.out}}"
+// CHECK-SPIRV: # "x86_64-unknown-linux-gnu" - "Offload::Linker", inputs: ["[[x86_O]]"], output: "[[x86_O:.+\.o]]"
+// CHECK-SPIRV: # "x86_64-unknown-linux-gnu" - "GNU::Linker", inputs: ["[[x86_O]]"], output: "{{.+\.out}}"
+
+// RUN: %clang --offload-new-driver --target=x86_64-unknown-linux-gnu --offload-arch=amdgcnspirv \
+// RUN: -nogpuinc -nogpulib -x hip %s -save-temps \
+// RUN: -use-spirv-backend --offload-device-only -ccc-print-bindings \
+// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-OFFLOAD-DEVICE-ONLY
+
+// CHECK-SPIRV-OFFLOAD-DEVICE-ONLY: # "spirv64-amd-amdhsa" - "clang", inputs: ["[[INPUT:.+]]"], output: "[[HIPI:.+\.hipi]]"
+// CHECK-SPIRV-OFFLOAD-DEVICE-ONLY: # "spirv64-amd-amdhsa" - "clang", inputs: ["[[HIPI]]"], output: "[[SPV_BC:.+\.bc]]"
+// CHECK-SPIRV-OFFLOAD-DEVICE-ONLY: # "spirv64-amd-amdhsa" - "clang", inputs: ["[[SPV_BC]]"], output: "[[SPV_OUT:.+\.out]]"
+// CHECK-SPIRV-OFFLOAD-DEVICE-ONLY: # "spirv64-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[SPV_OUT]]"], output: "{{.+\.hipfb}}"
+
+// RUN: %clang --offload-new-driver --target=x86_64-unknown-linux-gnu --offload-arch=amdgcnspirv \
+// RUN: -nogpuinc -nogpulib -x hip %s -save-temps \
+// RUN: -use-spirv-backend --offload-device-only -fgpu-rdc -ccc-print-bindings \
+// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-OFFLOAD-DEVICE-ONLY-RDC
+
+// CHECK-SPIRV-OFFLOAD-DEVICE-ONLY-RDC: # "spirv64-amd-amdhsa" - "clang", inputs: ["[[INPUT:.+]]"], output: "[[HIPI:.+\.hipi]]"
+// CHECK-SPIRV-OFFLOAD-DEVICE-ONLY-RDC: # "spirv64-amd-amdhsa" - "clang", inputs: ["[[HIPI]]"], output: "[[SPV_BC:.+\.bc]]"
+// CHECK-SPIRV-OFFLOAD-DEVICE-ONLY-RDC: # "spirv64-amd-amdhsa" - "clang", inputs: ["[[SPV_BC]]"], output: "{{.+}}"
+
+// RUN: %clang --offload-new-driver --target=x86_64-unknown-linux-gnu --offload-arch=amdgcnspirv \
+// RUN: -nogpuinc -nogpulib -x hip %s -save-temps \
+// RUN: -use-spirv-backend --offload-device-only -S -fgpu-rdc -ccc-print-bindings \
+// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-OFFLOAD-DEVICE-ONLY-RDC
+
+// RUN: %clang --offload-new-driver --target=x86_64-unknown-linux-gnu --offload-arch=amdgcnspirv \
+// RUN: -nogpuinc -nogpulib -x hip %s -save-temps \
+// RUN: -use-spirv-backend --offload-device-only -S -ccc-print-bindings \
+// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-SPIRV-TEXTUAL-OFFLOAD-DEVICE-ONLY
+
+// CHECK-SPIRV-TEXTUAL-OFFLOAD-DEVICE-ONLY: # "spirv64-amd-amdhsa" - "clang", inputs: ["[[INPUT:.+]]"], output: "[[HIPI:.+\.hipi]]"
+// CHECK-SPIRV-TEXTUAL-OFFLOAD-DEVICE-ONLY: # "spirv64-amd-amdhsa" - "clang", inputs: ["[[HIPI]]"], output: "[[SPV_BC:.+\.bc]]"
+// CHECK-SPIRV-TEXTUAL-OFFLOAD-DEVICE-ONLY: # "spirv64-amd-amdhsa" - "clang", inputs: ["[[SPV_BC]]"], output: "{{.+\.s}}"
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..d5f55f766d787
--- /dev/null
+++ b/clang/test/Driver/hip-spirv-backend-opt.c
@@ -0,0 +1,55 @@
+// This test case validates the behavior of -use-spirv-backend
+
+// --offload-device-only is always set --- testing interactions with -S and -fgpu-rdc
+
+// RUN: %clang --offload-new-driver --target=x86_64-unknown-linux-gnu --offload-arch=amdgcnspirv \
+// RUN: -nogpuinc -nogpulib -### -x hip %s -save-temps \
+// RUN: -use-spirv-backend --offload-device-only -S \
+// RUN: 2>&1 | FileCheck %s --check-prefixes=CHECK-SPIRV-TRANSLATOR,CHECK-SPIRV-BACKEND-TEXTUAL
+
+// RUN: %clang --offload-new-driver --target=x86_64-unknown-linux-gnu --offload-arch=amdgcnspirv \
+// RUN: -nogpuinc -nogpulib -### -x hip %s -save-temps \
+// RUN: -use-spirv-backend --offload-device-only \
+// RUN: 2>&1 | FileCheck %s --check-prefixes=CHECK-SPIRV-TRANSLATOR,CHECK-SPIRV-BACKEND-BINARY
+
+// The new driver's behavior is to emit LLVM IR for --offload-device-only and -fgpu-rdc (independently of SPIR-V).
+// RUN: %clang --offload-new-driver --target=x86_64-unknown-linux-gnu --offload-arch=amdgcnspirv \
+// RUN: -### -nogpuinc -nogpulib -x hip %s -save-temps \
+// RUN: -use-spirv-backend --offload-device-only -S -fgpu-rdc \
+// RUN: 2>&1 | FileCheck %s --check-prefixes=CHECK-SPIRV-TRANSLATOR,CHECK-SPIRV-BACKEND-LL,CHECK-FGPU-RDC
+
+// The new driver's behavior is to emit LLVM IR for --offload-device-only and -fgpu-rdc (independently of SPIR-V).
+// RUN: %clang --offload-new-driver --target=x86_64-unknown-linux-gnu --offload-arch=amdgcnspirv \
+// RUN: -nogpuinc -nogpulib -### -x hip %s -save-temps \
+// RUN: -use-spirv-backend --offload-device-only -fgpu-rdc \
+// RUN: 2>&1 | FileCheck %s --check-prefixes=CHECK-SPIRV-TRANSLATOR,CHECK-SPIRV-BACKEND-BC,CHECK-FGPU-RDC
+
+// --offload-device-only is always unset --- testing interactions with -S and -fgpu-rdc
+
+// RUN: %clang --offload-new-driver --target=x86_64-unknown-linux-gnu --offload-arch=amdgcnspirv \
+// RUN: -nogpuinc -nogpulib -### -x hip %s -save-temps \
+// RUN: -use-spirv-backend -S -fgpu-rdc \
+// RUN: 2>&1 | FileCheck %s --check-prefixes=CHECK-SPIRV-TRANSLATOR,CHECK-SPIRV-BACKEND-BC,CHECK-FGPU-RDC
+
+// RUN: %clang --offload-new-driver --target=x86_64-unknown-linux-gnu --offload-arch=amdgcnspirv \
+// RUN: -nogpuinc -nogpulib -### -x hip %s -save-temps \
+// RUN: -use-spirv-backend -S \
+// RUN: 2>&1 | FileCheck %s --check-prefixes=CHECK-SPIRV-TRANSLATOR,CHECK-SPIRV-BACKEND-BC
+
+// RUN: %clang --offload-new-driver --target=x86_64-unknown-linux-gnu --offload-arch=amdgcnspirv \
+// RUN: -nogpuinc -nogpulib -### -x hip %s -save-temps \
+// RUN: -use-spirv-backend -fgpu-rdc \
+// RUN: 2>&1 | FileCheck %s --check-prefixes=CHECK-SPIRV-TRANSLATOR,CHECK-SPIRV-BACKEND-BC,CHECK-CLANG-LINKER-WRAPPER
+
+// RUN: %clang --offload-new-driver --target=x86_64-unknown-linux-gnu --offload-arch=amdgcnspirv \
+// RUN: -nogpuinc -nogpulib -### -x hip %s -save-temps \
+// RUN: -use-spirv-backend \
+// RUN: 2>&1 | FileCheck %s --check-prefixes=CHECK-SPIRV-TRANSLATOR,CHECK-SPIRV-BACKEND-BC,CHECK-CLANG-LINKER-WRAPPER
+
+// CHECK-SPIRV-TRANSLATOR-NOT: "{{.*llvm-spirv.*}}"
+// CHECK-SPIRV-BACKEND-TEXTUAL: "{{.*}}clang{{.*}}" "-cc1" "-triple" "spirv64-amd-amdhsa" {{.*}} "-S"
+// CHECK-SPIRV-BACKEND-BINARY: "{{.*}}clang{{.*}}" "-cc1" "-triple" "spirv64-amd-amdhsa" {{.*}} "-emit-obj"
+// CHECK-SPIRV-BACKEND-BC: "{{.*}}clang{{.*}}" "-cc1" "-triple" "spirv64-amd-amdhsa" {{.*}} "-emit-llvm-bc"
+// CHECK-SPIRV-BACKEND-LL: "{{.*}}clang{{.*}}" "-cc1" "-triple" "spirv64-amd-amdhsa" {{.*}} "-emit-llvm"
+// CHECK-FGPU-RDC-SAME: {{.*}} "-fgpu-rdc"
+// CHECK-CLANG-LINKER-WRAPPER: "{{.*}}clang-linker-wrapper" "--should-extract=amdgcnspirv" {{.*}} "--device-compiler=spirv64-amd-amdhsa=-use-spirv-backend"
diff --git a/clang/test/Driver/hip-spirv-backend-phases.c b/clang/test/Driv...
[truncated]
|
jhuber6
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't fully understand what the SPIR-V plan is exactly. Maybe @AlexVlx or @yxsamliu can chime in. This seems to apply for --offload-device-only cases? What's the expected output there. For me I would expect it to be SPIR-V. I think the --offload-new-driver behavior in device only mode differs slightly so I'll need to confirm what we want to actually happen.
@jhuber6 Thanks for the feedback. The PR enables the SPIR-V BE when
Yes, it handles those cases and also handles the cases when
Just to follow, do you mean that it differs slightly in regards to what precisely? I don't understand if you mean with respect to non device only in the new driver, or device only but in the old driver. What two things are you comparing? |
87d9103 to
6d1b5b6
Compare
🐧 Linux x64 Test Results
|
31b08be to
46bd79c
Compare
|
Hello, Just to add one data point: I've cherry-picked this PR over amd-staging and added 2 quick and dirty workarounds* for the SPIRV backend to work in https://github.com/ROCm/llvm-project/commits/users/jmmartinez/spirv/hacks_but_it_works . I then tried the following combinations over the
I haven't tested the SPIRV translator path. * The workaround are related to visibility-hidden not being representable in SPIRV (the backend crashes when there are declarations with this visibility) |
Thanks @jmmartinez. I've tested the translator path too. There is only one minor expected difference between the output types for |
jhuber6
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems fine, one nit. I'll wait for @AlexVlx to give the final go-ahead because he knows the goals for this better than I do
…PIRV backend instead of the SPIRV translator for HIP.
…-use-spirv-backend.
5f452ef to
6a500dd
Compare
|
Got green light from Alex. |
… HIP (llvm#167543)" This reverts commit 1a03673. Reverted due to a failure in hip-spirv-backend-opt.c for fuchsia-x86_64-linux.
…67543) For HIP, the SPIR-V backend can be optionally activated with the -use-spirv-backend flag. This option uses the SPIR-V BE instead of the SPIR-V translator. These changes also ensure that -use-spirv-backend does not require external dependencies, such as spirv-as and spirv-link
… HIP" (#169637) This relands "[clang][Driver] Support for the SPIR-V backend when compiling HIP" #167543. The only new change is a small fix for the multicall driver. For HIP, the SPIR-V backend can be optionally activated with the -use-spirv-backend flag. This option uses the SPIR-V BE instead of the SPIR-V translator. These changes also ensure that -use-spirv-backend does not require external dependencies, such as spirv-as and spirv-link
… HIP" (llvm#169637) This relands "[clang][Driver] Support for the SPIR-V backend when compiling HIP" llvm#167543. The only new change is a small fix for the multicall driver. For HIP, the SPIR-V backend can be optionally activated with the -use-spirv-backend flag. This option uses the SPIR-V BE instead of the SPIR-V translator. These changes also ensure that -use-spirv-backend does not require external dependencies, such as spirv-as and spirv-link
… HIP" (llvm#169637) This relands "[clang][Driver] Support for the SPIR-V backend when compiling HIP" llvm#167543. The only new change is a small fix for the multicall driver. For HIP, the SPIR-V backend can be optionally activated with the -use-spirv-backend flag. This option uses the SPIR-V BE instead of the SPIR-V translator. These changes also ensure that -use-spirv-backend does not require external dependencies, such as spirv-as and spirv-link
This PR enables the SPIR-V backend in the new driver via
-use-spirv-backend.When the SPIR-V backend must be called in
--offload-device-onlymode, we rely on the default compiler path. The changes for this end are only to avoid external dependencies such asspirv-asandspirv-link.When
--offload-device-onlyis unset,clang-linker-wrappercallsclangfor linking the bitcode(s). In this case, we link the LLVM bitcode and call the backend to avoid changingclang-linker-wrapperand relying onspirv-link.The expected behavior is that when
-use-spirv-backendis set and the new driver requires generating SPIR-V it does so using the SPIR-V backend instead of the SPIR-V translator; this must work with and without--offload-device-only.The output file type remains as if
-use-spirv-backendis unset (always in the new driver).These scenarios that we expect to support, starting with
clang --offload-new-driver --target=x86_64-unknown-linux-gnu --offload-arch=amdgcnspirv -use-spirv-backend:--offload-device-only -S--offload-device-only--offload-device-only -S -fgpu-rdc--offload-device-only -fgpu-rdc-S -fgpu-rdc-S-fgpu-rdcEDIT: These changes also introduce support for
-use-spirv-backendin the old driver