[Clang] Add standalone AMDGPU SPIR-V toolchain (#144576)

Summary:
The AMDGPU toolchain uses a different set of tools than the standard
SPIR-V toolchain. The linker wrapper prefers to invoke a linker via a
clang toolchain. To make that work we introduce
`--target=spirv64-amd-amdhsa` so that it creates the linking phases that
HIP prefers. Additionally, this can be used to make LLVM-IR / SPIR-V
from C/C++ that can be linked with the HIP output.
This commit is contained in:
Joseph Huber 2025-06-19 09:23:57 -05:00 committed by GitHub
parent 7e8f1f5f72
commit 4c6f398b86
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 51 additions and 5 deletions

View file

@ -6857,11 +6857,17 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
TC = std::make_unique<toolchains::NVPTXToolChain>(*this, Target, Args);
break;
case llvm::Triple::AMDHSA: {
bool DL =
usesInput(Args, types::isOpenCL) || usesInput(Args, types::isLLVMIR);
TC = DL ? std::make_unique<toolchains::ROCMToolChain>(*this, Target, Args)
: std::make_unique<toolchains::AMDGPUToolChain>(*this, Target,
Args);
if (Target.getArch() == llvm::Triple::spirv64) {
TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*this, Target,
Args);
} else {
bool DL = usesInput(Args, types::isOpenCL) ||
usesInput(Args, types::isLLVMIR);
TC = DL ? std::make_unique<toolchains::ROCMToolChain>(*this, Target,
Args)
: std::make_unique<toolchains::AMDGPUToolChain>(*this, Target,
Args);
}
break;
}
case llvm::Triple::AMDPAL:

View file

@ -417,3 +417,15 @@ void HIPAMDToolChain::checkTargetID(
getDriver().Diag(clang::diag::err_drv_bad_target_id)
<< *PTID.OptionalTargetID;
}
SPIRVAMDToolChain::SPIRVAMDToolChain(const Driver &D,
const llvm::Triple &Triple,
const ArgList &Args)
: ROCMToolChain(D, Triple, Args) {
getProgramPaths().push_back(getDriver().Dir);
}
Tool *SPIRVAMDToolChain::buildLinker() const {
assert(getTriple().getArch() == llvm::Triple::spirv64);
return new tools::AMDGCN::Linker(*this);
}

View file

@ -97,6 +97,15 @@ protected:
Tool *buildLinker() const override;
};
class LLVM_LIBRARY_VISIBILITY SPIRVAMDToolChain final : public ROCMToolChain {
public:
SPIRVAMDToolChain(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args);
protected:
Tool *buildLinker() const override;
};
} // end namespace toolchains
} // end namespace driver
} // end namespace clang

View file

@ -0,0 +1,19 @@
// RUN: %clang -### -ccc-print-phases --target=spirv64-amd-amdhsa %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=PHASES
// PHASES: 0: input, "[[INPUT:.+]]", c
// PHASES: 1: preprocessor, {0}, cpp-output
// PHASES: 2: compiler, {1}, ir
// PHASES: 3: backend, {2}, assembler
// PHASES: 4: assembler, {3}, object
// PHASES: 5: linker, {4}, image
// RUN: %clang -### -ccc-print-bindings --target=spirv64-amd-amdhsa %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=BINDINGS
// BINDINGS: # "spirv64-amd-amdhsa" - "clang", inputs: ["[[INPUT:.+]]"], output: "[[OUTPUT:.+]]"
// BINDINGS: # "spirv64-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[OUTPUT]]"], output: "a.out"
// RUN: %clang -### --target=spirv64-amd-amdhsa %s -nogpulib -nogpuinc 2>&1 \
// RUN: | FileCheck %s --check-prefix=INVOCATION
// INVOCATION: "-cc1" "-triple" "spirv64-amd-amdhsa" {{.*}} "-o" "[[OUTPUT:.+]]" "-x" "c"
// INVOCATION: "{{.*}}llvm-link" "-o" "a.out" "[[OUTPUT]]"
// INVOCATION: "{{.*}}llvm-spirv" "--spirv-max-version=1.6" "--spirv-ext=+all" "--spirv-allow-unknown-intrinsics" "--spirv-lower-const-expr" "--spirv-preserve-auxdata" "--spirv-debug-info-version=nonsemantic-shader-200" "a.out" "-o" "a.out"