From cb1194860dfc16aad525512d94ea6083c8b92c40 Mon Sep 17 00:00:00 2001 From: Elizabeth Andrews Date: Tue, 29 Mar 2022 18:02:25 -0700 Subject: [PATCH] [SYCL] Fix function pointer address space Commits 57fd86de87 (https://reviews.llvm.org/D77119) and 4eaf5846d0 (https://reviews.llvm.org/D111566) set address space of function pointers unconditionally to program address space. A follow-up commit ed5b42b741 (https://reviews.llvm.org/D119045) modified the code to retain explicitly specified address spaces for function pointer. This introduced a regression in cases where function pointers were captured as kernel arguments, since openCL kernel generation sets global address space explicitly to all pointers. This patch reverts the behavior for function pointers captured as kernel arguments. Signed-off-by: Elizabeth Andrews --- clang/lib/Sema/SemaSYCL.cpp | 11 +++++++---- clang/test/CodeGenSYCL/functionptr-addrspace.cpp | 11 +++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) 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; }