-
Notifications
You must be signed in to change notification settings - Fork 14k
[Clang] Add standalone AMDGPU SPIR-V toolchain #144576
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
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-clang-driver @llvm/pr-subscribers-clang Author: Joseph Huber (jhuber6) ChangesSummary: Full diff: https://github.com/llvm/llvm-project/pull/144576.diff 4 Files Affected:
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 060f76fb653c9..1114cb2ec5881 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -6849,11 +6849,18 @@ 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::spirv32 ||
+ 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:
diff --git a/clang/lib/Driver/ToolChains/HIPAMD.cpp b/clang/lib/Driver/ToolChains/HIPAMD.cpp
index a8f2b09b1b20f..7b47dcf366e05 100644
--- a/clang/lib/Driver/ToolChains/HIPAMD.cpp
+++ b/clang/lib/Driver/ToolChains/HIPAMD.cpp
@@ -417,3 +417,17 @@ 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) {
+ // Lookup binaries into the driver directory, this is used to
+ // discover the clang-offload-bundler executable.
+ getProgramPaths().push_back(getDriver().Dir);
+}
+
+Tool *SPIRVAMDToolChain::buildLinker() const {
+ assert(getTriple().getArch() == llvm::Triple::spirv64);
+ return new tools::AMDGCN::Linker(*this);
+}
diff --git a/clang/lib/Driver/ToolChains/HIPAMD.h b/clang/lib/Driver/ToolChains/HIPAMD.h
index c31894e22c5c8..3630b11cd8b1a 100644
--- a/clang/lib/Driver/ToolChains/HIPAMD.h
+++ b/clang/lib/Driver/ToolChains/HIPAMD.h
@@ -97,6 +97,15 @@ class LLVM_LIBRARY_VISIBILITY HIPAMDToolChain final : public ROCMToolChain {
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
diff --git a/clang/test/Driver/spirv-amd-toolchain.c b/clang/test/Driver/spirv-amd-toolchain.c
new file mode 100644
index 0000000000000..c9417400a9378
--- /dev/null
+++ b/clang/test/Driver/spirv-amd-toolchain.c
@@ -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"
|
} | ||
|
||
Tool *SPIRVAMDToolChain::buildLinker() const { | ||
assert(getTriple().getArch() == llvm::Triple::spirv64); |
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.
It looks like we use SPIRVAMDToolChain
for spirv32
or spirv64
but we assert it's spirv64
here. Can spirv32
never hit this?
Should we add a spirv32
test case?
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.
32-bit SPIR-V isn't supported by AMD as far as I know, maybe @AlexVlx can clarify. Definitely shouldn't be creating the toolchain.
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.
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 thatHIP prefers. Additionally, this can be used to make LLVM-IR / SPIR-V
from C/C++ that can be linked with the HIP output.