diff --git a/clang/lib/CodeGen/CGCUDANV.cpp b/clang/lib/CodeGen/CGCUDANV.cpp index cb16fe1b36c68..a0aeb21bee380 100644 --- a/clang/lib/CodeGen/CGCUDANV.cpp +++ b/clang/lib/CodeGen/CGCUDANV.cpp @@ -327,9 +327,10 @@ void CGNVCUDARuntime::emitDeviceStub(CodeGenFunction &CGF, /// (void*, short, void*) is passed as {void **, short *, void **} to the launch /// function. For the LLVM/offload launch we flatten the arguments into the /// struct directly. In addition, we include the size of the arguments, thus -/// pass {sizeof({void *, short, void *}), ptr to {void *, short, void *}, -/// nullptr}. The last nullptr needs to be initialized to an array of pointers -/// pointing to the arguments if we want to offload to the host. +/// pass {size of ({void *, short, void *}) without tail padding, ptr to {void +/// *, short, void *}, nullptr}. The last nullptr needs to be initialized to an +/// array of pointers pointing to the arguments if we want to offload to the +/// host. Address CGNVCUDARuntime::prepareKernelArgsLLVMOffload(CodeGenFunction &CGF, FunctionArgList &Args) { SmallVector ArgTypes, KernelLaunchParamsTypes; @@ -350,7 +351,15 @@ Address CGNVCUDARuntime::prepareKernelArgsLLVMOffload(CodeGenFunction &CGF, KernelLaunchParamsTy, CharUnits::fromQuantity(16), "kernel_launch_params"); - auto KernelArgsSize = CGM.getDataLayout().getTypeAllocSize(KernelArgsTy); + // Avoid accounting the tail padding for the kernel arguments. + auto KernelArgsSize = llvm::TypeSize::getZero(); + if (auto N = KernelArgsTy->getNumElements()) { + auto *SL = CGM.getDataLayout().getStructLayout(KernelArgsTy); + KernelArgsSize += SL->getElementOffset(N - 1); + KernelArgsSize += CGM.getDataLayout().getTypeAllocSize( + KernelArgsTy->getElementType(N - 1)); + } + CGF.Builder.CreateStore(llvm::ConstantInt::get(Int64Ty, KernelArgsSize), CGF.Builder.CreateStructGEP(KernelLaunchParams, 0)); CGF.Builder.CreateStore(KernelArgs.emitRawPointer(CGF), diff --git a/offload/include/Shared/APITypes.h b/offload/include/Shared/APITypes.h index 8c150b6bfc2d4..9868370de3d73 100644 --- a/offload/include/Shared/APITypes.h +++ b/offload/include/Shared/APITypes.h @@ -119,7 +119,7 @@ static_assert(sizeof(KernelArgsTy) == /// Flat array of kernel launch parameters and their total size. struct KernelLaunchParamsTy { - /// Size of the Data array. + /// Size of the Data array without the tail padding. size_t Size = 0; /// Flat array of kernel parameters. void *Data = nullptr; diff --git a/offload/plugins-nextgen/amdgpu/src/rtl.cpp b/offload/plugins-nextgen/amdgpu/src/rtl.cpp index 64470e9fabf46..dc0e5c3ba11ef 100644 --- a/offload/plugins-nextgen/amdgpu/src/rtl.cpp +++ b/offload/plugins-nextgen/amdgpu/src/rtl.cpp @@ -3658,11 +3658,6 @@ Error AMDGPUKernelTy::launchImpl(GenericDeviceTy &GenericDevice, KernelArgsTy &KernelArgs, KernelLaunchParamsTy LaunchParams, AsyncInfoWrapperTy &AsyncInfoWrapper) const { - if (ArgsSize != LaunchParams.Size && - ArgsSize > LaunchParams.Size + getImplicitArgsSize()) - return Plugin::error(ErrorCode::INVALID_ARGUMENT, - "invalid kernel arguments size"); - AMDGPUPluginTy &AMDGPUPlugin = static_cast(GenericDevice.Plugin); AMDHostDeviceTy &HostDevice = AMDGPUPlugin.getHostDevice(); diff --git a/offload/plugins-nextgen/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp index 7d05dd25dbf75..56006d03ef325 100644 --- a/offload/plugins-nextgen/common/src/PluginInterface.cpp +++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp @@ -571,7 +571,9 @@ KernelLaunchParamsTy GenericKernelTy::prepareArgs( (void *)((intptr_t)ArgPtrs[I - KLEOffset] + ArgOffsets[I - KLEOffset]); Ptrs[I] = &Args[I]; } - return KernelLaunchParamsTy{sizeof(void *) * NumArgs, &Args[0], &Ptrs[0]}; + + size_t ArgsSize = sizeof(void *) * NumArgs; + return KernelLaunchParamsTy{ArgsSize, &Args[0], &Ptrs[0]}; } uint32_t GenericKernelTy::getNumThreads(GenericDeviceTy &GenericDevice, diff --git a/offload/test/offloading/CUDA/basic_launch_multi_arg.cu b/offload/test/offloading/CUDA/basic_launch_multi_arg.cu index 1f84a0e1288d4..ab6f753150932 100644 --- a/offload/test/offloading/CUDA/basic_launch_multi_arg.cu +++ b/offload/test/offloading/CUDA/basic_launch_multi_arg.cu @@ -23,6 +23,10 @@ __global__ void square(int *Dst, short Q, int *Src, short P) { Src[1] = P; } +__global__ void accumulate(short Q, int *Dst, char P) { + *Dst += Q + P; +} + int main(int argc, char **argv) { int DevNo = 0; int *Ptr = reinterpret_cast(llvm_omp_target_alloc_shared(4, DevNo)); @@ -39,5 +43,9 @@ int main(int argc, char **argv) { // CHECK: Ptr [[Ptr]], *Ptr: 42 printf("Src: %i : %i\n", Src[0], Src[1]); // CHECK: Src: 3 : 4 + accumulate<<<1, 1>>>(3, Ptr, 7); + printf("Ptr %p, *Ptr: %i\n", Ptr, *Ptr); + // CHECK: Ptr [[Ptr]], *Ptr: 52 llvm_omp_target_free_shared(Ptr, DevNo); + llvm_omp_target_free_shared(Src, DevNo); }