diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 9b4254f2c1dc4..4cc60f53226ed 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5524,7 +5524,11 @@ def fsycl_int_header_EQ : Joined<["-"], "fsycl-int-header=">, def fsycl_std_layout_kernel_params: Flag<["-"], "fsycl-std-layout-kernel-params">, HelpText<"Enable standard layout requirement for SYCL kernel parameters.">, MarshallingInfoFlag>; -defm sycl_allow_func_ptr: OptInFFlag<"sycl-allow-func-ptr", "Allow", "Disallow", " function pointers in SYCL device.", [CC1Option,CoreOption], LangOpts<"SYCLAllowFuncPtr">>; +defm sycl_allow_func_ptr: BoolFOption<"sycl-allow-func-ptr", + LangOpts<"SYCLAllowFuncPtr">, DefaultFalse, + PosFlag, + NegFlag, + BothFlags<[CC1Option, CoreOption], " function pointers in SYCL device.">>; def fenable_sycl_dae : Flag<["-"], "fenable-sycl-dae">, HelpText<"Enable Dead Argument Elimination in SPIR kernels">, MarshallingInfoFlag>; diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 8e758730d3309..88866c304fe4a 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -4774,9 +4774,14 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, // If the argument doesn't match, perform a bitcast to coerce it. This // can happen due to trivial type mismatches. if (FirstIRArg < IRFuncTy->getNumParams() && - V->getType() != IRFuncTy->getParamType(FirstIRArg)) - V = Builder.CreateBitCast(V, IRFuncTy->getParamType(FirstIRArg)); - + V->getType() != IRFuncTy->getParamType(FirstIRArg)) { + if (V->getType()->getPointerAddressSpace() != + IRFuncTy->getParamType(FirstIRArg)->getPointerAddressSpace()) + V = Builder.CreateAddrSpaceCast(V, + IRFuncTy->getParamType(FirstIRArg)); + else + V = Builder.CreateBitCast(V, IRFuncTy->getParamType(FirstIRArg)); + } IRCallArgs[FirstIRArg] = V; break; } diff --git a/clang/test/CodeGenSYCL/invoke-function-addrspace.cpp b/clang/test/CodeGenSYCL/invoke-function-addrspace.cpp new file mode 100644 index 0000000000000..29f20f6ccf866 --- /dev/null +++ b/clang/test/CodeGenSYCL/invoke-function-addrspace.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -sycl-std=2020 -fsycl-is-device -fsycl-allow-func-ptr -internal-isystem %S/Inputs -disable-llvm-passes -triple spir64-unknown-unknown-sycldevice -emit-llvm -o - %s | FileCheck %s + +// Test that the type of function object invoked from the kernel has +// the right address space. + +#include "sycl.hpp" + +using namespace cl::sycl; +queue q; + +// CHECK: define linkonce_odr spir_func i32 @{{.*}}invoke_function{{.*}}(i32 () addrspace(4)* %f) +template +auto invoke_function(Callable &&f) { + // CHECK: %f.addr = alloca i32 () addrspace(4)*, align 8 + // CHECK: %f.addr.ascast = addrspacecast i32 () addrspace(4)** %f.addr to i32 () addrspace(4)* addrspace(4)* + // CHECK: store i32 () addrspace(4)* %f, i32 () addrspace(4)* addrspace(4)* %f.addr.ascast, align 8 + // CHECK: %0 = load i32 () addrspace(4)*, i32 () addrspace(4)* addrspace(4)* %f.addr.ascast, align 8 + // CHECK: %call = call spir_func addrspace(4) i32 %0() + return f(); +} + +// CHECK: define dso_local spir_func i32 @{{.*}}bar10{{.*}}() +int bar10() { return 10; } + +int main() { + kernel_single_task( + [=]() { + invoke_function(bar10); + }); + return 0; +}