[llvm] [SPIR-V] Do not use OpenCL metadata for ptr element type resolution (PR #82678)

Vyacheslav Levytskyy via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 28 05:34:45 PST 2024


================
@@ -157,28 +159,42 @@ static SPIRVType *getArgSPIRVType(const Function &F, unsigned ArgIdx,
 
   Type *OriginalArgType = getOriginalFunctionType(F)->getParamType(ArgIdx);
 
-  // In case of non-kernel SPIR-V function or already TargetExtType, use the
-  // original IR type.
-  if (F.getCallingConv() != CallingConv::SPIR_KERNEL ||
-      isSpecialOpaqueType(OriginalArgType))
+  // If OriginalArgType is non-pointer, use the OriginalArgType (the type cannot
+  // be legally reassigned later).
+  if (!OriginalArgType->isPointerTy())
     return GR->getOrCreateSPIRVType(OriginalArgType, MIRBuilder, ArgAccessQual);
 
-  SPIRVType *ResArgType = nullptr;
-  if (MDString *MDKernelArgType = getOCLKernelArgType(F, ArgIdx)) {
-    StringRef MDTypeStr = MDKernelArgType->getString();
-    if (MDTypeStr.ends_with("*"))
-      ResArgType = GR->getOrCreateSPIRVTypeByName(
-          MDTypeStr, MIRBuilder,
-          addressSpaceToStorageClass(
-              OriginalArgType->getPointerAddressSpace()));
-    else if (MDTypeStr.ends_with("_t"))
-      ResArgType = GR->getOrCreateSPIRVTypeByName(
-          "opencl." + MDTypeStr.str(), MIRBuilder,
-          SPIRV::StorageClass::Function, ArgAccessQual);
+  // In case OriginalArgType is of pointer type, there are two possibilities:
+  // 1) This is an OpenCL/SPIR-V builtin type if there is spv_assign_type
+  // intrinsic assigning a TargetExtType.
+  // 2) This is a pointer, try to retrieve pointer element type from a
+  // spv_assign_ptr_type intrinsic or otherwise use default pointer element
+  // type.
+  for (auto User : F.getArg(ArgIdx)->users()) {
----------------
VyacheslavLevytskyy wrote:

@michalpaszkowski There is one more very important case. After triaging SYCL E2E tests I've (hopefully) found a way to improve a pass rate by account for function parameter attributes, as in https://llvm.org/docs/LangRef.html#parameter-attributes
Namely, `byval(<ty>)` and `byref(<ty>)` are to help in a very typical SYCL test case of passing data structures into lambda implementing kernel logic.

The simplest test case would be

```
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
target triple = "spir64-unknown-unknown"

%struct.S = type { i32 }
%struct.__wrapper_class = type { [7 x %struct.S] }

define spir_kernel void @foo(ptr noundef byval(%struct.__wrapper_class) align 4 %_arg_Arr) {
entry:
  ret void
}
```

with expected output for the argument of:

```
%ulong = OpTypeInt 64 0
%ulong_7 = OpConstant %ulong 7
%struct_S = OpTypeStruct %uint
%_arr_struct_S_ulong_7 = OpTypeArray %struct_S %ulong_7
%struct___wrapper_class = OpTypeStruct %_arr_struct_S_ulong_7
%_ptr_Function_struct___wrapper_class = OpTypePointer Function %struct___wrapper_class
%_arg_Arr = OpFunctionParameter %_ptr_Function_struct___wrapper_class
```

instead of incorrect current `%_arg_Arr = OpFunctionParameter %_ptr_Function_uchar`.

This can be achieved by enhancing `ElementType` in your patch with byval/byref data type info.

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


More information about the llvm-commits mailing list