[clang] e994e74 - [OpenCL] Add clang extension for non-portable kernel parameters.
Tom Stellard via cfe-commits
cfe-commits at lists.llvm.org
Mon May 10 22:15:57 PDT 2021
On 5/5/21 6:58 AM, Anastasia Stulova via cfe-commits wrote:
>
> Author: Anastasia Stulova
> Date: 2021-05-05T14:58:23+01:00
> New Revision: e994e74bca49831eb649e7c67955e9de7a1784b6
>
> URL: https://github.com/llvm/llvm-project/commit/e994e74bca49831eb649e7c67955e9de7a1784b6
> DIFF: https://github.com/llvm/llvm-project/commit/e994e74bca49831eb649e7c67955e9de7a1784b6.diff
>
> LOG: [OpenCL] Add clang extension for non-portable kernel parameters.
>
> Added __cl_clang_non_portable_kernel_param_types extension that
> allows using non-portable types as kernel parameters. This allows
> bypassing the portability guarantees from the restrictions specified
> in C++ for OpenCL v1.0 s2.4.
>
> Currently this only disables the restrictions related to the data
> layout. The programmer should ensure the compiler generates the same
> layout for host and device or otherwise the argument should only be
> accessed on the device side. This extension could be extended to other
> case (e.g. permitting size_t) if desired in the future.
>
> Patch by olestrohm (Ole Strohm)!
>
Hi Anastasia,
This change broke the clang-sphinx-docs builder:
https://lab.llvm.org/buildbot/#/builders/92/builds/9110
-Tom
> https://reviews.llvm.org/D101168
>
> Added:
>
>
> Modified:
> clang/docs/LanguageExtensions.rst
> clang/include/clang/Basic/OpenCLExtensions.def
> clang/lib/Basic/Targets/AMDGPU.h
> clang/lib/Basic/Targets/NVPTX.h
> clang/lib/Sema/SemaDecl.cpp
> clang/test/Misc/amdgcn.languageOptsOpenCL.cl
> clang/test/Misc/nvptx.languageOptsOpenCL.cl
> clang/test/Misc/r600.languageOptsOpenCL.cl
> clang/test/SemaOpenCLCXX/invalid-kernel.clcpp
>
> Removed:
>
>
>
> ################################################################################
> diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
> index 5e5382879e0c8..bdb5b3adf39fb 100644
> --- a/clang/docs/LanguageExtensions.rst
> +++ b/clang/docs/LanguageExtensions.rst
> @@ -1813,6 +1813,54 @@ supporting the variadic arguments e.g. majority of CPU targets.
> #pragma OPENCL EXTENSION __cl_clang_variadic_functions : disable
> void bar(int a, ...); // error - variadic prototype is not allowed
>
> +``__cl_clang_non_portable_kernel_param_types``
> +---------------------------------------------
> +
> +With this extension it is possible to enable the use of some restricted types
> +in kernel parameters specified in `C++ for OpenCL v1.0 s2.4
> +<https://www.khronos.org/opencl/assets/CXX_for_OpenCL.html#kernel_function>`_.
> +The restrictions can be relaxed using regular OpenCL extension pragma mechanism
> +detailed in `the OpenCL Extension Specification, section 1.2
> +<https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_Ext.html#extensions-overview>`_.
> +
> +This is not a conformant behavior and it can only be used when the
> +kernel arguments are not accessed on the host side or the data layout/size
> +between the host and device is known to be compatible.
> +
> +**Example of Use**:
> +
> +.. code-block:: c++
> +
> + // Plain Old Data type.
> + struct Pod {
> + int a;
> + int b;
> + };
> +
> + // Not POD type because of the constructor.
> + // Standard layout type because there is only one access control.
> + struct OnlySL {
> + int a;
> + int b;
> + NotPod() : a(0), b(0) {}
> + };
> +
> + // Not standard layout type because of two
> diff erent access controls.
> + struct NotSL {
> + int a;
> + private:
> + int b;
> + }
> +
> + kernel void kernel_main(
> + Pod a,
> + #pragma OPENCL EXTENSION __cl_clang_non_portable_kernel_param_types : enable
> + OnlySL b,
> + global NotSL *c,
> + #pragma OPENCL EXTENSION __cl_clang_non_portable_kernel_param_types : disable
> + global OnlySL *d,
> + );
> +
> Legacy 1.x atomics with generic address space
> ---------------------------------------------
>
>
> diff --git a/clang/include/clang/Basic/OpenCLExtensions.def b/clang/include/clang/Basic/OpenCLExtensions.def
> index 5e2977f478f3a..a0f01a2af9c37 100644
> --- a/clang/include/clang/Basic/OpenCLExtensions.def
> +++ b/clang/include/clang/Basic/OpenCLExtensions.def
> @@ -87,6 +87,7 @@ OPENCL_EXTENSION(cl_khr_subgroups, true, 200)
> OPENCL_EXTENSION(cl_clang_storage_class_specifiers, true, 100)
> OPENCL_EXTENSION(__cl_clang_function_pointers, true, 100)
> OPENCL_EXTENSION(__cl_clang_variadic_functions, true, 100)
> +OPENCL_EXTENSION(__cl_clang_non_portable_kernel_param_types, true, 100)
>
> // AMD OpenCL extensions
> OPENCL_EXTENSION(cl_amd_media_ops, true, 100)
>
> diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h
> index 8ee0ca30d305d..b2d422ce0bbe9 100644
> --- a/clang/lib/Basic/Targets/AMDGPU.h
> +++ b/clang/lib/Basic/Targets/AMDGPU.h
> @@ -287,6 +287,7 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
> Opts["cl_clang_storage_class_specifiers"] = true;
> Opts["__cl_clang_variadic_functions"] = true;
> Opts["__cl_clang_function_pointers"] = true;
> + Opts["__cl_clang_non_portable_kernel_param_types"] = true;
>
> bool IsAMDGCN = isAMDGCN(getTriple());
>
>
> diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h
> index 9e80473df9e00..b7b0aae65819d 100644
> --- a/clang/lib/Basic/Targets/NVPTX.h
> +++ b/clang/lib/Basic/Targets/NVPTX.h
> @@ -133,6 +133,7 @@ class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo {
> Opts["cl_clang_storage_class_specifiers"] = true;
> Opts["__cl_clang_function_pointers"] = true;
> Opts["__cl_clang_variadic_functions"] = true;
> + Opts["__cl_clang_non_portable_kernel_param_types"] = true;
>
> Opts["cl_khr_fp64"] = true;
> Opts["cl_khr_byte_addressable_store"] = true;
>
> diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
> index 1abb692413b9d..c1aa638369383 100644
> --- a/clang/lib/Sema/SemaDecl.cpp
> +++ b/clang/lib/Sema/SemaDecl.cpp
> @@ -8662,6 +8662,9 @@ static bool isOpenCLSizeDependentType(ASTContext &C, QualType Ty) {
> }
>
> static OpenCLParamType getOpenCLKernelParameterType(Sema &S, QualType PT) {
> + if (PT->isDependentType())
> + return InvalidKernelParam;
> +
> if (PT->isPointerType() || PT->isReferenceType()) {
> QualType PointeeType = PT->getPointeeType();
> if (PointeeType.getAddressSpace() == LangAS::opencl_generic ||
> @@ -8684,8 +8687,11 @@ static OpenCLParamType getOpenCLKernelParameterType(Sema &S, QualType PT) {
> // Moreover the types used in parameters of the kernel functions must be:
> // Standard layout types for pointer parameters. The same applies to
> // reference if an implementation supports them in kernel parameters.
> - if (S.getLangOpts().OpenCLCPlusPlus && !PointeeType->isAtomicType() &&
> - !PointeeType->isVoidType() && !PointeeType->isStandardLayoutType())
> + if (S.getLangOpts().OpenCLCPlusPlus &&
> + !S.getOpenCLOptions().isAvailableOption(
> + "__cl_clang_non_portable_kernel_param_types", S.getLangOpts()) &&
> + !PointeeType->isAtomicType() && !PointeeType->isVoidType() &&
> + !PointeeType->isStandardLayoutType())
> return InvalidKernelParam;
>
> return PtrKernelParam;
> @@ -8725,8 +8731,10 @@ static OpenCLParamType getOpenCLKernelParameterType(Sema &S, QualType PT) {
> // Moreover the types used in parameters of the kernel functions must be:
> // Trivial and standard-layout types C++17 [basic.types] (plain old data
> // types) for parameters passed by value;
> - if (S.getLangOpts().OpenCLCPlusPlus && !PT->isOpenCLSpecificType() &&
> - !PT.isPODType(S.Context))
> + if (S.getLangOpts().OpenCLCPlusPlus &&
> + !S.getOpenCLOptions().isAvailableOption(
> + "__cl_clang_non_portable_kernel_param_types", S.getLangOpts()) &&
> + !PT->isOpenCLSpecificType() && !PT.isPODType(S.Context))
> return InvalidKernelParam;
>
> if (PT->isRecordType())
>
> diff --git a/clang/test/Misc/amdgcn.languageOptsOpenCL.cl b/clang/test/Misc/amdgcn.languageOptsOpenCL.cl
> index 1dd31029d7349..7fc4e7ea005e7 100644
> --- a/clang/test/Misc/amdgcn.languageOptsOpenCL.cl
> +++ b/clang/test/Misc/amdgcn.languageOptsOpenCL.cl
> @@ -24,6 +24,11 @@
> #endif
> #pragma OPENCL EXTENSION __cl_clang_variadic_functions : enable
>
> +#ifndef __cl_clang_non_portable_kernel_param_types
> +#error "Missing __cl_clang_non_portable_kernel_param_types define"
> +#endif
> +#pragma OPENCL EXTENSION __cl_clang_non_portable_kernel_param_types : enable
> +
> #ifndef cl_khr_fp16
> #error "Missing cl_khr_fp16 define"
> #endif
>
> diff --git a/clang/test/Misc/nvptx.languageOptsOpenCL.cl b/clang/test/Misc/nvptx.languageOptsOpenCL.cl
> index d547f4d2acfd3..6657c18f1eebe 100644
> --- a/clang/test/Misc/nvptx.languageOptsOpenCL.cl
> +++ b/clang/test/Misc/nvptx.languageOptsOpenCL.cl
> @@ -28,6 +28,11 @@
> #endif
> #pragma OPENCL EXTENSION __cl_clang_variadic_functions : enable
>
> +#ifndef __cl_clang_non_portable_kernel_param_types
> +#error "Missing __cl_clang_non_portable_kernel_param_types define"
> +#endif
> +#pragma OPENCL EXTENSION __cl_clang_non_portable_kernel_param_types : enable
> +
> #ifdef cl_khr_fp16
> #error "Incorrect cl_khr_fp16 define"
> #endif
>
> diff --git a/clang/test/Misc/r600.languageOptsOpenCL.cl b/clang/test/Misc/r600.languageOptsOpenCL.cl
> index 2c87370f9d5fe..80c628af03608 100644
> --- a/clang/test/Misc/r600.languageOptsOpenCL.cl
> +++ b/clang/test/Misc/r600.languageOptsOpenCL.cl
> @@ -34,6 +34,11 @@
> #endif
> #pragma OPENCL EXTENSION __cl_clang_variadic_functions : enable
>
> +#ifndef __cl_clang_non_portable_kernel_param_types
> +#error "Missing __cl_clang_non_portable_kernel_param_types define"
> +#endif
> +#pragma OPENCL EXTENSION __cl_clang_non_portable_kernel_param_types : enable
> +
> #ifdef cl_khr_fp16
> #error "Incorrect cl_khr_fp16 define"
> #endif
>
> diff --git a/clang/test/SemaOpenCLCXX/invalid-kernel.clcpp b/clang/test/SemaOpenCLCXX/invalid-kernel.clcpp
> index 977d487928b65..9bd147364483c 100644
> --- a/clang/test/SemaOpenCLCXX/invalid-kernel.clcpp
> +++ b/clang/test/SemaOpenCLCXX/invalid-kernel.clcpp
> @@ -1,4 +1,9 @@
> -// RUN: %clang_cc1 %s -pedantic -verify -fsyntax-only
> +// RUN: %clang_cc1 %s -pedantic -verify -fsyntax-only -triple spir-unknown-unknown
> +// RUN: %clang_cc1 %s -pedantic -verify -fsyntax-only -triple spir-unknown-unknown -DUNSAFEKERNELPARAMETER
> +
> +#ifdef UNSAFEKERNELPARAMETER
> +#pragma OPENCL EXTENSION __cl_clang_non_portable_kernel_param_types : enable
> +#endif
>
> struct C {
> kernel void m(); //expected-error{{kernel functions cannot be class members}}
> @@ -24,8 +29,10 @@ kernel void int_p_p(__global int *__global *in);
> kernel void int_p_r(__global int *__global &in);
> kernel void int_p_p_r(__global int *__global *__global &in);
>
> -// expected-error at +1{{'__private atomic_int' (aka '__private _Atomic(int)') cannot be used as the type of a kernel parameter}}
> kernel void k_atomic_v(atomic_int in);
> +#ifndef UNSAFEKERNELPARAMETER
> +// expected-error at -2{{'__private atomic_int' (aka '__private _Atomic(int)') cannot be used as the type of a kernel parameter}}
> +#endif
> kernel void k_atomic_p(__global atomic_int *in);
> kernel void k_atomic_r(__global atomic_int &in);
>
> @@ -56,7 +63,10 @@ struct StandardLayout {
> StandardLayout(int a, int b) : a(a), b(b) {}
> };
>
> -kernel void standard_v(StandardLayout in) {} //expected-error{{'__private StandardLayout' cannot be used as the type of a kernel parameter}}
> +kernel void standard_v(StandardLayout in) {}
> +#ifndef UNSAFEKERNELPARAMETER
> +//expected-error at -2{{'__private StandardLayout' cannot be used as the type of a kernel parameter}}
> +#endif
> kernel void standard_p(__global StandardLayout *in) {}
> kernel void standard_p_p(__global StandardLayout *__global *in) {}
> kernel void standard_r(__global StandardLayout &in) {}
> @@ -67,7 +77,19 @@ private:
> int b;
> };
>
> -kernel void trivial_v(Trivial in) {} //expected-error{{'__private Trivial' cannot be used as the type of a kernel parameter}}
> -kernel void trivial_p(__global Trivial *in) {} //expected-error{{'__global Trivial *__private' cannot be used as the type of a kernel parameter}}
> -kernel void trivial_p_p(__global Trivial *__global *in) {} //expected-error{{'__global Trivial *__global *__private' cannot be used as the type of a kernel parameter}}
> -kernel void trivial_r(__global Trivial &in) {} //expected-error{{'__global Trivial &__private' cannot be used as the type of a kernel parameter}}
> +kernel void trivial_v(Trivial in) {}
> +#ifndef UNSAFEKERNELPARAMETER
> +//expected-error at -2{{'__private Trivial' cannot be used as the type of a kernel parameter}}
> +#endif
> +kernel void trivial_p(__global Trivial *in) {}
> +#ifndef UNSAFEKERNELPARAMETER
> +//expected-error at -2{{'__global Trivial *__private' cannot be used as the type of a kernel parameter}}
> +#endif
> +kernel void trivial_p_p(__global Trivial *__global *in) {}
> +#ifndef UNSAFEKERNELPARAMETER
> +//expected-error at -2{{'__global Trivial *__global *__private' cannot be used as the type of a kernel parameter}}
> +#endif
> +kernel void trivial_r(__global Trivial &in) {}
> +#ifndef UNSAFEKERNELPARAMETER
> +//expected-error at -2{{'__global Trivial &__private' cannot be used as the type of a kernel parameter}}
> +#endif
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
More information about the cfe-commits
mailing list