forked from OSchip/llvm-project
[OpenCL] Add version handling and add vector ld/st builtins
Allow setting a MinVersion, stating from which OpenCL version a builtin function is available, and a MaxVersion, stating from which OpenCL version a builtin function should not be available anymore. Guard some definitions of the "work-item" builtin functions according to the OpenCL versions from which they are available. Add the "vector data load and store" builtin functions (e.g. vload/vstore), whose signatures differ before and after OpenCL 2.0 in the pointer argument address spaces. Patch by Pierre Gondois and Sven van Haastregt. Differential Revision: https://reviews.llvm.org/D63504 llvm-svn: 372321
This commit is contained in:
parent
88a5fbfcea
commit
ed69faa01b
|
@ -20,12 +20,13 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
// Versions of OpenCL
|
||||
class Version<int _Version> {
|
||||
int Version = _Version;
|
||||
int ID = _Version;
|
||||
}
|
||||
def CL10: Version<100>;
|
||||
def CL11: Version<110>;
|
||||
def CL12: Version<120>;
|
||||
def CL20: Version<200>;
|
||||
def CLAll : Version< 0>;
|
||||
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.
|
||||
|
@ -191,8 +192,13 @@ class Builtin<string _Name, list<Type> _Signature> {
|
|||
list<Type> 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;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -312,6 +318,137 @@ foreach RType = [Float, Double, Half, Char, UChar, Short,
|
|||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// 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<name, [Size, UInt]>;
|
||||
}
|
||||
|
||||
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<name, [Size]>;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// 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 ---
|
||||
// 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<name, [VectorType<Char, VSize>, Size, PointerType<ConstType<Char>, AS>]>;
|
||||
def : Builtin<name, [VectorType<UChar, VSize>, Size, PointerType<ConstType<UChar>, AS>]>;
|
||||
def : Builtin<name, [VectorType<Short, VSize>, Size, PointerType<ConstType<Short>, AS>]>;
|
||||
def : Builtin<name, [VectorType<UShort, VSize>, Size, PointerType<ConstType<UShort>, AS>]>;
|
||||
def : Builtin<name, [VectorType<Int, VSize>, Size, PointerType<ConstType<Int>, AS>]>;
|
||||
def : Builtin<name, [VectorType<UInt, VSize>, Size, PointerType<ConstType<UInt>, AS>]>;
|
||||
def : Builtin<name, [VectorType<Long, VSize>, Size, PointerType<ConstType<Long>, AS>]>;
|
||||
def : Builtin<name, [VectorType<ULong, VSize>, Size, PointerType<ConstType<ULong>, AS>]>;
|
||||
def : Builtin<name, [VectorType<Float, VSize>, Size, PointerType<ConstType<Float>, AS>]>;
|
||||
def : Builtin<name, [VectorType<Double, VSize>, Size, PointerType<ConstType<Double>, AS>]>;
|
||||
def : Builtin<name, [VectorType<Half, VSize>, Size, PointerType<ConstType<Half>, AS>]>;
|
||||
}
|
||||
foreach name = ["vstore" # VSize] in {
|
||||
def : Builtin<name, [Void, VectorType<Char, VSize>, Size, PointerType<ConstType<Char>, AS>]>;
|
||||
def : Builtin<name, [Void, VectorType<UChar, VSize>, Size, PointerType<ConstType<UChar>, AS>]>;
|
||||
def : Builtin<name, [Void, VectorType<Short, VSize>, Size, PointerType<ConstType<Short>, AS>]>;
|
||||
def : Builtin<name, [Void, VectorType<UShort, VSize>, Size, PointerType<ConstType<UShort>, AS>]>;
|
||||
def : Builtin<name, [Void, VectorType<Int, VSize>, Size, PointerType<ConstType<Int>, AS>]>;
|
||||
def : Builtin<name, [Void, VectorType<UInt, VSize>, Size, PointerType<ConstType<UInt>, AS>]>;
|
||||
def : Builtin<name, [Void, VectorType<Long, VSize>, Size, PointerType<ConstType<Long>, AS>]>;
|
||||
def : Builtin<name, [Void, VectorType<ULong, VSize>, Size, PointerType<ConstType<ULong>, AS>]>;
|
||||
def : Builtin<name, [Void, VectorType<Float, VSize>, Size, PointerType<ConstType<Float>, AS>]>;
|
||||
def : Builtin<name, [Void, VectorType<Double, VSize>, Size, PointerType<ConstType<Double>, AS>]>;
|
||||
def : Builtin<name, [Void, VectorType<Half, VSize>, Size, PointerType<ConstType<Half>, AS>]>;
|
||||
}
|
||||
foreach name = ["vloada_half" # VSize] in {
|
||||
def : Builtin<name, [VectorType<Float, VSize>, Size, PointerType<ConstType<Half>, AS>]>;
|
||||
}
|
||||
foreach rnd = ["", "_rte", "_rtz", "_rtp", "_rtn"] in {
|
||||
foreach name = ["vstorea_half" # VSize # rnd] in {
|
||||
def : Builtin<name, [Void, VectorType<Float, VSize>, Size, PointerType<Half, AS>]>;
|
||||
def : Builtin<name, [Void, VectorType<Double, VSize>, Size, PointerType<Half, AS>]>;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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<name, [VectorType<Char, VSize>, Size, PointerType<ConstType<Char>, GenericAS>]>;
|
||||
def : Builtin<name, [VectorType<UChar, VSize>, Size, PointerType<ConstType<UChar>, GenericAS>]>;
|
||||
def : Builtin<name, [VectorType<Short, VSize>, Size, PointerType<ConstType<Short>, GenericAS>]>;
|
||||
def : Builtin<name, [VectorType<UShort, VSize>, Size, PointerType<ConstType<UShort>, GenericAS>]>;
|
||||
def : Builtin<name, [VectorType<Int, VSize>, Size, PointerType<ConstType<Int>, GenericAS>]>;
|
||||
def : Builtin<name, [VectorType<UInt, VSize>, Size, PointerType<ConstType<UInt>, GenericAS>]>;
|
||||
def : Builtin<name, [VectorType<Long, VSize>, Size, PointerType<ConstType<Long>, GenericAS>]>;
|
||||
def : Builtin<name, [VectorType<ULong, VSize>, Size, PointerType<ConstType<ULong>, GenericAS>]>;
|
||||
def : Builtin<name, [VectorType<Float, VSize>, Size, PointerType<ConstType<Float>, GenericAS>]>;
|
||||
def : Builtin<name, [VectorType<Double, VSize>, Size, PointerType<ConstType<Double>, GenericAS>]>;
|
||||
def : Builtin<name, [VectorType<Half, VSize>, Size, PointerType<ConstType<Half>, GenericAS>]>;
|
||||
}
|
||||
foreach name = ["vstore" # VSize] in {
|
||||
def : Builtin<name, [Void, VectorType<Char, VSize>, Size, PointerType<ConstType<Char>, GenericAS>]>;
|
||||
def : Builtin<name, [Void, VectorType<UChar, VSize>, Size, PointerType<ConstType<UChar>, GenericAS>]>;
|
||||
def : Builtin<name, [Void, VectorType<Short, VSize>, Size, PointerType<ConstType<Short>, GenericAS>]>;
|
||||
def : Builtin<name, [Void, VectorType<UShort, VSize>, Size, PointerType<ConstType<UShort>, GenericAS>]>;
|
||||
def : Builtin<name, [Void, VectorType<Int, VSize>, Size, PointerType<ConstType<Int>, GenericAS>]>;
|
||||
def : Builtin<name, [Void, VectorType<UInt, VSize>, Size, PointerType<ConstType<UInt>, GenericAS>]>;
|
||||
def : Builtin<name, [Void, VectorType<Long, VSize>, Size, PointerType<ConstType<Long>, GenericAS>]>;
|
||||
def : Builtin<name, [Void, VectorType<ULong, VSize>, Size, PointerType<ConstType<ULong>, GenericAS>]>;
|
||||
def : Builtin<name, [Void, VectorType<Float, VSize>, Size, PointerType<ConstType<Float>, GenericAS>]>;
|
||||
def : Builtin<name, [Void, VectorType<Double, VSize>, Size, PointerType<ConstType<Double>, GenericAS>]>;
|
||||
def : Builtin<name, [Void, VectorType<Half, VSize>, Size, PointerType<ConstType<Half>, GenericAS>]>;
|
||||
}
|
||||
foreach name = ["vloada_half" # VSize] in {
|
||||
def : Builtin<name, [VectorType<Float, VSize>, Size, PointerType<ConstType<Half>, GenericAS>]>;
|
||||
}
|
||||
foreach rnd = ["", "_rte", "_rtz", "_rtp", "_rtn"] in {
|
||||
foreach name = ["vstorea_half" # VSize # rnd] in {
|
||||
def : Builtin<name, [Void, VectorType<Float, VSize>, Size, PointerType<Half, GenericAS>]>;
|
||||
def : Builtin<name, [Void, VectorType<Double, VSize>, Size, PointerType<Half, GenericAS>]>;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Variants using pointers to the constant address space.
|
||||
foreach VSize = [2, 3, 4, 8, 16] in {
|
||||
foreach name = ["vload" # VSize] in {
|
||||
def : Builtin<name, [VectorType<Char, VSize>, Size, PointerType<ConstType<Char>, ConstantAS>]>;
|
||||
def : Builtin<name, [VectorType<UChar, VSize>, Size, PointerType<ConstType<UChar>, ConstantAS>]>;
|
||||
def : Builtin<name, [VectorType<Short, VSize>, Size, PointerType<ConstType<Short>, ConstantAS>]>;
|
||||
def : Builtin<name, [VectorType<UShort, VSize>, Size, PointerType<ConstType<UShort>, ConstantAS>]>;
|
||||
def : Builtin<name, [VectorType<Int, VSize>, Size, PointerType<ConstType<Int>, ConstantAS>]>;
|
||||
def : Builtin<name, [VectorType<UInt, VSize>, Size, PointerType<ConstType<UInt>, ConstantAS>]>;
|
||||
def : Builtin<name, [VectorType<Long, VSize>, Size, PointerType<ConstType<Long>, ConstantAS>]>;
|
||||
def : Builtin<name, [VectorType<ULong, VSize>, Size, PointerType<ConstType<ULong>, ConstantAS>]>;
|
||||
def : Builtin<name, [VectorType<Float, VSize>, Size, PointerType<ConstType<Float>, ConstantAS>]>;
|
||||
def : Builtin<name, [VectorType<Double, VSize>, Size, PointerType<ConstType<Double>, ConstantAS>]>;
|
||||
def : Builtin<name, [VectorType<Half, VSize>, Size, PointerType<ConstType<Half>, ConstantAS>]>;
|
||||
}
|
||||
foreach name = ["vloada_half" # VSize] in {
|
||||
def : Builtin<name, [VectorType<Float, VSize>, Size, PointerType<ConstType<Half>, ConstantAS>]>;
|
||||
}
|
||||
foreach rnd = ["", "_rte", "_rtz", "_rtp", "_rtn"] in {
|
||||
foreach name = ["vstorea_half" # VSize # rnd] in {
|
||||
def : Builtin<name, [Void, VectorType<Float, VSize>, Size, PointerType<Half, ConstantAS>]>;
|
||||
def : Builtin<name, [Void, VectorType<Double, VSize>, Size, PointerType<Half, ConstantAS>]>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// OpenCL v1.1 s6.11.10, v1.2 s6.12.10, v2.0 s6.13.10: Async Copies from Global to Local Memory, Local to Global Memory, and Prefetch
|
||||
// OpenCL Extension v2.0 s5.1.7 and s6.1.7: Async Copies from Global to Local Memory, Local to Global Memory, and Prefetch
|
||||
|
@ -350,14 +487,6 @@ foreach Type = [Int, UInt] in {
|
|||
}
|
||||
}
|
||||
|
||||
// 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<name, [Size, UInt]>;
|
||||
}
|
||||
|
||||
// OpenCL v1.2 s6.12.2: Math Functions
|
||||
foreach name = ["acos", "acosh", "acospi",
|
||||
"asin", "asinh", "asinpi",
|
||||
|
@ -511,7 +640,7 @@ foreach aQual = ["WO", "RW"] in {
|
|||
|
||||
|
||||
// OpenCL v2.0 s9.17.3: Additions to section 6.13.1: Work-Item Functions
|
||||
let Version = CL20 in {
|
||||
let MinVersion = 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]>;
|
||||
|
|
|
@ -764,6 +764,13 @@ static void InsertOCLBuiltinDeclarationsFromTable(Sema &S, LookupResult &LR,
|
|||
BuiltinTable[FctIndex + SignatureIndex];
|
||||
ASTContext &Context = S.Context;
|
||||
|
||||
// Ignore this BIF if its version does not match the language options.
|
||||
if (Context.getLangOpts().OpenCLVersion < OpenCLBuiltin.MinVersion)
|
||||
continue;
|
||||
if ((OpenCLBuiltin.MaxVersion != 0) &&
|
||||
(Context.getLangOpts().OpenCLVersion >= OpenCLBuiltin.MaxVersion))
|
||||
continue;
|
||||
|
||||
SmallVector<QualType, 1> RetTypes;
|
||||
SmallVector<SmallVector<QualType, 1>, 5> ArgTypes;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -15,7 +25,10 @@ typedef half half4 __attribute__((ext_vector_type(4)));
|
|||
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
|
||||
|
||||
|
@ -60,12 +73,14 @@ kernel void basic_image_readonly(read_only image2d_t image_read_only_image2d) {
|
|||
res = 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;
|
||||
|
@ -78,4 +93,39 @@ kernel void basic_image_writeonly(write_only image1d_buffer_t image_write_only_i
|
|||
|
||||
kernel void basic_subgroup(global uint *out) {
|
||||
out[0] = get_sub_group_size();
|
||||
#if __OPENCL_C_VERSION__ < CL_VERSION_2_0
|
||||
// expected-error@-2{{implicit declaration of function 'get_sub_group_size' is invalid in OpenCL}}
|
||||
#endif
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -121,11 +121,13 @@ private:
|
|||
// 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
|
||||
// { 58, 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 SignatureTable.
|
||||
// the SignatureTable. The last two values represent the minimum (1.0) and
|
||||
// maximum (0, meaning no max version) OpenCL version in which this overload
|
||||
// is supported.
|
||||
void EmitBuiltinTable();
|
||||
|
||||
// Emit a StringMatcher function to check whether a function name is an
|
||||
|
@ -268,6 +270,10 @@ struct OpenCLBuiltinStruct {
|
|||
// the SignatureTable represent the complete signature. The first type at
|
||||
// index SigTableIndex is the return type.
|
||||
const unsigned NumTypes;
|
||||
// First OpenCL version in which this overload was introduced (e.g. CL20).
|
||||
const unsigned short MinVersion;
|
||||
// First OpenCL version in which this overload was removed (e.g. CL20).
|
||||
const unsigned short MaxVersion;
|
||||
};
|
||||
|
||||
)";
|
||||
|
@ -400,11 +406,13 @@ void BuiltinNameEmitter::EmitBuiltinTable() {
|
|||
OS << " // " << (Index + 1) << ": " << FOM.first << "\n";
|
||||
|
||||
for (const auto &Overload : FOM.second) {
|
||||
OS << " { "
|
||||
<< Overload.second << ", "
|
||||
<< Overload.first->getValueAsListOfDefs("Signature").size()
|
||||
OS << " { " << Overload.second << ", "
|
||||
<< Overload.first->getValueAsListOfDefs("Signature").size() << ", "
|
||||
<< Overload.first->getValueAsDef("MinVersion")->getValueAsInt("ID")
|
||||
<< ", "
|
||||
<< Overload.first->getValueAsDef("MaxVersion")->getValueAsInt("ID")
|
||||
<< " },\n";
|
||||
Index++;
|
||||
Index++;
|
||||
}
|
||||
}
|
||||
OS << "};\n\n";
|
||||
|
|
Loading…
Reference in New Issue