Skip to content

[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

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

maarquitos14
Copy link
Contributor

@maarquitos14 maarquitos14 commented Mar 4, 2025

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 the SPIRVSubtarget, 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 is hlsl.shader attribute at SPIRV::ExecutionModel::ExecutionModel getExecutionModel(const SPIRVSubtarget &STI, const Function &F). Going forward we should consider also specific instructions that are Kernel-exclusive or Shader-exclusive.

@llvmbot
Copy link
Member

llvmbot commented Mar 4, 2025

@llvm/pr-subscribers-backend-spir-v

Author: Marcos Maronas (maarquitos14)

Changes

The 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:

  • (modified) llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_bit_instructions/spirv-friendly_extended_bit_ops.ll (+2-2)
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
 
 
 

@maarquitos14 maarquitos14 changed the title Use SPIRV-friendly builtin name. [SPIRV] Use SPIRV-friendly builtin name. Mar 4, 2025
@VyacheslavLevytskyy VyacheslavLevytskyy self-requested a review March 4, 2025 11:46
@maarquitos14 maarquitos14 force-pushed the maronas/use-spirv-friendly-call branch from b8daa27 to 11e5b6f Compare April 2, 2025 14:59
@maarquitos14 maarquitos14 changed the title [SPIRV] Use SPIRV-friendly builtin name. [SPIRV] Change how to detect OpenCL/Vulkan Env and update tests accordingly. Apr 2, 2025
Copy link

github-actions bot commented Apr 2, 2025

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

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());

@maarquitos14 maarquitos14 marked this pull request as draft April 2, 2025 15:04
Copy link
Contributor

@Keenuts Keenuts left a 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

Comment on lines 284 to 283
"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.");
Copy link
Contributor

Choose a reason for hiding this comment

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

unrelated no?

@VyacheslavLevytskyy
Copy link
Contributor

VyacheslavLevytskyy commented Apr 2, 2025

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.

@VyacheslavLevytskyy
Copy link
Contributor

Let's add to the discussion more people: @michalpaszkowski @MrSidims @asudarsa

@maarquitos14
Copy link
Contributor Author

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.

I would expect that updating Clang to generate opencl part of the triple for those other projects should suffice. What do you think?

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.

I agree, and similarly, isVulkanEnv() should be renamed to isShader(), I think.

@VyacheslavLevytskyy
Copy link
Contributor

CC: @AlexVlx

@MrSidims MrSidims requested review from bader, svenvh and AlexVlx April 4, 2025 11:07
Copy link
Contributor

@MrSidims MrSidims left a 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(); }
Copy link
Contributor

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:
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:


Environment component also defines 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.

Copy link
Contributor

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(); }
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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.

@maarquitos14 maarquitos14 force-pushed the maronas/use-spirv-friendly-call branch from 11e5b6f to eef5045 Compare April 23, 2025 11:01
@maarquitos14
Copy link
Contributor Author

@Keenuts the new approach I just added makes 58 tests fail. They can all pass if we explicitly pass vulkan in the triple. I didn't look at all of them individually, but took a look at a handful of them and from my POV, there's not enough information to make them work with unknown-unknown triple. In other words, I don't see anything Shader/Vulkan specific in them so that we can infer from the module what's the environment. Therefore, I think the only way to make them pass would be explicitly setting the triple to include vulkan. What do you think? Is that acceptable?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants