Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions clang/include/clang/Options/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,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.
Expand Down
45 changes: 42 additions & 3 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5024,15 +5024,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);
Expand Down Expand Up @@ -5258,12 +5267,28 @@ Action *Driver::ConstructPhaseAction(
Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
return C.MakeAction<BackendJobAction>(Input, Output);
}
bool UseSPIRVBackend = Args.hasFlag(options::OPT_use_spirv_backend,
options::OPT_no_use_spirv_backend,
/*Default=*/false);

auto OffloadingToolChain = Input->getOffloadingToolChain();
// For AMD SPIRV, 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 =
TargetDeviceOffloadKind == Action::OFK_HIP && OffloadingToolChain &&
OffloadingToolChain->getTriple().isSPIRV() && UseSPIRVBackend &&
offloadDeviceOnly() &&
!Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, false);

if (Args.hasArg(options::OPT_emit_llvm) ||
TargetDeviceOffloadKind == Action::OFK_SYCL ||
(((Input->getOffloadingToolChain() &&
Input->getOffloadingToolChain()->getTriple().isAMDGPU() &&
TargetDeviceOffloadKind != Action::OFK_None) ||
TargetDeviceOffloadKind == Action::OFK_HIP) &&
!UseSPIRVBackendForHipDeviceOnlyNoRDC &&
((Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
false) ||
(Args.hasFlag(options::OPT_offload_new_driver,
Expand All @@ -5285,6 +5310,20 @@ 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).
if (UseSPIRVBackendForHipDeviceOnlyNoRDC && !Args.hasArg(options::OPT_S)) {
// The current HIP bundling expects the type to be types::TY_Image
return C.MakeAction<BackendJobAction>(Input, types::TY_Image);
}
Comment on lines +5322 to +5325
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (UseSPIRVBackendForHipDeviceOnlyNoRDC && !Args.hasArg(options::OPT_S)) {
// The current HIP bundling expects the type to be types::TY_Image
return C.MakeAction<BackendJobAction>(Input, types::TY_Image);
}
// The current HIP bundling expects the type to be types::TY_Image
if (UseSPIRVBackendForHipDeviceOnlyNoRDC && !Args.hasArg(options::OPT_S))
return C.MakeAction<BackendJobAction>(Input, types::TY_Image);


return C.MakeAction<BackendJobAction>(Input, types::TY_PP_Asm);
}
case phases::Assemble:
Expand Down
10 changes: 9 additions & 1 deletion clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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!");
}
Expand Down Expand Up @@ -9084,7 +9090,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.
Expand Down
48 changes: 35 additions & 13 deletions clang/lib/Driver/ToolChains/HIPAMD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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) {
Copy link
Contributor Author

@mgcarrasco mgcarrasco Nov 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jhuber6 This PR is designed for the new driver and this handling here is required for the new driver when clang-linker-wrapper calls clang. We link the bitcode first because we can't have a dependency with spirv-link, this is required for -fgpu-rdc.

I'm writing this comment to make a question for the old driver. The old driver always builds SPIR-V in the linking step (this function). This new code for the new driver works out-of-the-box for the old driver. This new code enables -use-spirv-backend also for the old driver.

Would it be OK to let the old driver use this new code to handle -use-spirv-backend as we need? I mean considering that this change is already required for the new driver.

// 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
Expand Down
57 changes: 57 additions & 0 deletions clang/test/Driver/hip-spirv-backend-bindings.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// 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: # "spirv64-amd-amdhsa" - "Offload::Packager", inputs: ["[[SPV_BC]]"], output: "[[HIP_OUT:.+\.out]]"
// CHECK-SPIRV: # "spirv64-amd-amdhsa" - "Offload::Linker", inputs: ["[[HIP_OUT]]"], output: "[[HIPFB:.+\.hipfb]]"
// CHECK-SPIRV-RDC: # "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: # "x86_64-unknown-linux-gnu" - "clang", inputs: ["[[HIPI]]", "[[HIPFB]]"], output: "[[x86_BC:.+\.bc]]"
// CHECK-SPIRV-RDC: # "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-BASE: # "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}}"
55 changes: 55 additions & 0 deletions clang/test/Driver/hip-spirv-backend-opt.c
Original file line number Diff line number Diff line change
@@ -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"
Loading