[llvm] [SPIR-V] Emit proper pointer type for OpenCL kernel arguments (PR #67726)

Nathan Gauër via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 2 01:31:36 PDT 2023


================
@@ -194,23 +194,39 @@ getKernelArgTypeQual(const Function &KernelFunction, unsigned ArgIdx) {
   return {};
 }
 
-static Type *getArgType(const Function &F, unsigned ArgIdx) {
+static SPIRVType *getArgSPIRVType(const Function &F, unsigned ArgIdx,
+                                  SPIRVGlobalRegistry *GR,
+                                  MachineIRBuilder &MIRBuilder) {
+  // Read argument's access qualifier from metadata or default
+  SPIRV::AccessQualifier::AccessQualifier ArgAccessQual =
+      getArgAccessQual(F, ArgIdx);
+
   Type *OriginalArgType = getOriginalFunctionType(F)->getParamType(ArgIdx);
-  if (F.getCallingConv() != CallingConv::SPIR_KERNEL ||
-      isSpecialOpaqueType(OriginalArgType))
-    return OriginalArgType;
+
+  // In case of non-kernel SPIR-V function, use the original IR type.
+  if (F.getCallingConv() != CallingConv::SPIR_KERNEL)
+    return GR->getOrCreateSPIRVType(OriginalArgType, MIRBuilder, ArgAccessQual);
+
+  // Use original type if it is already TargetExtType of a builtin type.
+  if (isSpecialOpaqueType(OriginalArgType))
+    return GR->getOrCreateSPIRVType(OriginalArgType, MIRBuilder, ArgAccessQual);
 
   MDString *MDKernelArgType =
       getKernelArgAttribute(F, ArgIdx, "kernel_arg_type");
-  if (!MDKernelArgType || !MDKernelArgType->getString().endswith("_t"))
-    return OriginalArgType;
-
-  std::string KernelArgTypeStr = "opencl." + MDKernelArgType->getString().str();
-  Type *ExistingOpaqueType =
-      StructType::getTypeByName(F.getContext(), KernelArgTypeStr);
-  return ExistingOpaqueType
-             ? ExistingOpaqueType
-             : StructType::create(F.getContext(), KernelArgTypeStr);
+  if (!MDKernelArgType || (MDKernelArgType->getString().ends_with("*") &&
----------------
Keenuts wrote:

My main question is why is the pointer type handled by parsing the typename and not using the IR types?
For HLSL specific types, they do the following:

```
%"class.hlsl::RWBuffer" = type { ptr }
```

Then, they can use this type as a normal IR type.
And then, the type can be annotated using LLVM's addresspace notation, and other constructs. For read-only buffers, they mark it as constant for ex.
It seems OpenCL does it using several metadatas like "kernel_arg_addr_space" and "kernel_arg_access_qual".
Is that just for historical reasons, or is there a real benefit in doing this over what HLSL is doing?



https://github.com/llvm/llvm-project/pull/67726


More information about the llvm-commits mailing list