-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[SPIRV] Change how to detect OpenCL/Vulkan Env and update tests accordingly. #129689
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?
[SPIRV] Change how to detect OpenCL/Vulkan Env and update tests accordingly. #129689
Conversation
@llvm/pr-subscribers-backend-spir-v Author: Marcos Maronas (maarquitos14) ChangesThe test is intended to specifically test spirv-friendly builtins, so change the function name to spirv-friendly format. Full diff: https://github.com/llvm/llvm-project/pull/129689.diff 1 Files Affected:
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_bit_instructions/spirv-friendly_extended_bit_ops.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_bit_instructions/spirv-friendly_extended_bit_ops.ll
index e49a55956aff0..c93a4ad1bf1c9 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_bit_instructions/spirv-friendly_extended_bit_ops.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_bit_instructions/spirv-friendly_extended_bit_ops.ll
@@ -76,12 +76,12 @@ declare spir_func <8 x i8> @_Z24__spirv_BitFieldUExtractDv8_hjj(<8 x i8>, i32, i
; }
define spir_kernel void @testBitReverse_SPIRVFriendly(<4 x i64> %b, ptr addrspace(1) nocapture align 32 %res) #3 {
entry:
- %call = call <4 x i64> @llvm.bitreverse.v4i64(<4 x i64> %b)
+ %call = call <4 x i64> @_Z18__spirv_BitReverseDv4_l(<4 x i64> %b)
store <4 x i64> %call, ptr addrspace(1) %res, align 32
ret void
}
-declare <4 x i64> @llvm.bitreverse.v4i64(<4 x i64>) #4
+declare <4 x i64> @_Z18__spirv_BitReverseDv4_l(<4 x i64>) #4
|
b8daa27
to
11e5b6f
Compare
You can test this locally with the following command:git-clang-format --diff HEAD~1 HEAD --extensions h,cpp -- llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp llvm/lib/Target/SPIRV/SPIRVSubtarget.h llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp View the diff from clang-format here.diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 39cdf04b6..d1342cb46 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -2205,11 +2205,12 @@ bool SPIRVInstructionSelector::selectWaveOpInst(Register ResVReg,
MachineBasicBlock &BB = *I.getParent();
SPIRVType *IntTy = GR.getOrCreateSPIRVIntegerType(32, I, TII);
- auto BMI = BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode))
- .addDef(ResVReg)
- .addUse(GR.getSPIRVTypeID(ResType))
- .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I,
- IntTy, TII, !STI.isLogicalSPIRV()));
+ auto BMI =
+ BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode))
+ .addDef(ResVReg)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII,
+ !STI.isLogicalSPIRV()));
for (unsigned J = 2; J < I.getNumOperands(); J++) {
BMI.addUse(I.getOperand(J).getReg());
|
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 think this is OK for me, as I don't think there are any other target than OpenCL/Vulkan for now. This can be revisited when Microsoft adds their DX/SPIRV thing
"This entry point lacks mandatory hlsl.shader attribute."); | ||
"This entry point lacks mandatory hlsl.shader attribute.", false); | ||
} | ||
|
||
const auto value = attribute.getValueAsString(); | ||
if (value == "compute") | ||
return SPIRV::ExecutionModel::GLCompute; | ||
|
||
report_fatal_error("This HLSL entry point is not supported by this backend."); |
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.
unrelated no?
I'm afraid, this looks fragile with regards to the triple. Triples of kinds, for instance, "spirv64-unknown-unknown" and "spirv64v1.6-unknown-unknown" are massively in use and nobody expects that the "-opencl" suffix change game rules. If a user needs now to apply "-opencl" everywhere to be recognized as the user of the compute flavor of SPIR-V, I expect that pretty much everything will start to fail after this change. Probably we need a way that doesn't require updating the whole compute's set of test cases, this is the only guarantee that SYCL, Intel's XPU backend for Triton, etc. will not notice the internal change in the SPIR-V backend. This is not to mention non-Intel applications of the compute flavor of SPIR-V. For the context it's important that isOpenCLEnv() is just a bad choice of the name for such a function, it should be renamed to something of a kind of isCompute() to reflect what it means. |
Let's add to the discussion more people: @michalpaszkowski @MrSidims @asudarsa |
I would expect that updating Clang to generate
I agree, and similarly, |
CC: @AlexVlx |
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.
This patch is LGTM, but IMHO this is a case when a work shouldn't be split across components - I mean that either this PR should also include changes in clang, that are forcing OpenCL environment to be included in the triple information for OpenCL lang or the appropriate PR in clang should already exist and be linked here as we also need to have attention and feedback from the frontend folks.
fyi @svenvh
} | ||
bool isVulkanEnv() const { return TargetTriple.getArch() == Triple::spirv; } | ||
bool isVulkanEnv() const { return !isOpenCLEnv(); } |
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 see that Vulkan is added to the triple as OSType:
Vulkan, // Vulkan SPIR-V |
SPIR target uses
Vulkan
OSType to detect Vulkan environment: llvm-project/clang/lib/Basic/Targets/SPIR.h
Lines 305 to 312 in 9fdac84
assert(Triple.getArch() == llvm::Triple::spirv && | |
"Invalid architecture for Logical SPIR-V."); | |
assert(Triple.getOS() == llvm::Triple::Vulkan && | |
Triple.getVulkanVersion() != llvm::VersionTuple(0) && | |
"Logical SPIR-V requires a valid Vulkan environment."); | |
assert(Triple.getEnvironment() >= llvm::Triple::Pixel && | |
Triple.getEnvironment() <= llvm::Triple::Amplification && | |
"Logical SPIR-V environment must be a valid shader stage."); |
OpenCL is a bit messy.
I see one* OpenCL OSType:
NVCL, // NVIDIA OpenCL |
Environment component also defines OpenCL:
OpenCL, |
I don't know the meaning of OpenCL in the environment component, but using OS triple component makes more sense to me. This topic probably forth a separate discussion, but I would add OpenCL component to OSType rather than to environment component. I guess we can alias NVCL
to the OpenCL
OSType value.
* - Maybe Mesa3D
can be also considered as OpenCL environment.
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 know the meaning of OpenCL in the environment component
It was added in #78655 and seems to be just a side change. I've asked the author in the PR, what was the idea behind adding OpenCL to env, but not sure if I'll get a reply.
} | ||
bool isVulkanEnv() const { return TargetTriple.getArch() == Triple::spirv; } | ||
bool isVulkanEnv() const { return !isOpenCLEnv(); } |
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.
bool isVulkanEnv() const { return !isOpenCLEnv(); }
This code says that any triple that doesn't match OpenCL environment is Vulkan environment.
I would prefer SPIR-V backend to keep existing behavior for existing triple i.e. spirv[32|64]-unknown-unknown -> OpenCL environment.
New triples:
spirv-<vendor>-vulkan
- SPIR-V for Vulkan environment.spirv[32|64]-<vendor>-opencl
- SPIR-V for OpenCL environment.
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.
One of the things that we would like to fix is the fact that Vulkan/Shader environment can also be for a physical target (spirv32, spirv64). In other words, although de facto every physical SPIRV is Compute, and every logical SPIRV is Shader, that is not a requirement from the spec, so we should be able to support logical SPIRV for Compute and physical SPIRV for Shader.
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.
Can it be done in less intrusive way e.g. by requiring vulkan OS in the target triple?
If OS target triple is not Vulkan, the environment is set to OpenCL.
This way, we won't break the existing interface for FEs using "unknown" OS type to target OpenCL environment.
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.
The new approach I just added shouldn't break the existing interface for FEs using "unknown" OS type to target OpenCL environment.
11e5b6f
to
eef5045
Compare
@Keenuts the new approach I just added makes 58 tests fail. They can all pass if we explicitly pass |
A new test added for spirv-friendly builtins for SPV_KHR_bit_instructions unveiled that current mechanism to detect whether SPIRV Backend is in OpenCL environment or Vulkan environment was not good enough. This PR updates how to detect the environment and all the tests accordingly.
UPDATE: the new approach is having a new member in
SPIRVSubtarget
to represent the environment. It can be either OpenCL, Kernel or Unknown. If the triple is explicit, we can directly set it at the creation of theSPIRVSubtarget
, otherwise we just leave it unknown until we find other information that can help us set the environment. For now, the only other information we use to set the environment ishlsl.shader
attribute atSPIRV::ExecutionModel::ExecutionModel getExecutionModel(const SPIRVSubtarget &STI, const Function &F)
. Going forward we should consider also specific instructions that are Kernel-exclusive or Shader-exclusive.