diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp index fac53fcfbf94a..01e741fbfc713 100644 --- a/clang/lib/Sema/SemaSYCL.cpp +++ b/clang/lib/Sema/SemaSYCL.cpp @@ -2158,15 +2158,18 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler { bool handlePointerType(FieldDecl *FD, QualType FieldTy) final { // USM allows to use raw pointers instead of buffers/accessors, but these - // pointers point to the specially allocated memory. For pointer fields we - // add a kernel argument with the same type as field but global address - // space, because OpenCL requires it. + // pointers point to the specially allocated memory. For pointer fields, + // except for function pointer fields, we add a kernel argument with the + // same type as field but global address space, because OpenCL requires it. + // Function pointers should have program address space. This is set in + // CodeGen. QualType PointeeTy = FieldTy->getPointeeType(); Qualifiers Quals = PointeeTy.getQualifiers(); auto AS = Quals.getAddressSpace(); // Leave global_device and global_host address spaces as is to help FPGA // device in memory allocations - if (AS != LangAS::sycl_global_device && AS != LangAS::sycl_global_host) + if (!PointeeTy->isFunctionType() && AS != LangAS::sycl_global_device && + AS != LangAS::sycl_global_host) Quals.setAddressSpace(LangAS::sycl_global); PointeeTy = SemaRef.getASTContext().getQualifiedType( PointeeTy.getUnqualifiedType(), Quals); diff --git a/clang/test/CodeGenSYCL/functionptr-addrspace.cpp b/clang/test/CodeGenSYCL/functionptr-addrspace.cpp index 9801af10041f6..fd5b4e3963fdb 100644 --- a/clang/test/CodeGenSYCL/functionptr-addrspace.cpp +++ b/clang/test/CodeGenSYCL/functionptr-addrspace.cpp @@ -21,5 +21,16 @@ int main() { invoke_function(r, &a); invoke_function(f, &a); }); + + // Test function pointer as kernel argument. Function pointers should have program address space i.e. 0. + + int (*fptr)(); + int *ptr; + + // define dso_local spir_kernel void @{{.*}}fake_kernel_2{{.*}}(i32 ()* align 4 %_arg_fptr, i32 addrspace(1)* align 4 %_arg_ptr) + kernel_single_task([=]() { + invoke_function(fptr, ptr); + }); + return 0; }