Index: clang/lib/Sema/OpenCLBuiltins.td =================================================================== --- clang/lib/Sema/OpenCLBuiltins.td +++ clang/lib/Sema/OpenCLBuiltins.td @@ -20,12 +20,13 @@ //===----------------------------------------------------------------------===// // Versions of OpenCL class Version { - int Version = _Version; + int Name = _Version; } -def CL10: Version<100>; -def CL11: Version<110>; -def CL12: Version<120>; -def CL20: Version<200>; +def CLAll : Version<000>; +def CL10 : Version<100>; +def CL11 : Version<110>; +def CL12 : Version<120>; +def CL20 : Version<200>; // Address spaces // Pointer types need to be assigned an address space. @@ -179,8 +180,13 @@ list Signature = _Signature; // OpenCL Extension to which the function belongs (cl_khr_subgroups, ...) string Extension = ""; - // OpenCL Version to which the function belongs (CL10, ...) - Version Version = CL10; + // Version of OpenCL from which the function is available (e.g.: CL10). + // MinVersion is inclusive. + Version MinVersion = CL10; + // Version of OpenCL from which the function is not supported anymore. + // MaxVersion is exclusive. + // CLAll makes the function available for all versions. + Version MaxVersion = CLAll; } //===----------------------------------------------------------------------===// @@ -285,6 +291,137 @@ } } +//-------------------------------------------------------------------- +// OpenCL v1.1 s6.11.1, v1.2 s6.12.1, v2.0 s6.13.1 - Work-item Functions +// --- Table 7 --- +def : Builtin<"get_work_dim", [UInt]>; +foreach name = ["get_global_size", "get_global_id", "get_local_size", + "get_local_id", "get_num_groups", "get_group_id", + "get_global_offset"] in { + def : Builtin; +} + +let MinVersion = CL20 in { + def : Builtin<"get_enqueued_local_size", [Size, UInt]>; + foreach name = ["get_global_linear_id", "get_local_linear_id"] in { + def : Builtin; + } +} + +//-------------------------------------------------------------------- +// OpenCL v1.1 s6.11.7, v1.2 s6.12.7, v2.0 s6.13.7 - Vector Data Load and Store Functions +// OpenCL Extension v1.1 s9.3.6 and s9.6.6, v1.2 s9.5.6, v2.0 s9.4.6, v2.0 s5.1.6 and 6.1.6 - Vector Data Load and Store Functions +// --- Table 15 --- +// --- 3 arguments --- +// Variants for OpenCL versions below 2.0, using pointers to the global, local +// and private address spaces +let MaxVersion = CL20 in { + foreach AS = [GlobalAS, LocalAS, PrivateAS] in { + foreach VSize = [2, 3, 4, 8, 16] in { + foreach name = ["vload"#VSize] in { + def : Builtin, Size, PointerType, AS>]>; + def : Builtin, Size, PointerType, AS>]>; + def : Builtin, Size, PointerType, AS>]>; + def : Builtin, Size, PointerType, AS>]>; + def : Builtin, Size, PointerType, AS>]>; + def : Builtin, Size, PointerType, AS>]>; + def : Builtin, Size, PointerType, AS>]>; + def : Builtin, Size, PointerType, AS>]>; + def : Builtin, Size, PointerType, AS>]>; + def : Builtin, Size, PointerType, AS>]>; + def : Builtin, Size, PointerType, AS>]>; + } + foreach name = ["vstore"#VSize] in { + def : Builtin, Size, PointerType, AS>]>; + def : Builtin, Size, PointerType, AS>]>; + def : Builtin, Size, PointerType, AS>]>; + def : Builtin, Size, PointerType, AS>]>; + def : Builtin, Size, PointerType, AS>]>; + def : Builtin, Size, PointerType, AS>]>; + def : Builtin, Size, PointerType, AS>]>; + def : Builtin, Size, PointerType, AS>]>; + def : Builtin, Size, PointerType, AS>]>; + def : Builtin, Size, PointerType, AS>]>; + def : Builtin, Size, PointerType, AS>]>; + } + foreach name = ["vloada_half"#VSize] in { + def : Builtin, Size, PointerType, AS>]>; + } + foreach rnd = ["", "_rte", "_rtz", "_rtp", "_rtn"] in { + foreach name = ["vstorea_half"#VSize#rnd] in { + def : Builtin, Size, PointerType]>; + def : Builtin, Size, PointerType]>; + } + } + } + } +} +// Variants for OpenCL versions above 2.0, using pointers to the generic +// address space +let MinVersion = CL20 in { + foreach VSize = [2, 3, 4, 8, 16] in { + foreach name = ["vload"#VSize] in { + def : Builtin, Size, PointerType, GenericAS>]>; + def : Builtin, Size, PointerType, GenericAS>]>; + def : Builtin, Size, PointerType, GenericAS>]>; + def : Builtin, Size, PointerType, GenericAS>]>; + def : Builtin, Size, PointerType, GenericAS>]>; + def : Builtin, Size, PointerType, GenericAS>]>; + def : Builtin, Size, PointerType, GenericAS>]>; + def : Builtin, Size, PointerType, GenericAS>]>; + def : Builtin, Size, PointerType, GenericAS>]>; + def : Builtin, Size, PointerType, GenericAS>]>; + def : Builtin, Size, PointerType, GenericAS>]>; + } + foreach name = ["vstore"#VSize] in { + def : Builtin, Size, PointerType, GenericAS>]>; + def : Builtin, Size, PointerType, GenericAS>]>; + def : Builtin, Size, PointerType, GenericAS>]>; + def : Builtin, Size, PointerType, GenericAS>]>; + def : Builtin, Size, PointerType, GenericAS>]>; + def : Builtin, Size, PointerType, GenericAS>]>; + def : Builtin, Size, PointerType, GenericAS>]>; + def : Builtin, Size, PointerType, GenericAS>]>; + def : Builtin, Size, PointerType, GenericAS>]>; + def : Builtin, Size, PointerType, GenericAS>]>; + def : Builtin, Size, PointerType, GenericAS>]>; + } + foreach name = ["vloada_half"#VSize] in { + def : Builtin, Size, PointerType, GenericAS>]>; + } + foreach rnd = ["", "_rte", "_rtz", "_rtp", "_rtn"] in { + foreach name = ["vstorea_half"#VSize#rnd] in { + def : Builtin, Size, PointerType]>; + def : Builtin, Size, PointerType]>; + } + } + } +} +// Variants using pointers to the constant address space +foreach VSize = [2, 3, 4, 8, 16] in { + foreach name = ["vload"#VSize] in { + def : Builtin, Size, PointerType, ConstantAS>]>; + def : Builtin, Size, PointerType, ConstantAS>]>; + def : Builtin, Size, PointerType, ConstantAS>]>; + def : Builtin, Size, PointerType, ConstantAS>]>; + def : Builtin, Size, PointerType, ConstantAS>]>; + def : Builtin, Size, PointerType, ConstantAS>]>; + def : Builtin, Size, PointerType, ConstantAS>]>; + def : Builtin, Size, PointerType, ConstantAS>]>; + def : Builtin, Size, PointerType, ConstantAS>]>; + def : Builtin, Size, PointerType, ConstantAS>]>; + def : Builtin, Size, PointerType, ConstantAS>]>; + } + foreach name = ["vloada_half"#VSize] in { + def : Builtin, Size, PointerType, ConstantAS>]>; + } + foreach rnd = ["", "_rte", "_rtz", "_rtp", "_rtn"] in { + foreach name = ["vstorea_half"#VSize#rnd] in { + def : Builtin, Size, PointerType]>; + def : Builtin, Size, PointerType]>; + } + } +} //-------------------------------------------------------------------- // OpenCL v2.0 s6.13.11 - Atomics Functions. @@ -306,14 +443,6 @@ } -// OpenCL v1.2 s6.12.1: Work-Item Functions -def get_work_dim : Builtin<"get_work_dim", [UInt]>; -foreach name = ["get_global_size", "get_global_id", "get_local_size", - "get_local_id", "get_num_groups", "get_group_id", - "get_global_offset"] in { - def : Builtin; -} - // OpenCL v1.2 s6.12.2: Math Functions foreach name = ["acos", "acosh", "acospi", "asin", "asinh", "asinpi", @@ -377,14 +506,3 @@ def : Builtin, VectorType, VectorType]>; } } - - - -// OpenCL v2.0 s9.17.3: Additions to section 6.13.1: Work-Item Functions -let Version = CL20 in { - let Extension = "cl_khr_subgroups" in { - def get_sub_group_size : Builtin<"get_sub_group_size", [UInt]>; - def get_max_sub_group_size : Builtin<"get_max_sub_group_size", [UInt]>; - def get_num_sub_groups : Builtin<"get_num_sub_groups", [UInt]>; - } -} Index: clang/lib/Sema/SemaLookup.cpp =================================================================== --- clang/lib/Sema/SemaLookup.cpp +++ clang/lib/Sema/SemaLookup.cpp @@ -798,6 +798,13 @@ BuiltinTable[FctIndex + SignatureIndex]; ASTContext &Context = S.Context; + // Ignore this BIF if the version is incorrect. + if (Context.getLangOpts().OpenCLVersion < OpenCLBuiltin.MinVersion) + continue; + if ((OpenCLBuiltin.MaxVersion != 0) && + (Context.getLangOpts().OpenCLVersion >= OpenCLBuiltin.MaxVersion)) + continue; + std::vector RetTypes; SmallVector, 5> ArgTypes; Index: clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl =================================================================== --- clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl +++ clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl @@ -1,10 +1,20 @@ +// RUN: %clang_cc1 %s -triple spir -verify -pedantic -fsyntax-only -cl-std=CL -fdeclare-opencl-builtins -DNO_HEADER +// RUN: %clang_cc1 %s -triple spir -verify -pedantic -fsyntax-only -cl-std=CL -fdeclare-opencl-builtins -finclude-default-header +// RUN: %clang_cc1 %s -triple spir -verify -pedantic -fsyntax-only -cl-std=CL1.2 -fdeclare-opencl-builtins -DNO_HEADER +// RUN: %clang_cc1 %s -triple spir -verify -pedantic -fsyntax-only -cl-std=CL1.2 -fdeclare-opencl-builtins -finclude-default-header // RUN: %clang_cc1 %s -triple spir -verify -pedantic -fsyntax-only -cl-std=CL2.0 -fdeclare-opencl-builtins -DNO_HEADER // RUN: %clang_cc1 %s -triple spir -verify -pedantic -fsyntax-only -cl-std=CL2.0 -fdeclare-opencl-builtins -finclude-default-header + +#if __OPENCL_C_VERSION__ >= CL_VERSION_2_0 // expected-no-diagnostics +#endif // Test the -fdeclare-opencl-builtins option. #pragma OPENCL EXTENSION cl_khr_fp16 : enable +#if __OPENCL_C_VERSION__ < CL_VERSION_1_2 +#pragma OPENCL EXTENSION cl_khr_fp64 : enable +#endif // Provide typedefs when invoking clang without -finclude-default-header. #ifdef NO_HEADER @@ -14,7 +24,10 @@ typedef int int2 __attribute__((ext_vector_type(2))); typedef int int4 __attribute__((ext_vector_type(4))); typedef long long2 __attribute__((ext_vector_type(2))); +typedef unsigned char uchar; typedef unsigned int uint; +typedef unsigned long ulong; +typedef unsigned short ushort; typedef __SIZE_TYPE__ size_t; #endif @@ -49,12 +62,14 @@ read_imageh(image_read_only_image2d, sampler, i2); } +#if __OPENCL_C_VERSION__ >= CL_VERSION_2_0 kernel void basic_image_readwrite(read_write image3d_t image_read_write_image3d) { half4 h4; int4 i4; write_imageh(image_read_write_image3d, i4, h4); } +#endif // __OPENCL_C_VERSION__ >= CL_VERSION_2_0 kernel void basic_image_writeonly(write_only image1d_buffer_t image_write_only_image1d_buffer) { half4 h4; @@ -63,6 +78,34 @@ write_imageh(image_write_only_image1d_buffer, i, h4); } -kernel void basic_subgroup(global uint *out) { - out[0] = get_sub_group_size(); +kernel void basic_vector_data() { +#if __OPENCL_C_VERSION__ >= CL_VERSION_2_0 + generic void *generic_p; +#endif + constant void *constant_p; + local void *local_p; + global void *global_p; + private void *private_p; + size_t s; + + vload4(s, (const __constant ulong *) constant_p); + vload16(s, (const __constant short *) constant_p); + +#if __OPENCL_C_VERSION__ >= CL_VERSION_2_0 + vload3(s, (const __generic ushort *) generic_p); + vload16(s, (const __generic uchar *) generic_p); +#endif + + vload8(s, (const __global long *) global_p); + vload2(s, (const __local uint *) local_p); + vload16(s, (const __private float *) private_p); +} + +kernel void basic_work_item() { + uint ui; + + get_enqueued_local_size(ui); +#if __OPENCL_C_VERSION__ < CL_VERSION_2_0 +// expected-error@-2{{implicit declaration of function 'get_enqueued_local_size' is invalid in OpenCL}} +#endif } Index: clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp =================================================================== --- clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp +++ clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp @@ -55,13 +55,15 @@ // }; // // static const OpenCLBuiltinStruct BuiltinTable[] = { -// // convert_float2_rtn -// { 58, 2 }, // The "convert_float2_rtn" function has one signature at the -// // index 58 of the SignatureTable, and it uses the 2 values -// // after this index. -// { 202, 2 }, -// { 346, 2 }, -// { 490, 2 }, +// // 891 convert_float2_rtn +// { 38, 2, 100, 0 }, // The "convert_float2_rtn" function has one signature +// // at the index 891 of the SignatureTable, it uses the 2 +// // values after this index. The first value is the +// // return type. +// // This prototype is available from OpenCL C version 1.0 +// // to the last available version (0 meaning all). +// { 182, 2, 100, 0 }, +// { 326, 2, 100, 0 }, // ... // Other functions and signatures. // }; // @@ -191,11 +193,12 @@ // Emit the BuiltinTable table. This table contains all the overloads of // each function, and is a struct OpenCLBuiltinDecl. // E.g.: - // // convert_float2_rtn - // { 58, 2 }, + // // 891 convert_float2_rtn + // { 38, 2, 100, 0 }, // This means that the signature of this convert_float2_rtn overload has // 1 argument (+1 for the return type), stored at index 58 in // the OpenCLSignature table. + // Trailing values add information about the version. void EmitBuiltinTable(); // Emit a StringMatcher function to check whether a function name is an @@ -354,6 +357,10 @@ // the SignatureTable must be considered to build the signature. // The first type at index SigTableIndex is the return type. const unsigned NumTypes; + // Version in which it was introduced (e.g.: CL20). MinVersion is inclusive. + const unsigned MinVersion; + // Version in which it was introduced (e.g.: CL20). MaxVersion is exclusive. + const unsigned MaxVersion; }; )"; @@ -469,7 +476,9 @@ for (const auto &Overload : FOM.second) { OS << " { " << Overload.second << ", " - << Overload.first->getValueAsListOfDefs("Signature").size() + << Overload.first->getValueAsListOfDefs("Signature").size() << ", " + << Overload.first->getValueAsDef("MinVersion")->getValueAsInt("Name") << ", " + << Overload.first->getValueAsDef("MaxVersion")->getValueAsInt("Name") << " },\n"; Index++; }