xref: /freebsd-src/contrib/llvm-project/clang/lib/Sema/OpenCLBuiltins.td (revision 1838bd0f4839006b42d41a02a787b7f578655223)
1//==--- OpenCLBuiltins.td - OpenCL builtin declarations -------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6// See https://llvm.org/LICENSE.txt for license information.
7// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8//
9//===----------------------------------------------------------------------===//
10//
11// This file contains TableGen definitions for OpenCL builtin function
12// declarations.  In case of an unresolved function name in OpenCL, Clang will
13// check for a function described in this file when -fdeclare-opencl-builtins
14// is specified.
15//
16//===----------------------------------------------------------------------===//
17
18//===----------------------------------------------------------------------===//
19//              Definitions of miscellaneous basic entities.
20//===----------------------------------------------------------------------===//
21// Versions of OpenCL
22class Version<int _Version> {
23  int ID = _Version;
24}
25def CLAll : Version<  0>;
26def CL10  : Version<100>;
27def CL11  : Version<110>;
28def CL12  : Version<120>;
29def CL20  : Version<200>;
30
31// Address spaces
32// Pointer types need to be assigned an address space.
33class AddressSpace<string _AS> {
34  string Name = _AS;
35}
36def DefaultAS    : AddressSpace<"clang::LangAS::Default">;
37def PrivateAS    : AddressSpace<"clang::LangAS::opencl_private">;
38def GlobalAS     : AddressSpace<"clang::LangAS::opencl_global">;
39def ConstantAS   : AddressSpace<"clang::LangAS::opencl_constant">;
40def LocalAS      : AddressSpace<"clang::LangAS::opencl_local">;
41def GenericAS    : AddressSpace<"clang::LangAS::opencl_generic">;
42
43// OpenCL language extension.
44class AbstractExtension<string _Ext> {
45  // One or more OpenCL extensions, space separated.  Each extension must be
46  // a valid extension name for the opencl extension pragma.
47  string ExtName = _Ext;
48}
49
50// Extension associated to a builtin function.
51class FunctionExtension<string _Ext> : AbstractExtension<_Ext>;
52
53// Extension associated to a type.  This enables implicit conditionalization of
54// builtin function overloads containing a type that depends on an extension.
55// During overload resolution, when a builtin function overload contains a type
56// with a TypeExtension, those overloads are skipped when the extension is
57// disabled.
58class TypeExtension<string _Ext> : AbstractExtension<_Ext>;
59
60// TypeExtension definitions.
61def NoTypeExt   : TypeExtension<"">;
62def Fp16TypeExt : TypeExtension<"cl_khr_fp16">;
63def Fp64TypeExt : TypeExtension<"cl_khr_fp64">;
64
65// FunctionExtension definitions.
66def FuncExtNone                          : FunctionExtension<"">;
67def FuncExtKhrSubgroups                  : FunctionExtension<"cl_khr_subgroups">;
68def FuncExtKhrSubgroupExtendedTypes      : FunctionExtension<"cl_khr_subgroup_extended_types">;
69def FuncExtKhrSubgroupNonUniformVote     : FunctionExtension<"cl_khr_subgroup_non_uniform_vote">;
70def FuncExtKhrSubgroupBallot             : FunctionExtension<"cl_khr_subgroup_ballot">;
71def FuncExtKhrSubgroupNonUniformArithmetic: FunctionExtension<"cl_khr_subgroup_non_uniform_arithmetic">;
72def FuncExtKhrSubgroupShuffle            : FunctionExtension<"cl_khr_subgroup_shuffle">;
73def FuncExtKhrSubgroupShuffleRelative    : FunctionExtension<"cl_khr_subgroup_shuffle_relative">;
74def FuncExtKhrSubgroupClusteredReduce    : FunctionExtension<"cl_khr_subgroup_clustered_reduce">;
75def FuncExtKhrExtendedBitOps             : FunctionExtension<"cl_khr_extended_bit_ops">;
76def FuncExtKhrGlobalInt32BaseAtomics     : FunctionExtension<"cl_khr_global_int32_base_atomics">;
77def FuncExtKhrGlobalInt32ExtendedAtomics : FunctionExtension<"cl_khr_global_int32_extended_atomics">;
78def FuncExtKhrLocalInt32BaseAtomics      : FunctionExtension<"cl_khr_local_int32_base_atomics">;
79def FuncExtKhrLocalInt32ExtendedAtomics  : FunctionExtension<"cl_khr_local_int32_extended_atomics">;
80def FuncExtKhrInt64BaseAtomics           : FunctionExtension<"cl_khr_int64_base_atomics">;
81def FuncExtKhrInt64ExtendedAtomics       : FunctionExtension<"cl_khr_int64_extended_atomics">;
82def FuncExtKhrMipmapImage                : FunctionExtension<"cl_khr_mipmap_image">;
83def FuncExtKhrMipmapImageReadWrite       : FunctionExtension<"cl_khr_mipmap_image __opencl_c_read_write_images">;
84def FuncExtKhrMipmapImageWrites          : FunctionExtension<"cl_khr_mipmap_image_writes">;
85def FuncExtKhrGlMsaaSharing              : FunctionExtension<"cl_khr_gl_msaa_sharing">;
86def FuncExtKhrGlMsaaSharingReadWrite     : FunctionExtension<"cl_khr_gl_msaa_sharing __opencl_c_read_write_images">;
87
88def FuncExtOpenCLCGenericAddressSpace    : FunctionExtension<"__opencl_c_generic_address_space">;
89def FuncExtOpenCLCNamedAddressSpaceBuiltins : FunctionExtension<"__opencl_c_named_address_space_builtins">;
90def FuncExtOpenCLCPipes                  : FunctionExtension<"__opencl_c_pipes">;
91def FuncExtOpenCLCWGCollectiveFunctions  : FunctionExtension<"__opencl_c_work_group_collective_functions">;
92def FuncExtOpenCLCReadWriteImages        : FunctionExtension<"__opencl_c_read_write_images">;
93def FuncExtFloatAtomicsFp16GlobalLoadStore  : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_global_atomic_load_store">;
94def FuncExtFloatAtomicsFp16LocalLoadStore   : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_local_atomic_load_store">;
95def FuncExtFloatAtomicsFp16GenericLoadStore : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_global_atomic_load_store __opencl_c_ext_fp16_local_atomic_load_store">;
96def FuncExtFloatAtomicsFp16GlobalAdd     : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_global_atomic_add">;
97def FuncExtFloatAtomicsFp32GlobalAdd     : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_global_atomic_add">;
98def FuncExtFloatAtomicsFp64GlobalAdd     : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_global_atomic_add">;
99def FuncExtFloatAtomicsFp16LocalAdd      : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_local_atomic_add">;
100def FuncExtFloatAtomicsFp32LocalAdd      : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_local_atomic_add">;
101def FuncExtFloatAtomicsFp64LocalAdd      : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_local_atomic_add">;
102def FuncExtFloatAtomicsFp16GenericAdd    : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_local_atomic_add __opencl_c_ext_fp16_global_atomic_add">;
103def FuncExtFloatAtomicsFp32GenericAdd    : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_local_atomic_add __opencl_c_ext_fp32_global_atomic_add">;
104def FuncExtFloatAtomicsFp64GenericAdd    : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_local_atomic_add __opencl_c_ext_fp64_global_atomic_add">;
105def FuncExtFloatAtomicsFp16GlobalMinMax  : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_global_atomic_min_max">;
106def FuncExtFloatAtomicsFp32GlobalMinMax  : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_global_atomic_min_max">;
107def FuncExtFloatAtomicsFp64GlobalMinMax  : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_global_atomic_min_max">;
108def FuncExtFloatAtomicsFp16LocalMinMax   : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_local_atomic_min_max">;
109def FuncExtFloatAtomicsFp32LocalMinMax   : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_local_atomic_min_max">;
110def FuncExtFloatAtomicsFp64LocalMinMax   : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_local_atomic_min_max">;
111def FuncExtFloatAtomicsFp16GenericMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp16_local_atomic_min_max __opencl_c_ext_fp16_global_atomic_min_max">;
112def FuncExtFloatAtomicsFp32GenericMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_local_atomic_min_max __opencl_c_ext_fp32_global_atomic_min_max">;
113def FuncExtFloatAtomicsFp64GenericMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_local_atomic_min_max __opencl_c_ext_fp64_global_atomic_min_max">;
114
115// Not a real extension, but a workaround to add C++ for OpenCL specific builtins.
116def FuncExtOpenCLCxx                     : FunctionExtension<"__cplusplus">;
117
118// Multiple extensions
119def FuncExtKhrMipmapWritesAndWrite3d     : FunctionExtension<"cl_khr_mipmap_image_writes cl_khr_3d_image_writes">;
120
121// Arm extensions.
122def ArmIntegerDotProductInt8                   : FunctionExtension<"cl_arm_integer_dot_product_int8">;
123def ArmIntegerDotProductAccumulateInt8         : FunctionExtension<"cl_arm_integer_dot_product_accumulate_int8">;
124def ArmIntegerDotProductAccumulateInt16        : FunctionExtension<"cl_arm_integer_dot_product_accumulate_int16">;
125def ArmIntegerDotProductAccumulateSaturateInt8 : FunctionExtension<"cl_arm_integer_dot_product_accumulate_saturate_int8">;
126
127// Qualified Type.  These map to ASTContext::QualType.
128class QualType<string _TypeExpr, bit _IsAbstract=0> {
129  // Expression to obtain the QualType inside OCL2Qual.
130  // E.g. TypeExpr="Context.IntTy" for the int type.
131  string TypeExpr = _TypeExpr;
132  // Some QualTypes in this file represent an abstract type for which there is
133  // no corresponding AST QualType, e.g. a GenType or an `image2d_t` type
134  // without access qualifiers.
135  bit IsAbstract = _IsAbstract;
136}
137
138// List of integers.
139class IntList<string _Name, list<int> _List> {
140  string Name = _Name;
141  list<int> List = _List;
142}
143
144//===----------------------------------------------------------------------===//
145//                      OpenCL C classes for types
146//===----------------------------------------------------------------------===//
147// OpenCL C basic data types (int, float, image2d_t, ...).
148// Its child classes can represent concrete types (e.g. VectorType) or
149// abstract types (e.g. GenType).
150class Type<string _Name, QualType _QTExpr> {
151  // Name of the Type.
152  string Name = _Name;
153  // QualType associated with this type.
154  QualType QTExpr = _QTExpr;
155  // Size of the vector (if applicable).
156  int VecWidth = 1;
157  // Is a pointer.
158  bit IsPointer = 0;
159  // "const" qualifier.
160  bit IsConst = 0;
161  // "volatile" qualifier.
162  bit IsVolatile = 0;
163  // Access qualifier. Must be one of ("RO", "WO", "RW").
164  string AccessQualifier = "";
165  // Address space.
166  string AddrSpace = DefaultAS.Name;
167  // Extension that needs to be enabled to expose a builtin that uses this type.
168  TypeExtension Extension = NoTypeExt;
169}
170
171// OpenCL vector types (e.g. int2, int3, int16, float8, ...).
172class VectorType<Type _Ty, int _VecWidth> : Type<_Ty.Name, _Ty.QTExpr> {
173  let VecWidth = _VecWidth;
174  let AccessQualifier = "";
175  // Inherited fields
176  let IsPointer = _Ty.IsPointer;
177  let IsConst = _Ty.IsConst;
178  let IsVolatile = _Ty.IsVolatile;
179  let AddrSpace = _Ty.AddrSpace;
180  let Extension = _Ty.Extension;
181}
182
183// OpenCL pointer types (e.g. int*, float*, ...).
184class PointerType<Type _Ty, AddressSpace _AS = DefaultAS> :
185    Type<_Ty.Name, _Ty.QTExpr> {
186  let AddrSpace = _AS.Name;
187  // Inherited fields
188  let VecWidth = _Ty.VecWidth;
189  let IsPointer = 1;
190  let IsConst = _Ty.IsConst;
191  let IsVolatile = _Ty.IsVolatile;
192  let AccessQualifier = _Ty.AccessQualifier;
193  let Extension = _Ty.Extension;
194}
195
196// OpenCL const types (e.g. const int).
197class ConstType<Type _Ty> : Type<_Ty.Name, _Ty.QTExpr> {
198  let IsConst = 1;
199  // Inherited fields
200  let VecWidth = _Ty.VecWidth;
201  let IsPointer = _Ty.IsPointer;
202  let IsVolatile = _Ty.IsVolatile;
203  let AccessQualifier = _Ty.AccessQualifier;
204  let AddrSpace = _Ty.AddrSpace;
205  let Extension = _Ty.Extension;
206}
207
208// OpenCL volatile types (e.g. volatile int).
209class VolatileType<Type _Ty> : Type<_Ty.Name, _Ty.QTExpr> {
210  let IsVolatile = 1;
211  // Inherited fields
212  let VecWidth = _Ty.VecWidth;
213  let IsPointer = _Ty.IsPointer;
214  let IsConst = _Ty.IsConst;
215  let AccessQualifier = _Ty.AccessQualifier;
216  let AddrSpace = _Ty.AddrSpace;
217  let Extension = _Ty.Extension;
218}
219
220// OpenCL image types (e.g. image2d).
221class ImageType<Type _Ty, string _AccessQualifier> :
222    Type<_Ty.Name, QualType<_Ty.QTExpr.TypeExpr # _AccessQualifier # "Ty", 0>> {
223  let VecWidth = 0;
224  let AccessQualifier = _AccessQualifier;
225  // Inherited fields
226  let IsPointer = _Ty.IsPointer;
227  let IsConst = _Ty.IsConst;
228  let IsVolatile = _Ty.IsVolatile;
229  let AddrSpace = _Ty.AddrSpace;
230  let Extension = _Ty.Extension;
231}
232
233// OpenCL enum type (e.g. memory_scope).
234class EnumType<string _Name> :
235    Type<_Name, QualType<"getOpenCLEnumType(S, \"" # _Name # "\")", 0>> {
236}
237
238// OpenCL typedef type (e.g. cl_mem_fence_flags).
239class TypedefType<string _Name> :
240    Type<_Name, QualType<"getOpenCLTypedefType(S, \"" # _Name # "\")", 0>> {
241}
242
243// List of Types.
244class TypeList<list<Type> _Type> {
245  list<Type> List = _Type;
246}
247
248// A GenericType is an abstract type that defines a set of types as a
249// combination of Types and vector sizes.
250//
251// For example, if TypeList = <int, float> and VectorList = <1, 2, 4>, then it
252// represents <int, int2, int4, float, float2, float4>.
253//
254// Some rules apply when using multiple GenericType arguments in a declaration:
255//   1. The number of vector sizes must be equal or 1 for all gentypes in a
256//      declaration.
257//   2. The number of Types must be equal or 1 for all gentypes in a
258//      declaration.
259//   3. Generic types are combined by iterating over all generic types at once.
260//      For example, for the following GenericTypes
261//        GenT1 = GenericType<half, [1, 2]> and
262//        GenT2 = GenericType<float, int, [1, 2]>
263//      A declaration f(GenT1, GenT2) results in the combinations
264//        f(half, float), f(half2, float2), f(half, int), f(half2, int2) .
265//   4. "sgentype" from the OpenCL specification is supported by specifying
266//      a single vector size.
267//      For example, for the following GenericTypes
268//        GenT = GenericType<half, int, [1, 2]> and
269//        SGenT = GenericType<half, int, [1]>
270//      A declaration f(GenT, SGenT) results in the combinations
271//        f(half, half), f(half2, half), f(int, int), f(int2, int) .
272class GenericType<string _Ty, TypeList _TypeList, IntList _VectorList> :
273    Type<_Ty, QualType<"null", 1>> {
274  // Possible element types of the generic type.
275  TypeList TypeList = _TypeList;
276  // Possible vector sizes of the types in the TypeList.
277  IntList VectorList = _VectorList;
278  // The VecWidth field is ignored for GenericTypes. Use VectorList instead.
279  let VecWidth = 0;
280}
281
282// Builtin function attributes.
283def Attr {
284  list<bit> None = [0, 0, 0];
285  list<bit> Pure = [1, 0, 0];
286  list<bit> Const = [0, 1, 0];
287  list<bit> Convergent = [0, 0, 1];
288}
289
290//===----------------------------------------------------------------------===//
291//                      OpenCL C class for builtin functions
292//===----------------------------------------------------------------------===//
293class Builtin<string _Name, list<Type> _Signature, list<bit> _Attributes = Attr.None> {
294  // Name of the builtin function
295  string Name = _Name;
296  // List of types used by the function. The first one is the return type and
297  // the following are the arguments. The list must have at least one element
298  // (the return type).
299  list<Type> Signature = _Signature;
300  // Function attribute __attribute__((pure))
301  bit IsPure = _Attributes[0];
302  // Function attribute __attribute__((const))
303  bit IsConst = _Attributes[1];
304  // Function attribute __attribute__((convergent))
305  bit IsConv = _Attributes[2];
306  // OpenCL extensions to which the function belongs.
307  FunctionExtension Extension = FuncExtNone;
308  // Version of OpenCL from which the function is available (e.g.: CL10).
309  // MinVersion is inclusive.
310  Version MinVersion = CL10;
311  // Version of OpenCL from which the function is not supported anymore.
312  // MaxVersion is exclusive.
313  // CLAll makes the function available for all versions.
314  Version MaxVersion = CLAll;
315}
316
317//===----------------------------------------------------------------------===//
318//                 Definitions of OpenCL C types
319//===----------------------------------------------------------------------===//
320
321// OpenCL v1.0/1.2/2.0 s6.1.1: Built-in Scalar Data Types.
322def Bool      : Type<"bool",      QualType<"Context.BoolTy">>;
323def Char      : Type<"char",      QualType<"Context.CharTy">>;
324def UChar     : Type<"uchar",     QualType<"Context.UnsignedCharTy">>;
325def Short     : Type<"short",     QualType<"Context.ShortTy">>;
326def UShort    : Type<"ushort",    QualType<"Context.UnsignedShortTy">>;
327def Int       : Type<"int",       QualType<"Context.IntTy">>;
328def UInt      : Type<"uint",      QualType<"Context.UnsignedIntTy">>;
329def Long      : Type<"long",      QualType<"Context.LongTy">>;
330def ULong     : Type<"ulong",     QualType<"Context.UnsignedLongTy">>;
331def Float     : Type<"float",     QualType<"Context.FloatTy">>;
332let Extension = Fp64TypeExt in {
333  def Double    : Type<"double",    QualType<"Context.DoubleTy">>;
334}
335let Extension = Fp16TypeExt in {
336  def Half      : Type<"half",      QualType<"Context.HalfTy">>;
337}
338def Size      : Type<"size_t",    QualType<"Context.getSizeType()">>;
339def PtrDiff   : Type<"ptrdiff_t", QualType<"Context.getPointerDiffType()">>;
340def IntPtr    : Type<"intptr_t",  QualType<"Context.getIntPtrType()">>;
341def UIntPtr   : Type<"uintptr_t", QualType<"Context.getUIntPtrType()">>;
342def Void      : Type<"void",      QualType<"Context.VoidTy">>;
343
344// OpenCL v1.0/1.2/2.0 s6.1.2: Built-in Vector Data Types.
345// Built-in vector data types are created by TableGen's OpenCLBuiltinEmitter.
346
347// OpenCL v1.0/1.2/2.0 s6.1.3: Other Built-in Data Types.
348// The image definitions are "abstract".  They should not be used without
349// specifying an access qualifier (RO/WO/RW).
350def Image1d               : Type<"image1d_t", QualType<"Context.OCLImage1d", 1>>;
351def Image2d               : Type<"image2d_t", QualType<"Context.OCLImage2d", 1>>;
352def Image3d               : Type<"image3d_t", QualType<"Context.OCLImage3d", 1>>;
353def Image1dArray          : Type<"image1d_array_t", QualType<"Context.OCLImage1dArray", 1>>;
354def Image1dBuffer         : Type<"image1d_buffer_t", QualType<"Context.OCLImage1dBuffer", 1>>;
355def Image2dArray          : Type<"image2d_array_t", QualType<"Context.OCLImage2dArray", 1>>;
356def Image2dDepth          : Type<"image2d_depth_t", QualType<"Context.OCLImage2dDepth", 1>>;
357def Image2dArrayDepth     : Type<"image2d_array_depth_t", QualType<"Context.OCLImage2dArrayDepth", 1>>;
358def Image2dMsaa           : Type<"image2d_msaa_t", QualType<"Context.OCLImage2dMSAA", 1>>;
359def Image2dArrayMsaa      : Type<"image2d_array_msaa_t", QualType<"Context.OCLImage2dArrayMSAA", 1>>;
360def Image2dMsaaDepth      : Type<"image2d_msaa_depth_t", QualType<"Context.OCLImage2dMSAADepth", 1>>;
361def Image2dArrayMsaaDepth : Type<"image2d_array_msaa_depth_t", QualType<"Context.OCLImage2dArrayMSAADepth", 1>>;
362
363def Sampler               : Type<"sampler_t", QualType<"Context.OCLSamplerTy">>;
364def ClkEvent              : Type<"clk_event_t", QualType<"Context.OCLClkEventTy">>;
365def Event                 : Type<"event_t", QualType<"Context.OCLEventTy">>;
366def Queue                 : Type<"queue_t", QualType<"Context.OCLQueueTy">>;
367def ReserveId             : Type<"reserve_id_t", QualType<"Context.OCLReserveIDTy">>;
368def MemFenceFlags         : TypedefType<"cl_mem_fence_flags">;
369def ClkProfilingInfo      : TypedefType<"clk_profiling_info">;
370def NDRange               : TypedefType<"ndrange_t">;
371
372// OpenCL v2.0 s6.13.11: Atomic integer and floating-point types.
373def AtomicInt             : Type<"atomic_int", QualType<"Context.getAtomicType(Context.IntTy)">>;
374def AtomicUInt            : Type<"atomic_uint", QualType<"Context.getAtomicType(Context.UnsignedIntTy)">>;
375def AtomicLong            : Type<"atomic_long", QualType<"Context.getAtomicType(Context.LongTy)">>;
376def AtomicULong           : Type<"atomic_ulong", QualType<"Context.getAtomicType(Context.UnsignedLongTy)">>;
377def AtomicFloat           : Type<"atomic_float", QualType<"Context.getAtomicType(Context.FloatTy)">>;
378def AtomicDouble          : Type<"atomic_double", QualType<"Context.getAtomicType(Context.DoubleTy)">>;
379def AtomicHalf            : Type<"atomic_half", QualType<"Context.getAtomicType(Context.HalfTy)">>;
380def AtomicIntPtr          : Type<"atomic_intptr_t", QualType<"Context.getAtomicType(Context.getIntPtrType())">>;
381def AtomicUIntPtr         : Type<"atomic_uintptr_t", QualType<"Context.getAtomicType(Context.getUIntPtrType())">>;
382def AtomicSize            : Type<"atomic_size_t", QualType<"Context.getAtomicType(Context.getSizeType())">>;
383def AtomicPtrDiff         : Type<"atomic_ptrdiff_t", QualType<"Context.getAtomicType(Context.getPointerDiffType())">>;
384
385def AtomicFlag            : TypedefType<"atomic_flag">;
386def MemoryOrder           : EnumType<"memory_order">;
387def MemoryScope           : EnumType<"memory_scope">;
388
389//===----------------------------------------------------------------------===//
390//                 Definitions of OpenCL gentype variants
391//===----------------------------------------------------------------------===//
392// The OpenCL specification often uses "gentype" in builtin function
393// declarations to indicate that a builtin function is available with various
394// argument and return types.  The types represented by "gentype" vary between
395// different parts of the specification.  The following definitions capture
396// the different type lists for gentypes in different parts of the
397// specification.
398
399// Vector width lists.
400def VecAndScalar: IntList<"VecAndScalar", [1, 2, 3, 4, 8, 16]>;
401def VecNoScalar : IntList<"VecNoScalar", [2, 3, 4, 8, 16]>;
402def Vec1        : IntList<"Vec1", [1]>;
403def Vec1234     : IntList<"Vec1234", [1, 2, 3, 4]>;
404
405// Type lists.
406def TLAll           : TypeList<[Char,  UChar, Short,  UShort, Int,  UInt, Long,  ULong, Float, Double, Half]>;
407def TLFloat         : TypeList<[Float, Double, Half]>;
408def TLSignedInts    : TypeList<[Char, Short, Int, Long]>;
409def TLUnsignedInts  : TypeList<[UChar, UShort, UInt, ULong]>;
410
411def TLIntLongFloats : TypeList<[Int, UInt, Long, ULong, Float, Double, Half]>;
412
413// All unsigned integer types twice, to facilitate unsigned return types for e.g.
414// uchar abs(char) and
415// uchar abs(uchar).
416def TLAllUIntsTwice : TypeList<[UChar, UChar, UShort, UShort, UInt, UInt, ULong, ULong]>;
417
418def TLAllInts       : TypeList<[Char, UChar, Short, UShort, Int, UInt, Long, ULong]>;
419
420// GenType definitions for multiple base types (e.g. all floating point types,
421// or all integer types).
422// All types
423def AGenType1              : GenericType<"AGenType1", TLAll, Vec1>;
424def AGenTypeN              : GenericType<"AGenTypeN", TLAll, VecAndScalar>;
425def AGenTypeNNoScalar      : GenericType<"AGenTypeNNoScalar", TLAll, VecNoScalar>;
426// All integer
427def AIGenType1             : GenericType<"AIGenType1", TLAllInts, Vec1>;
428def AIGenTypeN             : GenericType<"AIGenTypeN", TLAllInts, VecAndScalar>;
429def AIGenTypeNNoScalar     : GenericType<"AIGenTypeNNoScalar", TLAllInts, VecNoScalar>;
430// All integer to unsigned
431def AI2UGenTypeN           : GenericType<"AI2UGenTypeN", TLAllUIntsTwice, VecAndScalar>;
432// Signed integer
433def SGenTypeN              : GenericType<"SGenTypeN", TLSignedInts, VecAndScalar>;
434// Unsigned integer
435def UGenTypeN              : GenericType<"UGenTypeN", TLUnsignedInts, VecAndScalar>;
436// Float
437def FGenTypeN              : GenericType<"FGenTypeN", TLFloat, VecAndScalar>;
438// (u)int, (u)long, and all floats
439def IntLongFloatGenType1   : GenericType<"IntLongFloatGenType1", TLIntLongFloats, Vec1>;
440// (u)char and (u)short
441def CharShortGenType1      : GenericType<"CharShortGenType1",
442                                 TypeList<[Char, UChar, Short, UShort]>, Vec1>;
443
444// GenType definitions for every single base type (e.g. fp32 only).
445// Names are like: GenTypeFloatVecAndScalar.
446foreach Type = [Char, UChar, Short, UShort,
447                Int, UInt, Long, ULong,
448                Float, Double, Half] in {
449  foreach VecSizes = [VecAndScalar, VecNoScalar] in {
450    def "GenType" # Type # VecSizes :
451              GenericType<"GenType" # Type # VecSizes,
452                          TypeList<[Type]>, VecSizes>;
453  }
454}
455
456// GenType definitions for vec1234.
457foreach Type = [Float, Double, Half] in {
458  def "GenType" # Type # Vec1234 :
459              GenericType<"GenType" # Type # Vec1234,
460                          TypeList<[Type]>, Vec1234>;
461}
462
463
464//===----------------------------------------------------------------------===//
465//                 Definitions of OpenCL builtin functions
466//===----------------------------------------------------------------------===//
467//--------------------------------------------------------------------
468// OpenCL v1.1/1.2/2.0 s6.2.3 - Explicit conversions.
469// OpenCL v2.0 Extensions s5.1.1 and s6.1.1 - Conversions.
470
471// Generate the convert_* builtins functions.
472foreach RType = [Float, Double, Half, Char, UChar, Short,
473                 UShort, Int, UInt, Long, ULong] in {
474  foreach IType = [Float, Double, Half, Char, UChar, Short,
475                   UShort, Int, UInt, Long, ULong] in {
476    // Conversions to integer type have a sat and non-sat variant.
477    foreach sat = !cond(!eq(RType.Name, "float") : [""],
478                        !eq(RType.Name, "double") : [""],
479                        !eq(RType.Name, "half") : [""],
480                        1 : ["", "_sat"]) in {
481      foreach rnd = ["", "_rte", "_rtn", "_rtp", "_rtz"] in {
482        def : Builtin<"convert_" # RType.Name # sat # rnd, [RType, IType],
483                      Attr.Const>;
484        foreach v = [2, 3, 4, 8, 16] in {
485          def : Builtin<"convert_" # RType.Name # v # sat # rnd,
486                        [VectorType<RType, v>, VectorType<IType, v>],
487                        Attr.Const>;
488        }
489      }
490    }
491  }
492}
493
494//--------------------------------------------------------------------
495// OpenCL v1.1 s6.11.1, v1.2 s6.12.1, v2.0 s6.13.1 - Work-item Functions
496// --- Table 7 ---
497def : Builtin<"get_work_dim", [UInt], Attr.Const>;
498foreach name = ["get_global_size", "get_global_id", "get_local_size",
499                "get_local_id", "get_num_groups", "get_group_id",
500                "get_global_offset"] in {
501  def : Builtin<name, [Size, UInt], Attr.Const>;
502}
503
504let MinVersion = CL20 in {
505  def : Builtin<"get_enqueued_local_size", [Size, UInt]>;
506  foreach name = ["get_global_linear_id", "get_local_linear_id"] in {
507    def : Builtin<name, [Size]>;
508  }
509}
510
511
512//--------------------------------------------------------------------
513// OpenCL v1.1 s6.11.2, v1.2 s6.12.2, v2.0 s6.13.2 - Math functions
514// OpenCL Extension v2.0 s5.1.2 and s6.1.2 - Math Functions
515// --- Table 8 ---
516// --- 1 argument ---
517foreach name = ["acos", "acosh", "acospi",
518                "asin", "asinh", "asinpi",
519                "atan", "atanh", "atanpi",
520                "cbrt", "ceil",
521                "cos", "cosh", "cospi",
522                "erfc", "erf",
523                "exp", "exp2", "exp10", "expm1",
524                "fabs", "floor",
525                "log", "log2", "log10", "log1p", "logb",
526                "rint", "round", "rsqrt",
527                "sin", "sinh", "sinpi",
528                "sqrt",
529                "tan", "tanh", "tanpi",
530                "tgamma", "trunc",
531                "lgamma"] in {
532    def : Builtin<name, [FGenTypeN, FGenTypeN], Attr.Const>;
533}
534foreach name = ["nan"] in {
535  def : Builtin<name, [GenTypeFloatVecAndScalar, GenTypeUIntVecAndScalar], Attr.Const>;
536  def : Builtin<name, [GenTypeDoubleVecAndScalar, GenTypeULongVecAndScalar], Attr.Const>;
537  def : Builtin<name, [GenTypeHalfVecAndScalar, GenTypeUShortVecAndScalar], Attr.Const>;
538}
539
540// --- 2 arguments ---
541foreach name = ["atan2", "atan2pi", "copysign", "fdim", "fmod", "hypot",
542                "maxmag", "minmag", "nextafter", "pow", "powr",
543                "remainder"] in {
544  def : Builtin<name, [FGenTypeN, FGenTypeN, FGenTypeN], Attr.Const>;
545}
546foreach name = ["fmax", "fmin"] in {
547  def : Builtin<name, [FGenTypeN, FGenTypeN, FGenTypeN], Attr.Const>;
548  def : Builtin<name, [GenTypeFloatVecNoScalar, GenTypeFloatVecNoScalar, Float], Attr.Const>;
549  def : Builtin<name, [GenTypeDoubleVecNoScalar, GenTypeDoubleVecNoScalar, Double], Attr.Const>;
550  def : Builtin<name, [GenTypeHalfVecNoScalar, GenTypeHalfVecNoScalar, Half], Attr.Const>;
551}
552foreach name = ["ilogb"] in {
553  def : Builtin<name, [GenTypeIntVecAndScalar, GenTypeFloatVecAndScalar], Attr.Const>;
554  def : Builtin<name, [GenTypeIntVecAndScalar, GenTypeDoubleVecAndScalar], Attr.Const>;
555  def : Builtin<name, [GenTypeIntVecAndScalar, GenTypeHalfVecAndScalar], Attr.Const>;
556}
557foreach name = ["ldexp"] in {
558  def : Builtin<name, [GenTypeFloatVecAndScalar, GenTypeFloatVecAndScalar, GenTypeIntVecAndScalar], Attr.Const>;
559  def : Builtin<name, [GenTypeFloatVecNoScalar, GenTypeFloatVecNoScalar, Int], Attr.Const>;
560  def : Builtin<name, [GenTypeDoubleVecAndScalar, GenTypeDoubleVecAndScalar, GenTypeIntVecAndScalar], Attr.Const>;
561  def : Builtin<name, [GenTypeDoubleVecNoScalar, GenTypeDoubleVecNoScalar, Int], Attr.Const>;
562  def : Builtin<name, [GenTypeHalfVecAndScalar, GenTypeHalfVecAndScalar, GenTypeIntVecAndScalar], Attr.Const>;
563  def : Builtin<name, [GenTypeHalfVecNoScalar, GenTypeHalfVecNoScalar, Int], Attr.Const>;
564}
565foreach name = ["pown", "rootn"] in {
566  def : Builtin<name, [GenTypeFloatVecAndScalar, GenTypeFloatVecAndScalar, GenTypeIntVecAndScalar], Attr.Const>;
567  def : Builtin<name, [GenTypeDoubleVecAndScalar, GenTypeDoubleVecAndScalar, GenTypeIntVecAndScalar], Attr.Const>;
568  def : Builtin<name, [GenTypeHalfVecAndScalar, GenTypeHalfVecAndScalar, GenTypeIntVecAndScalar], Attr.Const>;
569}
570
571// --- 3 arguments ---
572foreach name = ["fma", "mad"] in {
573  def : Builtin<name, [FGenTypeN, FGenTypeN, FGenTypeN, FGenTypeN], Attr.Const>;
574}
575
576// The following math builtins take pointer arguments.  Which overloads are
577// available depends on whether the generic address space feature is enabled.
578multiclass MathWithPointer<list<AddressSpace> addrspaces> {
579  foreach AS = addrspaces in {
580    foreach name = ["fract", "modf", "sincos"] in {
581      def : Builtin<name, [FGenTypeN, FGenTypeN, PointerType<FGenTypeN, AS>]>;
582    }
583    foreach name = ["frexp", "lgamma_r"] in {
584      foreach Type = [GenTypeFloatVecAndScalar, GenTypeDoubleVecAndScalar, GenTypeHalfVecAndScalar] in {
585        def : Builtin<name, [Type, Type, PointerType<GenTypeIntVecAndScalar, AS>]>;
586      }
587    }
588    foreach name = ["remquo"] in {
589      foreach Type = [GenTypeFloatVecAndScalar, GenTypeDoubleVecAndScalar, GenTypeHalfVecAndScalar] in {
590        def : Builtin<name, [Type, Type, Type, PointerType<GenTypeIntVecAndScalar, AS>]>;
591      }
592    }
593  }
594}
595
596let Extension = FuncExtOpenCLCNamedAddressSpaceBuiltins in {
597  defm : MathWithPointer<[GlobalAS, LocalAS, PrivateAS]>;
598}
599let Extension = FuncExtOpenCLCGenericAddressSpace in {
600  defm : MathWithPointer<[GenericAS]>;
601}
602
603// --- Table 9 ---
604foreach name = ["half_cos",
605                "half_exp", "half_exp2", "half_exp10",
606                "half_log", "half_log2", "half_log10",
607                "half_recip", "half_rsqrt",
608                "half_sin", "half_sqrt", "half_tan",
609                "native_cos",
610                "native_exp", "native_exp2", "native_exp10",
611                "native_log", "native_log2", "native_log10",
612                "native_recip", "native_rsqrt",
613                "native_sin", "native_sqrt", "native_tan"] in {
614  def : Builtin<name, [GenTypeFloatVecAndScalar, GenTypeFloatVecAndScalar], Attr.Const>;
615}
616foreach name = ["half_divide", "half_powr",
617                "native_divide", "native_powr"] in {
618  def : Builtin<name, [GenTypeFloatVecAndScalar, GenTypeFloatVecAndScalar, GenTypeFloatVecAndScalar], Attr.Const>;
619}
620
621//--------------------------------------------------------------------
622// OpenCL v1.1 s6.11.3, v1.2 s6.12.3, v2.0 s6.13.3 - Integer Functions
623// --- Table 10 ---
624// --- 1 argument ---
625foreach name = ["abs"] in {
626  def : Builtin<name, [AI2UGenTypeN, AIGenTypeN], Attr.Const>;
627}
628def : Builtin<"clz", [AIGenTypeN, AIGenTypeN], Attr.Const>;
629let MinVersion = CL12 in {
630  def : Builtin<"popcount", [AIGenTypeN, AIGenTypeN], Attr.Const>;
631}
632let MinVersion = CL20 in {
633  foreach name = ["ctz"] in {
634    def : Builtin<name, [AIGenTypeN, AIGenTypeN], Attr.Const>;
635  }
636}
637
638// --- 2 arguments ---
639foreach name = ["abs_diff"] in {
640  def : Builtin<name, [AI2UGenTypeN, AIGenTypeN, AIGenTypeN], Attr.Const>;
641}
642foreach name = ["add_sat", "hadd", "rhadd", "mul_hi", "rotate", "sub_sat"] in {
643  def : Builtin<name, [AIGenTypeN, AIGenTypeN, AIGenTypeN], Attr.Const>;
644}
645foreach name = ["max", "min"] in {
646  def : Builtin<name, [AIGenTypeN, AIGenTypeN, AIGenTypeN], Attr.Const>;
647  def : Builtin<name, [AIGenTypeNNoScalar, AIGenTypeNNoScalar, AIGenType1], Attr.Const>;
648}
649foreach name = ["upsample"] in {
650  def : Builtin<name, [GenTypeShortVecAndScalar, GenTypeCharVecAndScalar, GenTypeUCharVecAndScalar], Attr.Const>;
651  def : Builtin<name, [GenTypeUShortVecAndScalar, GenTypeUCharVecAndScalar, GenTypeUCharVecAndScalar], Attr.Const>;
652  def : Builtin<name, [GenTypeIntVecAndScalar, GenTypeShortVecAndScalar, GenTypeUShortVecAndScalar], Attr.Const>;
653  def : Builtin<name, [GenTypeUIntVecAndScalar, GenTypeUShortVecAndScalar, GenTypeUShortVecAndScalar], Attr.Const>;
654  def : Builtin<name, [GenTypeLongVecAndScalar, GenTypeIntVecAndScalar, GenTypeUIntVecAndScalar], Attr.Const>;
655  def : Builtin<name, [GenTypeULongVecAndScalar, GenTypeUIntVecAndScalar, GenTypeUIntVecAndScalar], Attr.Const>;
656}
657
658// --- 3 arguments ---
659foreach name = ["clamp"] in {
660  def : Builtin<name, [AIGenTypeN, AIGenTypeN, AIGenTypeN, AIGenTypeN], Attr.Const>;
661  def : Builtin<name, [AIGenTypeNNoScalar, AIGenTypeNNoScalar, AIGenType1, AIGenType1], Attr.Const>;
662}
663foreach name = ["mad_hi", "mad_sat"] in {
664  def : Builtin<name, [AIGenTypeN, AIGenTypeN, AIGenTypeN, AIGenTypeN], Attr.Const>;
665}
666
667// --- Table 11 ---
668foreach name = ["mad24"] in {
669  def : Builtin<name, [GenTypeIntVecAndScalar, GenTypeIntVecAndScalar, GenTypeIntVecAndScalar, GenTypeIntVecAndScalar], Attr.Const>;
670  def : Builtin<name, [GenTypeUIntVecAndScalar, GenTypeUIntVecAndScalar, GenTypeUIntVecAndScalar, GenTypeUIntVecAndScalar], Attr.Const>;
671}
672foreach name = ["mul24"] in {
673  def : Builtin<name, [GenTypeIntVecAndScalar, GenTypeIntVecAndScalar, GenTypeIntVecAndScalar], Attr.Const>;
674  def : Builtin<name, [GenTypeUIntVecAndScalar, GenTypeUIntVecAndScalar, GenTypeUIntVecAndScalar], Attr.Const>;
675}
676
677//--------------------------------------------------------------------
678// OpenCL v1.1 s6.11.4, v1.2 s6.12.4, v2.0 s6.13.4 - Common Functions
679// OpenCL Extension v2.0 s5.1.3 and s6.1.3 - Common Functions
680// --- Table 12 ---
681// --- 1 argument ---
682foreach name = ["degrees", "radians", "sign"] in {
683  def : Builtin<name, [FGenTypeN, FGenTypeN], Attr.Const>;
684}
685
686// --- 2 arguments ---
687foreach name = ["max", "min"] in {
688  def : Builtin<name, [FGenTypeN, FGenTypeN, FGenTypeN], Attr.Const>;
689  def : Builtin<name, [GenTypeFloatVecNoScalar, GenTypeFloatVecNoScalar, Float], Attr.Const>;
690  def : Builtin<name, [GenTypeDoubleVecNoScalar, GenTypeDoubleVecNoScalar, Double], Attr.Const>;
691  def : Builtin<name, [GenTypeHalfVecNoScalar, GenTypeHalfVecNoScalar, Half], Attr.Const>;
692}
693foreach name = ["step"] in {
694  def : Builtin<name, [FGenTypeN, FGenTypeN, FGenTypeN], Attr.Const>;
695  def : Builtin<name, [GenTypeFloatVecNoScalar, Float, GenTypeFloatVecNoScalar], Attr.Const>;
696  def : Builtin<name, [GenTypeDoubleVecNoScalar, Double, GenTypeDoubleVecNoScalar], Attr.Const>;
697  def : Builtin<name, [GenTypeHalfVecNoScalar, Half, GenTypeHalfVecNoScalar], Attr.Const>;
698}
699
700// --- 3 arguments ---
701foreach name = ["clamp"] in {
702  def : Builtin<name, [FGenTypeN, FGenTypeN, FGenTypeN, FGenTypeN], Attr.Const>;
703  def : Builtin<name, [GenTypeFloatVecNoScalar, GenTypeFloatVecNoScalar, Float, Float], Attr.Const>;
704  def : Builtin<name, [GenTypeDoubleVecNoScalar, GenTypeDoubleVecNoScalar, Double, Double], Attr.Const>;
705  def : Builtin<name, [GenTypeHalfVecNoScalar, GenTypeHalfVecNoScalar, Half, Half], Attr.Const>;
706}
707foreach name = ["mix"] in {
708  def : Builtin<name, [FGenTypeN, FGenTypeN, FGenTypeN, FGenTypeN], Attr.Const>;
709  def : Builtin<name, [GenTypeFloatVecNoScalar, GenTypeFloatVecNoScalar, GenTypeFloatVecNoScalar, Float], Attr.Const>;
710  def : Builtin<name, [GenTypeDoubleVecNoScalar, GenTypeDoubleVecNoScalar, GenTypeDoubleVecNoScalar, Double], Attr.Const>;
711  def : Builtin<name, [GenTypeHalfVecNoScalar, GenTypeHalfVecNoScalar, GenTypeHalfVecNoScalar, Half], Attr.Const>;
712}
713foreach name = ["smoothstep"] in {
714  def : Builtin<name, [FGenTypeN, FGenTypeN, FGenTypeN, FGenTypeN], Attr.Const>;
715  def : Builtin<name, [GenTypeFloatVecNoScalar, Float, Float, GenTypeFloatVecNoScalar], Attr.Const>;
716  def : Builtin<name, [GenTypeDoubleVecNoScalar, Double, Double, GenTypeDoubleVecNoScalar], Attr.Const>;
717  def : Builtin<name, [GenTypeHalfVecNoScalar, Half, Half, GenTypeHalfVecNoScalar], Attr.Const>;
718}
719
720
721//--------------------------------------------------------------------
722// OpenCL v1.1 s6.11.5, v1.2 s6.12.5, v2.0 s6.13.5 - Geometric Functions
723// OpenCL Extension v2.0 s5.1.4 and s6.1.4 - Geometric Functions
724// --- Table 13 ---
725// --- 1 argument ---
726foreach name = ["length"] in {
727  def : Builtin<name, [Float, GenTypeFloatVec1234], Attr.Const>;
728  def : Builtin<name, [Double, GenTypeDoubleVec1234], Attr.Const>;
729  def : Builtin<name, [Half, GenTypeHalfVec1234], Attr.Const>;
730}
731foreach name = ["normalize"] in {
732  def : Builtin<name, [GenTypeFloatVec1234, GenTypeFloatVec1234], Attr.Const>;
733  def : Builtin<name, [GenTypeDoubleVec1234, GenTypeDoubleVec1234], Attr.Const>;
734  def : Builtin<name, [GenTypeHalfVec1234, GenTypeHalfVec1234], Attr.Const>;
735}
736foreach name = ["fast_length"] in {
737  def : Builtin<name, [Float, GenTypeFloatVec1234], Attr.Const>;
738}
739foreach name = ["fast_normalize"] in {
740  def : Builtin<name, [GenTypeFloatVec1234, GenTypeFloatVec1234], Attr.Const>;
741}
742
743// --- 2 arguments ---
744foreach name = ["cross"] in {
745  foreach VSize = [3, 4] in {
746    def : Builtin<name, [VectorType<Float, VSize>, VectorType<Float, VSize>, VectorType<Float, VSize>], Attr.Const>;
747    def : Builtin<name, [VectorType<Double, VSize>, VectorType<Double, VSize>, VectorType<Double, VSize>], Attr.Const>;
748    def : Builtin<name, [VectorType<Half, VSize>, VectorType<Half, VSize>, VectorType<Half, VSize>], Attr.Const>;
749  }
750}
751foreach name = ["dot", "distance"] in {
752  def : Builtin<name, [Float, GenTypeFloatVec1234, GenTypeFloatVec1234], Attr.Const>;
753  def : Builtin<name, [Double, GenTypeDoubleVec1234, GenTypeDoubleVec1234], Attr.Const>;
754  def : Builtin<name, [Half, GenTypeHalfVec1234, GenTypeHalfVec1234], Attr.Const>;
755}
756foreach name = ["fast_distance"] in {
757  def : Builtin<name, [Float, GenTypeFloatVec1234, GenTypeFloatVec1234], Attr.Const>;
758}
759
760
761//--------------------------------------------------------------------
762// OpenCL v1.1 s6.11.6, v1.2 s6.12.6, v2.0 s6.13.6 - Relational Functions
763// OpenCL Extension v2.0 s5.1.5 and s6.1.5 - Relational Functions
764// --- Table 14 ---
765// --- 1 argument ---
766foreach name = ["isfinite", "isinf", "isnan", "isnormal", "signbit"] in {
767  def : Builtin<name, [GenTypeIntVecAndScalar, GenTypeFloatVecAndScalar], Attr.Const>;
768  def : Builtin<name, [Int, Double], Attr.Const>;
769  def : Builtin<name, [GenTypeLongVecNoScalar, GenTypeDoubleVecNoScalar], Attr.Const>;
770  def : Builtin<name, [Int, Half], Attr.Const>;
771  def : Builtin<name, [GenTypeShortVecNoScalar, GenTypeHalfVecNoScalar], Attr.Const>;
772}
773foreach name = ["any", "all"] in {
774  def : Builtin<name, [Int, SGenTypeN], Attr.Const>;
775}
776
777// --- 2 arguments ---
778foreach name = ["isequal", "isnotequal", "isgreater", "isgreaterequal",
779                "isless", "islessequal", "islessgreater", "isordered",
780                "isunordered"] in {
781  def : Builtin<name, [GenTypeIntVecAndScalar, GenTypeFloatVecAndScalar, GenTypeFloatVecAndScalar], Attr.Const>;
782  def : Builtin<name, [Int, Double, Double], Attr.Const>;
783  def : Builtin<name, [GenTypeLongVecNoScalar, GenTypeDoubleVecNoScalar, GenTypeDoubleVecNoScalar], Attr.Const>;
784  def : Builtin<name, [Int, Half, Half], Attr.Const>;
785  def : Builtin<name, [GenTypeShortVecNoScalar, GenTypeHalfVecNoScalar, GenTypeHalfVecNoScalar], Attr.Const>;
786}
787
788// --- 3 arguments ---
789foreach name = ["bitselect"] in {
790  def : Builtin<name, [AGenTypeN, AGenTypeN, AGenTypeN, AGenTypeN], Attr.Const>;
791}
792foreach name = ["select"] in {
793  def : Builtin<name, [SGenTypeN, SGenTypeN, SGenTypeN, SGenTypeN], Attr.Const>;
794  def : Builtin<name, [SGenTypeN, SGenTypeN, SGenTypeN, UGenTypeN], Attr.Const>;
795  def : Builtin<name, [UGenTypeN, UGenTypeN, UGenTypeN, UGenTypeN], Attr.Const>;
796  def : Builtin<name, [UGenTypeN, UGenTypeN, UGenTypeN, SGenTypeN], Attr.Const>;
797  def : Builtin<name, [GenTypeFloatVecAndScalar, GenTypeFloatVecAndScalar, GenTypeFloatVecAndScalar, GenTypeIntVecAndScalar], Attr.Const>;
798  def : Builtin<name, [GenTypeFloatVecAndScalar, GenTypeFloatVecAndScalar, GenTypeFloatVecAndScalar, GenTypeUIntVecAndScalar], Attr.Const>;
799  def : Builtin<name, [GenTypeDoubleVecAndScalar, GenTypeDoubleVecAndScalar, GenTypeDoubleVecAndScalar, GenTypeLongVecAndScalar], Attr.Const>;
800  def : Builtin<name, [GenTypeDoubleVecAndScalar, GenTypeDoubleVecAndScalar, GenTypeDoubleVecAndScalar, GenTypeULongVecAndScalar], Attr.Const>;
801  def : Builtin<name, [GenTypeHalfVecAndScalar, GenTypeHalfVecAndScalar, GenTypeHalfVecAndScalar, GenTypeShortVecAndScalar], Attr.Const>;
802  def : Builtin<name, [GenTypeHalfVecAndScalar, GenTypeHalfVecAndScalar, GenTypeHalfVecAndScalar, GenTypeUShortVecAndScalar], Attr.Const>;
803}
804
805
806//--------------------------------------------------------------------
807// OpenCL v1.1 s6.11.7, v1.2 s6.12.7, v2.0 s6.13.7 - Vector Data Load and Store Functions
808// OpenCL Extension v1.1 s9.3.6 and s9.6.6, v1.2 s9.5.6, v2.0 s5.1.6 and s6.1.6 - Vector Data Load and Store Functions
809// --- Table 15 ---
810multiclass VloadVstore<list<AddressSpace> addrspaces, bit defStores> {
811  foreach AS = addrspaces in {
812    foreach VSize = [2, 3, 4, 8, 16] in {
813      foreach name = ["vload" # VSize] in {
814        def : Builtin<name, [VectorType<Char, VSize>, Size, PointerType<ConstType<Char>, AS>], Attr.Pure>;
815        def : Builtin<name, [VectorType<UChar, VSize>, Size, PointerType<ConstType<UChar>, AS>], Attr.Pure>;
816        def : Builtin<name, [VectorType<Short, VSize>, Size, PointerType<ConstType<Short>, AS>], Attr.Pure>;
817        def : Builtin<name, [VectorType<UShort, VSize>, Size, PointerType<ConstType<UShort>, AS>], Attr.Pure>;
818        def : Builtin<name, [VectorType<Int, VSize>, Size, PointerType<ConstType<Int>, AS>], Attr.Pure>;
819        def : Builtin<name, [VectorType<UInt, VSize>, Size, PointerType<ConstType<UInt>, AS>], Attr.Pure>;
820        def : Builtin<name, [VectorType<Long, VSize>, Size, PointerType<ConstType<Long>, AS>], Attr.Pure>;
821        def : Builtin<name, [VectorType<ULong, VSize>, Size, PointerType<ConstType<ULong>, AS>], Attr.Pure>;
822        def : Builtin<name, [VectorType<Float, VSize>, Size, PointerType<ConstType<Float>, AS>], Attr.Pure>;
823        def : Builtin<name, [VectorType<Double, VSize>, Size, PointerType<ConstType<Double>, AS>], Attr.Pure>;
824        def : Builtin<name, [VectorType<Half, VSize>, Size, PointerType<ConstType<Half>, AS>], Attr.Pure>;
825      }
826      if defStores then {
827        foreach name = ["vstore" # VSize] in {
828          def : Builtin<name, [Void, VectorType<Char, VSize>, Size, PointerType<Char, AS>]>;
829          def : Builtin<name, [Void, VectorType<UChar, VSize>, Size, PointerType<UChar, AS>]>;
830          def : Builtin<name, [Void, VectorType<Short, VSize>, Size, PointerType<Short, AS>]>;
831          def : Builtin<name, [Void, VectorType<UShort, VSize>, Size, PointerType<UShort, AS>]>;
832          def : Builtin<name, [Void, VectorType<Int, VSize>, Size, PointerType<Int, AS>]>;
833          def : Builtin<name, [Void, VectorType<UInt, VSize>, Size, PointerType<UInt, AS>]>;
834          def : Builtin<name, [Void, VectorType<Long, VSize>, Size, PointerType<Long, AS>]>;
835          def : Builtin<name, [Void, VectorType<ULong, VSize>, Size, PointerType<ULong, AS>]>;
836          def : Builtin<name, [Void, VectorType<Float, VSize>, Size, PointerType<Float, AS>]>;
837          def : Builtin<name, [Void, VectorType<Double, VSize>, Size, PointerType<Double, AS>]>;
838          def : Builtin<name, [Void, VectorType<Half, VSize>, Size, PointerType<Half, AS>]>;
839        }
840      }
841    }
842  }
843}
844
845let Extension = FuncExtOpenCLCNamedAddressSpaceBuiltins in {
846  defm : VloadVstore<[GlobalAS, LocalAS, PrivateAS], 1>;
847}
848let Extension = FuncExtOpenCLCGenericAddressSpace in {
849  defm : VloadVstore<[GenericAS], 1>;
850}
851// vload with constant address space is available regardless of version.
852defm : VloadVstore<[ConstantAS], 0>;
853
854multiclass VloadVstoreHalf<list<AddressSpace> addrspaces, bit defStores> {
855  foreach AS = addrspaces in {
856    def : Builtin<"vload_half", [Float, Size, PointerType<ConstType<Half>, AS>], Attr.Pure>;
857    foreach VSize = [2, 3, 4, 8, 16] in {
858      foreach name = ["vload_half" # VSize, "vloada_half" # VSize] in {
859        def : Builtin<name, [VectorType<Float, VSize>, Size, PointerType<ConstType<Half>, AS>], Attr.Pure>;
860      }
861    }
862    if defStores then {
863      foreach rnd = ["", "_rte", "_rtz", "_rtp", "_rtn"] in {
864        foreach name = ["vstore_half" # rnd] in {
865          def : Builtin<name, [Void, Float, Size, PointerType<Half, AS>]>;
866          def : Builtin<name, [Void, Double, Size, PointerType<Half, AS>]>;
867        }
868        foreach VSize = [2, 3, 4, 8, 16] in {
869          foreach name = ["vstore_half" # VSize # rnd, "vstorea_half" # VSize # rnd] in {
870            def : Builtin<name, [Void, VectorType<Float, VSize>, Size, PointerType<Half, AS>]>;
871            def : Builtin<name, [Void, VectorType<Double, VSize>, Size, PointerType<Half, AS>]>;
872          }
873        }
874      }
875    }
876  }
877}
878
879let Extension = FuncExtOpenCLCNamedAddressSpaceBuiltins in {
880  defm : VloadVstoreHalf<[GlobalAS, LocalAS, PrivateAS], 1>;
881}
882let Extension = FuncExtOpenCLCGenericAddressSpace in {
883  defm : VloadVstoreHalf<[GenericAS], 1>;
884}
885// vload_half and vloada_half with constant address space are available regardless of version.
886defm : VloadVstoreHalf<[ConstantAS], 0>;
887
888// OpenCL v3.0 s6.15.8 - Synchronization Functions.
889def : Builtin<"barrier", [Void, MemFenceFlags], Attr.Convergent>;
890let MinVersion = CL20 in {
891  def : Builtin<"work_group_barrier", [Void, MemFenceFlags], Attr.Convergent>;
892  def : Builtin<"work_group_barrier", [Void, MemFenceFlags, MemoryScope], Attr.Convergent>;
893}
894
895// OpenCL v3.0 s6.15.9 - Legacy Explicit Memory Fence Functions.
896def : Builtin<"mem_fence", [Void, MemFenceFlags]>;
897def : Builtin<"read_mem_fence", [Void, MemFenceFlags]>;
898def : Builtin<"write_mem_fence", [Void, MemFenceFlags]>;
899
900// OpenCL v3.0 s6.15.10 - Address Space Qualifier Functions.
901// to_global, to_local, to_private are declared in Builtins.def.
902
903let MinVersion = CL20 in {
904  // The OpenCL 3.0 specification defines these with a "gentype" argument indicating any builtin
905  // type or user-defined type, which cannot be represented currently.  Hence we slightly diverge
906  // by providing only the following overloads with a void pointer.
907  def : Builtin<"get_fence", [MemFenceFlags, PointerType<Void, GenericAS>]>;
908  def : Builtin<"get_fence", [MemFenceFlags, PointerType<ConstType<Void>, GenericAS>]>;
909}
910
911//--------------------------------------------------------------------
912// 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
913// OpenCL Extension v2.0 s5.1.7 and s6.1.7: Async Copies from Global to Local Memory, Local to Global Memory, and Prefetch
914// --- Table 18 ---
915foreach name = ["async_work_group_copy"] in {
916  def : Builtin<name, [Event, PointerType<AGenTypeN, LocalAS>, PointerType<ConstType<AGenTypeN>, GlobalAS>, Size, Event]>;
917  def : Builtin<name, [Event, PointerType<AGenTypeN, GlobalAS>, PointerType<ConstType<AGenTypeN>, LocalAS>, Size, Event]>;
918}
919foreach name = ["async_work_group_strided_copy"] in {
920  def : Builtin<name, [Event, PointerType<AGenTypeN, LocalAS>, PointerType<ConstType<AGenTypeN>, GlobalAS>, Size, Size, Event]>;
921  def : Builtin<name, [Event, PointerType<AGenTypeN, GlobalAS>, PointerType<ConstType<AGenTypeN>, LocalAS>, Size, Size, Event]>;
922}
923foreach name = ["wait_group_events"] in {
924  def : Builtin<name, [Void, Int, PointerType<Event, GenericAS>]>;
925}
926foreach name = ["prefetch"] in {
927  def : Builtin<name, [Void, PointerType<ConstType<AGenTypeN>, GlobalAS>, Size]>;
928}
929
930//--------------------------------------------------------------------
931// OpenCL v2.0 s6.13.11 - Atomics Functions.
932// Functions that use memory_order and cl_mem_fence_flags enums are not
933// declared here as the TableGen backend does not handle enums.
934
935// OpenCL v1.0 s9.5, s9.6, s9.7 - Atomic Functions for 32-bit integers
936// --- Table 9.1 ---
937let Extension = FuncExtKhrGlobalInt32BaseAtomics in {
938  foreach Type = [Int, UInt] in {
939    foreach name = ["atom_add", "atom_sub", "atom_xchg"] in {
940      def : Builtin<name, [Type, PointerType<VolatileType<Type>, GlobalAS>, Type]>;
941    }
942    foreach name = ["atom_inc", "atom_dec"] in {
943      def : Builtin<name, [Type, PointerType<VolatileType<Type>, GlobalAS>]>;
944    }
945    foreach name = ["atom_cmpxchg"] in {
946      def : Builtin<name, [Type, PointerType<VolatileType<Type>, GlobalAS>, Type, Type]>;
947    }
948  }
949}
950// --- Table 9.3 ---
951let Extension = FuncExtKhrLocalInt32BaseAtomics in {
952  foreach Type = [Int, UInt] in {
953    foreach name = ["atom_add", "atom_sub", "atom_xchg"] in {
954      def : Builtin<name, [Type, PointerType<VolatileType<Type>, LocalAS>, Type]>;
955    }
956    foreach name = ["atom_inc", "atom_dec"] in {
957      def : Builtin<name, [Type, PointerType<VolatileType<Type>, LocalAS>]>;
958    }
959    foreach name = ["atom_cmpxchg"] in {
960      def : Builtin<name, [Type, PointerType<VolatileType<Type>, LocalAS>, Type, Type]>;
961    }
962  }
963}
964// --- Table 9.5 ---
965let Extension = FuncExtKhrInt64BaseAtomics in {
966  foreach AS = [GlobalAS, LocalAS] in {
967    foreach Type = [Long, ULong] in {
968      foreach name = ["atom_add", "atom_sub", "atom_xchg"] in {
969        def : Builtin<name, [Type, PointerType<VolatileType<Type>, AS>, Type]>;
970      }
971      foreach name = ["atom_inc", "atom_dec"] in {
972        def : Builtin<name, [Type, PointerType<VolatileType<Type>, AS>]>;
973      }
974      foreach name = ["atom_cmpxchg"] in {
975        def : Builtin<name, [Type, PointerType<VolatileType<Type>, AS>, Type, Type]>;
976      }
977    }
978  }
979}
980// --- Table 9.2 ---
981let Extension = FuncExtKhrGlobalInt32ExtendedAtomics in {
982  foreach Type = [Int, UInt] in {
983    foreach name = ["atom_min", "atom_max", "atom_and",
984                    "atom_or", "atom_xor"] in {
985      def : Builtin<name, [Type, PointerType<VolatileType<Type>, GlobalAS>, Type]>;
986    }
987  }
988}
989// --- Table 9.4 ---
990let Extension = FuncExtKhrLocalInt32ExtendedAtomics in {
991  foreach Type = [Int, UInt] in {
992    foreach name = ["atom_min", "atom_max", "atom_and",
993                    "atom_or", "atom_xor"] in {
994      def : Builtin<name, [Type, PointerType<VolatileType<Type>, LocalAS>, Type]>;
995    }
996  }
997}
998// --- Table 9.6 ---
999let Extension = FuncExtKhrInt64ExtendedAtomics in {
1000  foreach AS = [GlobalAS, LocalAS] in {
1001    foreach Type = [Long, ULong] in {
1002      foreach name = ["atom_min", "atom_max", "atom_and",
1003                      "atom_or", "atom_xor"] in {
1004        def : Builtin<name, [Type, PointerType<VolatileType<Type>, AS>, Type]>;
1005      }
1006    }
1007  }
1008}
1009// OpenCL v1.1 s6.11.1, v1.2 s6.12.11 - Atomic Functions
1010foreach AS = [GlobalAS, LocalAS] in {
1011  def : Builtin<"atomic_xchg", [Float, PointerType<VolatileType<Float>, AS>, Float]>;
1012  foreach Type = [Int, UInt] in {
1013    foreach name = ["atomic_add", "atomic_sub", "atomic_xchg",
1014                    "atomic_min", "atomic_max", "atomic_and",
1015                    "atomic_or", "atomic_xor"] in {
1016      def : Builtin<name, [Type, PointerType<VolatileType<Type>, AS>, Type]>;
1017    }
1018    foreach name = ["atomic_inc", "atomic_dec"] in {
1019      def : Builtin<name, [Type, PointerType<VolatileType<Type>, AS>]>;
1020    }
1021    foreach name = ["atomic_cmpxchg"] in {
1022      def : Builtin<name, [Type, PointerType<VolatileType<Type>, AS>, Type, Type]>;
1023    }
1024  }
1025}
1026
1027let Extension = FuncExtOpenCLCxx in {
1028  foreach Type = [Int, UInt] in {
1029    foreach name = ["atomic_add", "atomic_sub", "atomic_xchg",
1030                    "atomic_min", "atomic_max", "atomic_and",
1031                    "atomic_or", "atomic_xor"] in {
1032      def : Builtin<name, [Type, PointerType<VolatileType<Type>, GenericAS>, Type]>;
1033    }
1034    foreach name = ["atomic_inc", "atomic_dec"] in {
1035      def : Builtin<name, [Type, PointerType<VolatileType<Type>, GenericAS>]>;
1036    }
1037    foreach name = ["atomic_cmpxchg"] in {
1038      def : Builtin<name, [Type, PointerType<VolatileType<Type>, GenericAS>, Type, Type]>;
1039    }
1040  }
1041}
1042
1043// OpenCL v2.0 s6.13.11 - Atomic Functions.
1044let MinVersion = CL20 in {
1045  def : Builtin<"atomic_work_item_fence", [Void, MemFenceFlags, MemoryOrder, MemoryScope]>;
1046
1047  foreach TypePair = [[AtomicInt, Int], [AtomicUInt, UInt],
1048                      [AtomicLong, Long], [AtomicULong, ULong],
1049                      [AtomicFloat, Float], [AtomicDouble, Double]] in {
1050    def : Builtin<"atomic_init",
1051        [Void, PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[1]]>;
1052    def : Builtin<"atomic_store",
1053        [Void, PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[1]]>;
1054    def : Builtin<"atomic_store_explicit",
1055        [Void, PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[1], MemoryOrder]>;
1056    def : Builtin<"atomic_store_explicit",
1057        [Void, PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[1], MemoryOrder, MemoryScope]>;
1058    def : Builtin<"atomic_load",
1059        [TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>]>;
1060    def : Builtin<"atomic_load_explicit",
1061        [TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, MemoryOrder]>;
1062    def : Builtin<"atomic_load_explicit",
1063        [TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, MemoryOrder, MemoryScope]>;
1064    def : Builtin<"atomic_exchange",
1065        [TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[1]]>;
1066    def : Builtin<"atomic_exchange_explicit",
1067        [TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[1], MemoryOrder]>;
1068    def : Builtin<"atomic_exchange_explicit",
1069        [TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[1], MemoryOrder, MemoryScope]>;
1070    foreach Variant = ["weak", "strong"] in {
1071      def : Builtin<"atomic_compare_exchange_" # Variant,
1072          [Bool, PointerType<VolatileType<TypePair[0]>, GenericAS>,
1073           PointerType<TypePair[1], GenericAS>, TypePair[1]]>;
1074      def : Builtin<"atomic_compare_exchange_" # Variant # "_explicit",
1075          [Bool, PointerType<VolatileType<TypePair[0]>, GenericAS>,
1076           PointerType<TypePair[1], GenericAS>, TypePair[1], MemoryOrder, MemoryOrder]>;
1077      def : Builtin<"atomic_compare_exchange_" # Variant # "_explicit",
1078          [Bool, PointerType<VolatileType<TypePair[0]>, GenericAS>,
1079           PointerType<TypePair[1], GenericAS>, TypePair[1], MemoryOrder, MemoryOrder, MemoryScope]>;
1080    }
1081  }
1082
1083  foreach TypePair = [[AtomicInt, Int, Int], [AtomicUInt, UInt, UInt],
1084                      [AtomicLong, Long, Long], [AtomicULong, ULong, ULong],
1085                      [AtomicUIntPtr, UIntPtr, PtrDiff]] in {
1086    foreach ModOp = ["add", "sub"] in {
1087      def : Builtin<"atomic_fetch_" # ModOp,
1088          [TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[2]]>;
1089      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1090          [TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[2], MemoryOrder]>;
1091      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1092          [TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[2], MemoryOrder, MemoryScope]>;
1093    }
1094  }
1095  foreach TypePair = [[AtomicInt, Int, Int], [AtomicUInt, UInt, UInt],
1096                      [AtomicLong, Long, Long], [AtomicULong, ULong, ULong]] in {
1097    foreach ModOp = ["or", "xor", "and", "min", "max"] in {
1098      def : Builtin<"atomic_fetch_" # ModOp,
1099          [TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[2]]>;
1100      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1101          [TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[2], MemoryOrder]>;
1102      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1103          [TypePair[1], PointerType<VolatileType<TypePair[0]>, GenericAS>, TypePair[2], MemoryOrder, MemoryScope]>;
1104    }
1105  }
1106
1107  def : Builtin<"atomic_flag_clear",
1108      [Void, PointerType<VolatileType<AtomicFlag>, GenericAS>]>;
1109  def : Builtin<"atomic_flag_clear_explicit",
1110      [Void, PointerType<VolatileType<AtomicFlag>, GenericAS>, MemoryOrder]>;
1111  def : Builtin<"atomic_flag_clear_explicit",
1112      [Void, PointerType<VolatileType<AtomicFlag>, GenericAS>, MemoryOrder, MemoryScope]>;
1113
1114  def : Builtin<"atomic_flag_test_and_set",
1115      [Bool, PointerType<VolatileType<AtomicFlag>, GenericAS>]>;
1116  def : Builtin<"atomic_flag_test_and_set_explicit",
1117      [Bool, PointerType<VolatileType<AtomicFlag>, GenericAS>, MemoryOrder]>;
1118  def : Builtin<"atomic_flag_test_and_set_explicit",
1119      [Bool, PointerType<VolatileType<AtomicFlag>, GenericAS>, MemoryOrder, MemoryScope]>;
1120}
1121
1122// The functionality added by cl_ext_float_atomics extension
1123let MinVersion = CL20 in {
1124  let Extension = FuncExtFloatAtomicsFp16GlobalLoadStore in {
1125    def : Builtin<"atomic_store",
1126        [Void, PointerType<VolatileType<AtomicHalf>, GlobalAS>, AtomicHalf]>;
1127    def : Builtin<"atomic_store_explicit",
1128        [Void, PointerType<VolatileType<AtomicHalf>, GlobalAS>, AtomicHalf, MemoryOrder]>;
1129    def : Builtin<"atomic_store_explicit",
1130        [Void, PointerType<VolatileType<AtomicHalf>, GlobalAS>, AtomicHalf, MemoryOrder, MemoryScope]>;
1131    def : Builtin<"atomic_load",
1132        [Half, PointerType<VolatileType<AtomicHalf>, GlobalAS>]>;
1133    def : Builtin<"atomic_load_explicit",
1134        [Half, PointerType<VolatileType<AtomicHalf>, GlobalAS>, MemoryOrder]>;
1135    def : Builtin<"atomic_load_explicit",
1136        [Half, PointerType<VolatileType<AtomicHalf>, GlobalAS>, MemoryOrder, MemoryScope]>;
1137    def : Builtin<"atomic_exchange",
1138        [Half, PointerType<VolatileType<AtomicHalf>, GlobalAS>, Half]>;
1139    def : Builtin<"atomic_exchange_explicit",
1140        [Half, PointerType<VolatileType<AtomicHalf>, GlobalAS>, Half, MemoryOrder]>;
1141    def : Builtin<"atomic_exchange_explicit",
1142        [Half, PointerType<VolatileType<AtomicHalf>, GlobalAS>, Half, MemoryOrder, MemoryScope]>;
1143  }
1144  let Extension = FuncExtFloatAtomicsFp16LocalLoadStore in {
1145    def : Builtin<"atomic_store",
1146        [Void, PointerType<VolatileType<AtomicHalf>, LocalAS>, AtomicHalf]>;
1147    def : Builtin<"atomic_store_explicit",
1148        [Void, PointerType<VolatileType<AtomicHalf>, LocalAS>, AtomicHalf, MemoryOrder]>;
1149    def : Builtin<"atomic_store_explicit",
1150        [Void, PointerType<VolatileType<AtomicHalf>, LocalAS>, AtomicHalf, MemoryOrder, MemoryScope]>;
1151    def : Builtin<"atomic_load",
1152        [Half, PointerType<VolatileType<AtomicHalf>, LocalAS>]>;
1153    def : Builtin<"atomic_load_explicit",
1154        [Half, PointerType<VolatileType<AtomicHalf>, LocalAS>, MemoryOrder]>;
1155    def : Builtin<"atomic_load_explicit",
1156        [Half, PointerType<VolatileType<AtomicHalf>, LocalAS>, MemoryOrder, MemoryScope]>;
1157    def : Builtin<"atomic_exchange",
1158        [Half, PointerType<VolatileType<AtomicHalf>, LocalAS>, Half]>;
1159    def : Builtin<"atomic_exchange_explicit",
1160        [Half, PointerType<VolatileType<AtomicHalf>, LocalAS>, Half, MemoryOrder]>;
1161    def : Builtin<"atomic_exchange_explicit",
1162        [Half, PointerType<VolatileType<AtomicHalf>, LocalAS>, Half, MemoryOrder, MemoryScope]>;
1163  }
1164  let Extension = FuncExtFloatAtomicsFp16GenericLoadStore in {
1165    def : Builtin<"atomic_store",
1166        [Void, PointerType<VolatileType<AtomicHalf>, GenericAS>, AtomicHalf]>;
1167    def : Builtin<"atomic_store_explicit",
1168        [Void, PointerType<VolatileType<AtomicHalf>, GenericAS>, AtomicHalf, MemoryOrder]>;
1169    def : Builtin<"atomic_store_explicit",
1170        [Void, PointerType<VolatileType<AtomicHalf>, GenericAS>, AtomicHalf, MemoryOrder, MemoryScope]>;
1171    def : Builtin<"atomic_load",
1172        [Half, PointerType<VolatileType<AtomicHalf>, GenericAS>]>;
1173    def : Builtin<"atomic_load_explicit",
1174        [Half, PointerType<VolatileType<AtomicHalf>, GenericAS>, MemoryOrder]>;
1175    def : Builtin<"atomic_load_explicit",
1176        [Half, PointerType<VolatileType<AtomicHalf>, GenericAS>, MemoryOrder, MemoryScope]>;
1177    def : Builtin<"atomic_exchange",
1178        [Half, PointerType<VolatileType<AtomicHalf>, GenericAS>, Half]>;
1179    def : Builtin<"atomic_exchange_explicit",
1180        [Half, PointerType<VolatileType<AtomicHalf>, GenericAS>, Half, MemoryOrder]>;
1181    def : Builtin<"atomic_exchange_explicit",
1182        [Half, PointerType<VolatileType<AtomicHalf>, GenericAS>, Half, MemoryOrder, MemoryScope]>;
1183  }
1184  foreach ModOp = ["add", "sub"] in {
1185    let Extension = FuncExtFloatAtomicsFp16GlobalAdd in {
1186      def : Builtin<"atomic_fetch_" # ModOp,
1187          [Half, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Half]>;
1188      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1189          [Half, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Half, MemoryOrder]>;
1190      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1191          [Half, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Half, MemoryOrder, MemoryScope]>;
1192    }
1193    let Extension = FuncExtFloatAtomicsFp32GlobalAdd in {
1194      def : Builtin<"atomic_fetch_" # ModOp,
1195          [Float, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Float]>;
1196      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1197          [Float, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Float, MemoryOrder]>;
1198      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1199          [Float, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Float, MemoryOrder, MemoryScope]>;
1200    }
1201    let Extension = FuncExtFloatAtomicsFp64GlobalAdd in {
1202      def : Builtin<"atomic_fetch_" # ModOp,
1203          [Double, PointerType<VolatileType<AtomicDouble>, GlobalAS>, Double]>;
1204      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1205          [Double, PointerType<VolatileType<AtomicDouble>, GlobalAS>, Double, MemoryOrder]>;
1206      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1207          [Double, PointerType<VolatileType<AtomicDouble>, GlobalAS>, Double, MemoryOrder, MemoryScope]>;
1208    }
1209    let Extension = FuncExtFloatAtomicsFp16LocalAdd in {
1210      def : Builtin<"atomic_fetch_" # ModOp,
1211          [Half, PointerType<VolatileType<AtomicFloat>, LocalAS>, Half]>;
1212      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1213          [Half, PointerType<VolatileType<AtomicFloat>, LocalAS>, Half, MemoryOrder]>;
1214      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1215          [Half, PointerType<VolatileType<AtomicFloat>, LocalAS>, Half, MemoryOrder, MemoryScope]>;
1216    }
1217    let Extension = FuncExtFloatAtomicsFp32LocalAdd in {
1218      def : Builtin<"atomic_fetch_" # ModOp,
1219          [Float, PointerType<VolatileType<AtomicFloat>, LocalAS>, Float]>;
1220      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1221          [Float, PointerType<VolatileType<AtomicFloat>, LocalAS>, Float, MemoryOrder]>;
1222      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1223          [Float, PointerType<VolatileType<AtomicFloat>, LocalAS>, Float, MemoryOrder, MemoryScope]>;
1224    }
1225    let Extension = FuncExtFloatAtomicsFp64LocalAdd in {
1226      def : Builtin<"atomic_fetch_" # ModOp,
1227          [Double, PointerType<VolatileType<AtomicDouble>, LocalAS>, Double]>;
1228      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1229          [Double, PointerType<VolatileType<AtomicDouble>, LocalAS>, Double, MemoryOrder]>;
1230      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1231          [Double, PointerType<VolatileType<AtomicDouble>, LocalAS>, Double, MemoryOrder, MemoryScope]>;
1232    }
1233    let Extension = FuncExtFloatAtomicsFp16GenericAdd in {
1234      def : Builtin<"atomic_fetch_" # ModOp,
1235          [Half, PointerType<VolatileType<AtomicFloat>, GenericAS>, Half]>;
1236      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1237          [Half, PointerType<VolatileType<AtomicFloat>, GenericAS>, Half, MemoryOrder]>;
1238      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1239          [Half, PointerType<VolatileType<AtomicFloat>, GenericAS>, Half, MemoryOrder, MemoryScope]>;
1240    }
1241    let Extension = FuncExtFloatAtomicsFp32GenericAdd in {
1242      def : Builtin<"atomic_fetch_" # ModOp,
1243          [Float, PointerType<VolatileType<AtomicFloat>, GenericAS>, Float]>;
1244      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1245          [Float, PointerType<VolatileType<AtomicFloat>, GenericAS>, Float, MemoryOrder]>;
1246      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1247          [Float, PointerType<VolatileType<AtomicFloat>, GenericAS>, Float, MemoryOrder, MemoryScope]>;
1248    }
1249    let Extension = FuncExtFloatAtomicsFp64GenericAdd in {
1250      def : Builtin<"atomic_fetch_" # ModOp,
1251          [Double, PointerType<VolatileType<AtomicDouble>, GenericAS>, Double]>;
1252      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1253          [Double, PointerType<VolatileType<AtomicDouble>, GenericAS>, Double, MemoryOrder]>;
1254      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1255          [Double, PointerType<VolatileType<AtomicDouble>, GenericAS>, Double, MemoryOrder, MemoryScope]>;
1256    }
1257  }
1258  foreach ModOp = ["min", "max"] in {
1259    let Extension = FuncExtFloatAtomicsFp16GlobalMinMax in {
1260      def : Builtin<"atomic_fetch_" # ModOp,
1261          [Half, PointerType<VolatileType<AtomicHalf>, GlobalAS>, Half]>;
1262      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1263          [Half, PointerType<VolatileType<AtomicHalf>, GlobalAS>, Half, MemoryOrder]>;
1264      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1265          [Half, PointerType<VolatileType<AtomicHalf>, GlobalAS>, Half, MemoryOrder, MemoryScope]>;
1266    }
1267    let Extension = FuncExtFloatAtomicsFp32GlobalMinMax in {
1268      def : Builtin<"atomic_fetch_" # ModOp,
1269          [Float, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Float]>;
1270      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1271          [Float, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Float, MemoryOrder]>;
1272      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1273          [Float, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Float, MemoryOrder, MemoryScope]>;
1274    }
1275    let Extension = FuncExtFloatAtomicsFp64GlobalMinMax in {
1276      def : Builtin<"atomic_fetch_" # ModOp,
1277          [Double, PointerType<VolatileType<AtomicDouble>, GlobalAS>, Double]>;
1278      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1279          [Double, PointerType<VolatileType<AtomicDouble>, GlobalAS>, Double, MemoryOrder]>;
1280      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1281          [Double, PointerType<VolatileType<AtomicDouble>, GlobalAS>, Double, MemoryOrder, MemoryScope]>;
1282    }
1283    let Extension = FuncExtFloatAtomicsFp16LocalMinMax in {
1284      def : Builtin<"atomic_fetch_" # ModOp,
1285          [Half, PointerType<VolatileType<AtomicHalf>, LocalAS>, Half]>;
1286      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1287          [Half, PointerType<VolatileType<AtomicHalf>, LocalAS>, Half, MemoryOrder]>;
1288      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1289          [Half, PointerType<VolatileType<AtomicHalf>, LocalAS>, Half, MemoryOrder, MemoryScope]>;
1290    }
1291    let Extension = FuncExtFloatAtomicsFp32LocalMinMax in {
1292      def : Builtin<"atomic_fetch_" # ModOp,
1293          [Float, PointerType<VolatileType<AtomicFloat>, LocalAS>, Float]>;
1294      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1295          [Float, PointerType<VolatileType<AtomicFloat>, LocalAS>, Float, MemoryOrder]>;
1296      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1297          [Float, PointerType<VolatileType<AtomicFloat>, LocalAS>, Float, MemoryOrder, MemoryScope]>;
1298    }
1299    let Extension = FuncExtFloatAtomicsFp64LocalMinMax in {
1300      def : Builtin<"atomic_fetch_" # ModOp,
1301          [Double, PointerType<VolatileType<AtomicDouble>, LocalAS>, Double]>;
1302      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1303          [Double, PointerType<VolatileType<AtomicDouble>, LocalAS>, Double, MemoryOrder]>;
1304      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1305          [Double, PointerType<VolatileType<AtomicDouble>, LocalAS>, Double, MemoryOrder, MemoryScope]>;
1306    }
1307    let Extension = FuncExtFloatAtomicsFp16GenericMinMax in {
1308      def : Builtin<"atomic_fetch_" # ModOp,
1309          [Half, PointerType<VolatileType<AtomicHalf>, GenericAS>, Half]>;
1310      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1311          [Half, PointerType<VolatileType<AtomicHalf>, GenericAS>, Half, MemoryOrder]>;
1312      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1313          [Half, PointerType<VolatileType<AtomicHalf>, GenericAS>, Half, MemoryOrder, MemoryScope]>;
1314    }
1315    let Extension = FuncExtFloatAtomicsFp32GenericMinMax in {
1316      def : Builtin<"atomic_fetch_" # ModOp,
1317          [Float, PointerType<VolatileType<AtomicFloat>, GenericAS>, Float]>;
1318      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1319          [Float, PointerType<VolatileType<AtomicFloat>, GenericAS>, Float, MemoryOrder]>;
1320      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1321          [Float, PointerType<VolatileType<AtomicFloat>, GenericAS>, Float, MemoryOrder, MemoryScope]>;
1322    }
1323    let Extension = FuncExtFloatAtomicsFp64GenericMinMax in {
1324      def : Builtin<"atomic_fetch_" # ModOp,
1325          [Double, PointerType<VolatileType<AtomicDouble>, GenericAS>, Double]>;
1326      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1327          [Double, PointerType<VolatileType<AtomicDouble>, GenericAS>, Double, MemoryOrder]>;
1328      def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
1329          [Double, PointerType<VolatileType<AtomicDouble>, GenericAS>, Double, MemoryOrder, MemoryScope]>;
1330    }
1331  }
1332}
1333
1334//--------------------------------------------------------------------
1335// OpenCL v1.1 s6.11.12, v1.2 s6.12.12, v2.0 s6.13.12 - Miscellaneous Vector Functions
1336// --- Table 19 ---
1337foreach VSize1 = [2, 4, 8, 16] in {
1338  foreach VSize2 = [2, 4, 8, 16] in {
1339    foreach VecAndMaskType = [[Char, UChar], [UChar, UChar],
1340                              [Short, UShort], [UShort, UShort],
1341                              [Int, UInt], [UInt, UInt],
1342                              [Long, ULong], [ULong, ULong],
1343                              [Float, UInt], [Double, ULong], [Half, UShort]] in {
1344      def : Builtin<"shuffle", [VectorType<VecAndMaskType[0], VSize1>,
1345                                VectorType<VecAndMaskType[0], VSize2>,
1346                                VectorType<VecAndMaskType[1], VSize1>],
1347                               Attr.Const>;
1348    }
1349  }
1350}
1351foreach VSize1 = [2, 4, 8, 16] in {
1352  foreach VSize2 = [2, 4, 8, 16] in {
1353    foreach VecAndMaskType = [[Char, UChar], [UChar, UChar],
1354                              [Short, UShort], [UShort, UShort],
1355                              [Int, UInt], [UInt, UInt],
1356                              [Long, ULong], [ULong, ULong],
1357                              [Float, UInt], [Double, ULong], [Half, UShort]] in {
1358      def : Builtin<"shuffle2", [VectorType<VecAndMaskType[0], VSize1>,
1359                                 VectorType<VecAndMaskType[0], VSize2>,
1360                                 VectorType<VecAndMaskType[0], VSize2>,
1361                                 VectorType<VecAndMaskType[1], VSize1>],
1362                                Attr.Const>;
1363    }
1364  }
1365}
1366
1367//--------------------------------------------------------------------
1368// OpenCL v1.1 s6.11.3, v1.2 s6.12.14, v2.0 s6.13.14: Image Read and Write Functions
1369// OpenCL Extension v2.0 s5.1.8 and s6.1.8: Image Read and Write Functions
1370// --- Table 22: Image Read Functions with Samplers ---
1371foreach imgTy = [Image1d] in {
1372  foreach coordTy = [Int, Float] in {
1373    def : Builtin<"read_imagef", [VectorType<Float, 4>, ImageType<imgTy, "RO">, Sampler, coordTy], Attr.Pure>;
1374    def : Builtin<"read_imagei", [VectorType<Int, 4>, ImageType<imgTy, "RO">, Sampler, coordTy], Attr.Pure>;
1375    def : Builtin<"read_imageui", [VectorType<UInt, 4>, ImageType<imgTy, "RO">, Sampler, coordTy], Attr.Pure>;
1376  }
1377}
1378foreach imgTy = [Image2d, Image1dArray] in {
1379  foreach coordTy = [Int, Float] in {
1380    def : Builtin<"read_imagef", [VectorType<Float, 4>, ImageType<imgTy, "RO">, Sampler, VectorType<coordTy, 2>], Attr.Pure>;
1381    def : Builtin<"read_imagei", [VectorType<Int, 4>, ImageType<imgTy, "RO">, Sampler, VectorType<coordTy, 2>], Attr.Pure>;
1382    def : Builtin<"read_imageui", [VectorType<UInt, 4>, ImageType<imgTy, "RO">, Sampler, VectorType<coordTy, 2>], Attr.Pure>;
1383  }
1384}
1385foreach imgTy = [Image3d, Image2dArray] in {
1386  foreach coordTy = [Int, Float] in {
1387    def : Builtin<"read_imagef", [VectorType<Float, 4>, ImageType<imgTy, "RO">, Sampler, VectorType<coordTy, 4>], Attr.Pure>;
1388    def : Builtin<"read_imagei", [VectorType<Int, 4>, ImageType<imgTy, "RO">, Sampler, VectorType<coordTy, 4>], Attr.Pure>;
1389    def : Builtin<"read_imageui", [VectorType<UInt, 4>, ImageType<imgTy, "RO">, Sampler, VectorType<coordTy, 4>], Attr.Pure>;
1390  }
1391}
1392foreach coordTy = [Int, Float] in {
1393  def : Builtin<"read_imagef", [Float, ImageType<Image2dDepth, "RO">, Sampler, VectorType<coordTy, 2>], Attr.Pure>;
1394  def : Builtin<"read_imagef", [Float, ImageType<Image2dArrayDepth, "RO">, Sampler, VectorType<coordTy, 4>], Attr.Pure>;
1395}
1396
1397// --- Table 23: Sampler-less Read Functions ---
1398multiclass ImageReadSamplerless<string aQual> {
1399  foreach imgTy = [Image2d, Image1dArray] in {
1400    def : Builtin<"read_imagef", [VectorType<Float, 4>, ImageType<imgTy, aQual>, VectorType<Int, 2>], Attr.Pure>;
1401    def : Builtin<"read_imagei", [VectorType<Int, 4>, ImageType<imgTy, aQual>, VectorType<Int, 2>], Attr.Pure>;
1402    def : Builtin<"read_imageui", [VectorType<UInt, 4>, ImageType<imgTy, aQual>, VectorType<Int, 2>], Attr.Pure>;
1403  }
1404  foreach imgTy = [Image3d, Image2dArray] in {
1405    def : Builtin<"read_imagef", [VectorType<Float, 4>, ImageType<imgTy, aQual>, VectorType<Int, 4>], Attr.Pure>;
1406    def : Builtin<"read_imagei", [VectorType<Int, 4>, ImageType<imgTy, aQual>, VectorType<Int, 4>], Attr.Pure>;
1407    def : Builtin<"read_imageui", [VectorType<UInt, 4>, ImageType<imgTy, aQual>, VectorType<Int, 4>], Attr.Pure>;
1408  }
1409  foreach imgTy = [Image1d, Image1dBuffer] in {
1410    def : Builtin<"read_imagef", [VectorType<Float, 4>, ImageType<imgTy, aQual>, Int], Attr.Pure>;
1411    def : Builtin<"read_imagei", [VectorType<Int, 4>, ImageType<imgTy, aQual>, Int], Attr.Pure>;
1412    def : Builtin<"read_imageui", [VectorType<UInt, 4>, ImageType<imgTy, aQual>, Int], Attr.Pure>;
1413  }
1414  def : Builtin<"read_imagef", [Float, ImageType<Image2dDepth, aQual>, VectorType<Int, 2>], Attr.Pure>;
1415  def : Builtin<"read_imagef", [Float, ImageType<Image2dArrayDepth, aQual>, VectorType<Int, 4>], Attr.Pure>;
1416}
1417
1418let MinVersion = CL12 in {
1419  defm : ImageReadSamplerless<"RO">;
1420  let Extension = FuncExtOpenCLCReadWriteImages in {
1421    defm : ImageReadSamplerless<"RW">;
1422  }
1423}
1424
1425// --- Table 24: Image Write Functions ---
1426multiclass ImageWrite<string aQual> {
1427  foreach imgTy = [Image2d] in {
1428    def : Builtin<"write_imagef", [Void, ImageType<imgTy, aQual>, VectorType<Int, 2>, VectorType<Float, 4>]>;
1429    def : Builtin<"write_imagei", [Void, ImageType<imgTy, aQual>, VectorType<Int, 2>, VectorType<Int, 4>]>;
1430    def : Builtin<"write_imageui", [Void, ImageType<imgTy, aQual>, VectorType<Int, 2>, VectorType<UInt, 4>]>;
1431  }
1432  foreach imgTy = [Image2dArray] in {
1433    def : Builtin<"write_imagef", [Void, ImageType<imgTy, aQual>, VectorType<Int, 4>, VectorType<Float, 4>]>;
1434    def : Builtin<"write_imagei", [Void, ImageType<imgTy, aQual>, VectorType<Int, 4>, VectorType<Int, 4>]>;
1435    def : Builtin<"write_imageui", [Void, ImageType<imgTy, aQual>, VectorType<Int, 4>, VectorType<UInt, 4>]>;
1436  }
1437  foreach imgTy = [Image1d, Image1dBuffer] in {
1438    def : Builtin<"write_imagef", [Void, ImageType<imgTy, aQual>, Int, VectorType<Float, 4>]>;
1439    def : Builtin<"write_imagei", [Void, ImageType<imgTy, aQual>, Int, VectorType<Int, 4>]>;
1440    def : Builtin<"write_imageui", [Void, ImageType<imgTy, aQual>, Int, VectorType<UInt, 4>]>;
1441  }
1442  foreach imgTy = [Image1dArray] in {
1443    def : Builtin<"write_imagef", [Void, ImageType<imgTy, aQual>, VectorType<Int, 2>, VectorType<Float, 4>]>;
1444    def : Builtin<"write_imagei", [Void, ImageType<imgTy, aQual>, VectorType<Int, 2>, VectorType<Int, 4>]>;
1445    def : Builtin<"write_imageui", [Void, ImageType<imgTy, aQual>, VectorType<Int, 2>, VectorType<UInt, 4>]>;
1446  }
1447  foreach imgTy = [Image3d] in {
1448    def : Builtin<"write_imagef", [Void, ImageType<imgTy, aQual>, VectorType<Int, 4>, VectorType<Float, 4>]>;
1449    def : Builtin<"write_imagei", [Void, ImageType<imgTy, aQual>, VectorType<Int, 4>, VectorType<Int, 4>]>;
1450    def : Builtin<"write_imageui", [Void, ImageType<imgTy, aQual>, VectorType<Int, 4>, VectorType<UInt, 4>]>;
1451  }
1452  def : Builtin<"write_imagef", [Void, ImageType<Image2dDepth, aQual>, VectorType<Int, 2>, Float]>;
1453  def : Builtin<"write_imagef", [Void, ImageType<Image2dArrayDepth, aQual>, VectorType<Int, 4>, Float]>;
1454}
1455
1456defm : ImageWrite<"WO">;
1457let Extension = FuncExtOpenCLCReadWriteImages in {
1458  defm : ImageWrite<"RW">;
1459}
1460
1461// --- Table 25: Image Query Functions ---
1462multiclass ImageQuery<string aQual> {
1463  foreach imgTy = [Image1d, Image1dBuffer, Image2d, Image3d,
1464                   Image1dArray, Image2dArray, Image2dDepth,
1465                   Image2dArrayDepth] in {
1466    foreach name = ["get_image_width", "get_image_channel_data_type",
1467                    "get_image_channel_order"] in {
1468      def : Builtin<name, [Int, ImageType<imgTy, aQual>], Attr.Const>;
1469    }
1470  }
1471  foreach imgTy = [Image2d, Image3d, Image2dArray, Image2dDepth,
1472                   Image2dArrayDepth] in {
1473    def : Builtin<"get_image_height", [Int, ImageType<imgTy, aQual>], Attr.Const>;
1474  }
1475  def : Builtin<"get_image_depth", [Int, ImageType<Image3d, aQual>], Attr.Const>;
1476  foreach imgTy = [Image2d, Image2dArray, Image2dDepth,
1477                   Image2dArrayDepth] in {
1478    def : Builtin<"get_image_dim", [VectorType<Int, 2>, ImageType<imgTy, aQual>], Attr.Const>;
1479  }
1480  def : Builtin<"get_image_dim", [VectorType<Int, 4>, ImageType<Image3d, aQual>], Attr.Const>;
1481  foreach imgTy = [Image1dArray, Image2dArray, Image2dArrayDepth] in {
1482    def : Builtin<"get_image_array_size", [Size, ImageType<imgTy, aQual>], Attr.Const>;
1483  }
1484}
1485
1486defm : ImageQuery<"RO">;
1487defm : ImageQuery<"WO">;
1488let Extension = FuncExtOpenCLCReadWriteImages in {
1489  defm : ImageQuery<"RW">;
1490}
1491
1492// OpenCL extension v2.0 s5.1.9: Built-in Image Read Functions
1493// --- Table 8 ---
1494foreach aQual = ["RO"] in {
1495  foreach name = ["read_imageh"] in {
1496    foreach coordTy = [Int, Float] in {
1497      foreach imgTy = [Image2d, Image1dArray] in {
1498        def : Builtin<name, [VectorType<Half, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<coordTy, 2>], Attr.Pure>;
1499      }
1500      foreach imgTy = [Image3d, Image2dArray] in {
1501        def : Builtin<name, [VectorType<Half, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<coordTy, 4>], Attr.Pure>;
1502      }
1503      foreach imgTy = [Image1d] in {
1504        def : Builtin<name, [VectorType<Half, 4>, ImageType<imgTy, aQual>, Sampler, coordTy], Attr.Pure>;
1505      }
1506    }
1507  }
1508}
1509// OpenCL extension v2.0 s5.1.10: Built-in Image Sampler-less Read Functions
1510// --- Table 9 ---
1511let MinVersion = CL12 in {
1512  multiclass ImageReadHalf<string aQual> {
1513    foreach name = ["read_imageh"] in {
1514      foreach imgTy = [Image2d, Image1dArray] in {
1515        def : Builtin<name, [VectorType<Half, 4>, ImageType<imgTy, aQual>, VectorType<Int, 2>], Attr.Pure>;
1516      }
1517      foreach imgTy = [Image3d, Image2dArray] in {
1518        def : Builtin<name, [VectorType<Half, 4>, ImageType<imgTy, aQual>, VectorType<Int, 4>], Attr.Pure>;
1519      }
1520      foreach imgTy = [Image1d, Image1dBuffer] in {
1521        def : Builtin<name, [VectorType<Half, 4>, ImageType<imgTy, aQual>, Int], Attr.Pure>;
1522      }
1523    }
1524  }
1525  defm : ImageReadHalf<"RO">;
1526  let Extension = FuncExtOpenCLCReadWriteImages in {
1527    defm : ImageReadHalf<"RW">;
1528  }
1529}
1530// OpenCL extension v2.0 s5.1.11: Built-in Image Write Functions
1531// --- Table 10 ---
1532multiclass ImageWriteHalf<string aQual> {
1533  foreach name = ["write_imageh"] in {
1534    def : Builtin<name, [Void, ImageType<Image2d, aQual>, VectorType<Int, 2>, VectorType<Half, 4>]>;
1535    def : Builtin<name, [Void, ImageType<Image2dArray, aQual>, VectorType<Int, 4>, VectorType<Half, 4>]>;
1536    def : Builtin<name, [Void, ImageType<Image1d, aQual>, Int, VectorType<Half, 4>]>;
1537    def : Builtin<name, [Void, ImageType<Image1dBuffer, aQual>, Int, VectorType<Half, 4>]>;
1538    def : Builtin<name, [Void, ImageType<Image1dArray, aQual>, VectorType<Int, 2>, VectorType<Half, 4>]>;
1539    def : Builtin<name, [Void, ImageType<Image3d, aQual>, VectorType<Int, 4>, VectorType<Half, 4>]>;
1540  }
1541}
1542
1543defm : ImageWriteHalf<"WO">;
1544let Extension = FuncExtOpenCLCReadWriteImages in {
1545  defm : ImageWriteHalf<"RW">;
1546}
1547
1548
1549
1550//--------------------------------------------------------------------
1551// OpenCL v2.0 s6.13.15 - Work-group Functions
1552// --- Table 26 ---
1553let Extension = FuncExtOpenCLCWGCollectiveFunctions in {
1554  foreach name = ["work_group_all", "work_group_any"] in {
1555    def : Builtin<name, [Int, Int], Attr.Convergent>;
1556  }
1557  foreach name = ["work_group_broadcast"] in {
1558    def : Builtin<name, [IntLongFloatGenType1, IntLongFloatGenType1, Size], Attr.Convergent>;
1559    def : Builtin<name, [IntLongFloatGenType1, IntLongFloatGenType1, Size, Size], Attr.Convergent>;
1560    def : Builtin<name, [IntLongFloatGenType1, IntLongFloatGenType1, Size, Size, Size], Attr.Convergent>;
1561  }
1562  foreach op = ["add", "min", "max"] in {
1563    foreach name = ["work_group_reduce_", "work_group_scan_exclusive_",
1564                    "work_group_scan_inclusive_"] in {
1565      def : Builtin<name # op, [IntLongFloatGenType1, IntLongFloatGenType1], Attr.Convergent>;
1566    }
1567  }
1568}
1569
1570
1571//--------------------------------------------------------------------
1572// OpenCL2.0 : 6.13.16 : Pipe Functions
1573// --- Table 27 ---
1574// Defined in Builtins.def
1575
1576// --- Table 28 ---
1577// Builtins taking pipe arguments are defined in Builtins.def
1578let Extension = FuncExtOpenCLCPipes in {
1579  def : Builtin<"is_valid_reserve_id", [Bool, ReserveId]>;
1580}
1581
1582// --- Table 29 ---
1583// Defined in Builtins.def
1584
1585
1586//--------------------------------------------------------------------
1587// OpenCL2.0 : 6.13.17 : Enqueuing Kernels
1588// --- Table 30 ---
1589// Defined in Builtins.def
1590
1591// --- Table 32 ---
1592// Defined in Builtins.def
1593
1594// --- Table 33 ---
1595let MinVersion = CL20 in {
1596  def : Builtin<"enqueue_marker",
1597      [Int, Queue, UInt, PointerType<ConstType<ClkEvent>, GenericAS>, PointerType<ClkEvent, GenericAS>]>;
1598
1599  // --- Table 34 ---
1600  def : Builtin<"retain_event", [Void, ClkEvent]>;
1601  def : Builtin<"release_event", [Void, ClkEvent]>;
1602  def : Builtin<"create_user_event", [ClkEvent]>;
1603  def : Builtin<"is_valid_event", [Bool, ClkEvent]>;
1604  def : Builtin<"set_user_event_status", [Void, ClkEvent, Int]>;
1605  def : Builtin<"capture_event_profiling_info",
1606      [Void, ClkEvent, ClkProfilingInfo, PointerType<Void, GlobalAS>]>;
1607
1608  // --- Table 35 ---
1609  def : Builtin<"get_default_queue", [Queue]>;
1610
1611  def : Builtin<"ndrange_1D", [NDRange, Size]>;
1612  def : Builtin<"ndrange_1D", [NDRange, Size, Size]>;
1613  def : Builtin<"ndrange_1D", [NDRange, Size, Size, Size]>;
1614  def : Builtin<"ndrange_2D", [NDRange, PointerType<ConstType<Size>, PrivateAS>]>;
1615  def : Builtin<"ndrange_2D", [NDRange, PointerType<ConstType<Size>, PrivateAS>,
1616                                        PointerType<ConstType<Size>, PrivateAS>]>;
1617  def : Builtin<"ndrange_2D", [NDRange, PointerType<ConstType<Size>, PrivateAS>,
1618                                        PointerType<ConstType<Size>, PrivateAS>,
1619                                        PointerType<ConstType<Size>, PrivateAS>]>;
1620  def : Builtin<"ndrange_3D", [NDRange, PointerType<ConstType<Size>, PrivateAS>]>;
1621  def : Builtin<"ndrange_3D", [NDRange, PointerType<ConstType<Size>, PrivateAS>,
1622                                        PointerType<ConstType<Size>, PrivateAS>]>;
1623  def : Builtin<"ndrange_3D", [NDRange, PointerType<ConstType<Size>, PrivateAS>,
1624                                        PointerType<ConstType<Size>, PrivateAS>,
1625                                        PointerType<ConstType<Size>, PrivateAS>]>;
1626}
1627
1628
1629//--------------------------------------------------------------------
1630// End of the builtin functions defined in the OpenCL C specification.
1631// Builtin functions defined in the OpenCL C Extension are below.
1632//--------------------------------------------------------------------
1633
1634
1635// OpenCL Extension v2.0 s9.18 - Mipmaps
1636let Extension = FuncExtKhrMipmapImage in {
1637  // Added to section 6.13.14.2.
1638  foreach aQual = ["RO"] in {
1639    foreach imgTy = [Image2d] in {
1640      foreach name = ["read_imagef"] in {
1641        def : Builtin<name, [VectorType<Float, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 2>, Float], Attr.Pure>;
1642        def : Builtin<name, [VectorType<Float, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 2>, VectorType<Float, 2>, VectorType<Float, 2>], Attr.Pure>;
1643      }
1644      foreach name = ["read_imagei"] in {
1645        def : Builtin<name, [VectorType<Int, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 2>, Float], Attr.Pure>;
1646        def : Builtin<name, [VectorType<Int, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 2>, VectorType<Float, 2>, VectorType<Float, 2>], Attr.Pure>;
1647      }
1648      foreach name = ["read_imageui"] in {
1649        def : Builtin<name, [VectorType<UInt, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 2>, Float], Attr.Pure>;
1650        def : Builtin<name, [VectorType<UInt, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 2>, VectorType<Float, 2>, VectorType<Float, 2>], Attr.Pure>;
1651      }
1652    }
1653    foreach imgTy = [Image2dDepth] in {
1654      foreach name = ["read_imagef"] in {
1655        def : Builtin<name, [Float, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 2>, Float], Attr.Pure>;
1656        def : Builtin<name, [Float, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 2>, VectorType<Float, 2>, VectorType<Float, 2>], Attr.Pure>;
1657      }
1658    }
1659    foreach imgTy = [Image1d] in {
1660      foreach name = ["read_imagef"] in {
1661        def : Builtin<name, [VectorType<Float, 4>, ImageType<imgTy, aQual>, Sampler, Float, Float], Attr.Pure>;
1662        def : Builtin<name, [VectorType<Float, 4>, ImageType<imgTy, aQual>, Sampler, Float, Float, Float], Attr.Pure>;
1663      }
1664      foreach name = ["read_imagei"] in {
1665        def : Builtin<name, [VectorType<Int, 4>, ImageType<imgTy, aQual>, Sampler, Float, Float], Attr.Pure>;
1666        def : Builtin<name, [VectorType<Int, 4>, ImageType<imgTy, aQual>, Sampler, Float, Float, Float], Attr.Pure>;
1667      }
1668      foreach name = ["read_imageui"] in {
1669        def : Builtin<name, [VectorType<UInt, 4>, ImageType<imgTy, aQual>, Sampler, Float, Float], Attr.Pure>;
1670        def : Builtin<name, [VectorType<UInt, 4>, ImageType<imgTy, aQual>, Sampler, Float, Float, Float], Attr.Pure>;
1671      }
1672    }
1673    foreach imgTy = [Image3d] in {
1674      foreach name = ["read_imagef"] in {
1675        def : Builtin<name, [VectorType<Float, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 4>, VectorType<Float, 4>, VectorType<Float, 4>], Attr.Pure>;
1676        def : Builtin<name, [VectorType<Float, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 4>, Float], Attr.Pure>;
1677      }
1678      foreach name = ["read_imagei"] in {
1679        def : Builtin<name, [VectorType<Int, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 4>, VectorType<Float, 4>, VectorType<Float, 4>], Attr.Pure>;
1680        def : Builtin<name, [VectorType<Int, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 4>, Float], Attr.Pure>;
1681      }
1682      foreach name = ["read_imageui"] in {
1683        def : Builtin<name, [VectorType<UInt, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 4>, VectorType<Float, 4>, VectorType<Float, 4>], Attr.Pure>;
1684        def : Builtin<name, [VectorType<UInt, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 4>, Float], Attr.Pure>;
1685      }
1686    }
1687    foreach imgTy = [Image1dArray] in {
1688      foreach name = ["read_imagef"] in {
1689        def : Builtin<name, [VectorType<Float, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 2>, Float], Attr.Pure>;
1690        def : Builtin<name, [VectorType<Float, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 2>, Float, Float], Attr.Pure>;
1691      }
1692      foreach name = ["read_imagei"] in {
1693        def : Builtin<name, [VectorType<Int, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 2>, Float], Attr.Pure>;
1694        def : Builtin<name, [VectorType<Int, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 2>, Float, Float], Attr.Pure>;
1695      }
1696      foreach name = ["read_imageui"] in {
1697        def : Builtin<name, [VectorType<UInt, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 2>, Float], Attr.Pure>;
1698        def : Builtin<name, [VectorType<UInt, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 2>, Float, Float], Attr.Pure>;
1699      }
1700    }
1701    foreach imgTy = [Image2dArray] in {
1702      foreach name = ["read_imagef"] in {
1703        def : Builtin<name, [VectorType<Float, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 4>, Float], Attr.Pure>;
1704        def : Builtin<name, [VectorType<Float, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 4>, VectorType<Float, 2>, VectorType<Float, 2>], Attr.Pure>;
1705      }
1706      foreach name = ["read_imagei"] in {
1707        def : Builtin<name, [VectorType<Int, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 4>, Float], Attr.Pure>;
1708        def : Builtin<name, [VectorType<Int, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 4>, VectorType<Float, 2>, VectorType<Float, 2>], Attr.Pure>;
1709      }
1710      foreach name = ["read_imageui"] in {
1711        def : Builtin<name, [VectorType<UInt, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 4>, Float], Attr.Pure>;
1712        def : Builtin<name, [VectorType<UInt, 4>, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 4>, VectorType<Float, 2>, VectorType<Float, 2>], Attr.Pure>;
1713      }
1714    }
1715    foreach imgTy = [Image2dArrayDepth] in {
1716      foreach name = ["read_imagef"] in {
1717        def : Builtin<name, [Float, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 4>, Float], Attr.Pure>;
1718        def : Builtin<name, [Float, ImageType<imgTy, aQual>, Sampler, VectorType<Float, 4>, VectorType<Float, 2>, VectorType<Float, 2>], Attr.Pure>;
1719      }
1720    }
1721  }
1722}
1723
1724// Added to section 6.13.14.5
1725multiclass ImageQueryNumMipLevels<string aQual> {
1726  foreach imgTy = [Image1d, Image2d, Image3d, Image1dArray, Image2dArray, Image2dDepth, Image2dArrayDepth] in {
1727    def : Builtin<"get_image_num_mip_levels", [Int, ImageType<imgTy, aQual>]>;
1728  }
1729}
1730
1731let Extension = FuncExtKhrMipmapImage in {
1732  defm : ImageQueryNumMipLevels<"RO">;
1733  defm : ImageQueryNumMipLevels<"WO">;
1734}
1735
1736let Extension = FuncExtKhrMipmapImageReadWrite in {
1737  defm : ImageQueryNumMipLevels<"RW">;
1738}
1739
1740// Write functions are enabled using a separate extension.
1741let Extension = FuncExtKhrMipmapImageWrites in {
1742  // Added to section 6.13.14.4.
1743  foreach aQual = ["WO"] in {
1744    foreach imgTy = [Image2d] in {
1745      def : Builtin<"write_imagef", [Void, ImageType<imgTy, aQual>, VectorType<Int, 2>, Int, VectorType<Float, 4>]>;
1746      def : Builtin<"write_imagei", [Void, ImageType<imgTy, aQual>, VectorType<Int, 2>, Int, VectorType<Int, 4>]>;
1747      def : Builtin<"write_imageui", [Void, ImageType<imgTy, aQual>, VectorType<Int, 2>, Int, VectorType<UInt, 4>]>;
1748    }
1749    def : Builtin<"write_imagef", [Void, ImageType<Image2dDepth, aQual>, VectorType<Int, 2>, Int, Float]>;
1750    foreach imgTy = [Image1d] in {
1751      def : Builtin<"write_imagef", [Void, ImageType<imgTy, aQual>, Int, Int, VectorType<Float, 4>]>;
1752      def : Builtin<"write_imagei", [Void, ImageType<imgTy, aQual>, Int, Int, VectorType<Int, 4>]>;
1753      def : Builtin<"write_imageui", [Void, ImageType<imgTy, aQual>, Int, Int, VectorType<UInt, 4>]>;
1754    }
1755    foreach imgTy = [Image1dArray] in {
1756      def : Builtin<"write_imagef", [Void, ImageType<imgTy, aQual>, VectorType<Int, 2>, Int, VectorType<Float, 4>]>;
1757      def : Builtin<"write_imagei", [Void, ImageType<imgTy, aQual>, VectorType<Int, 2>, Int, VectorType<Int, 4>]>;
1758      def : Builtin<"write_imageui", [Void, ImageType<imgTy, aQual>, VectorType<Int, 2>, Int, VectorType<UInt, 4>]>;
1759    }
1760    foreach imgTy = [Image2dArray] in {
1761      def : Builtin<"write_imagef", [Void, ImageType<imgTy, aQual>, VectorType<Int, 4>, Int, VectorType<Float, 4>]>;
1762      def : Builtin<"write_imagei", [Void, ImageType<imgTy, aQual>, VectorType<Int, 4>, Int, VectorType<Int, 4>]>;
1763      def : Builtin<"write_imageui", [Void, ImageType<imgTy, aQual>, VectorType<Int, 4>, Int, VectorType<UInt, 4>]>;
1764    }
1765    def : Builtin<"write_imagef", [Void, ImageType<Image2dArrayDepth, aQual>, VectorType<Int, 4>, Int, Float]>;
1766    let Extension = FuncExtKhrMipmapWritesAndWrite3d in {
1767      foreach imgTy = [Image3d] in {
1768        def : Builtin<"write_imagef", [Void, ImageType<imgTy, aQual>, VectorType<Int, 4>, Int, VectorType<Float, 4>]>;
1769        def : Builtin<"write_imagei", [Void, ImageType<imgTy, aQual>, VectorType<Int, 4>, Int, VectorType<Int, 4>]>;
1770        def : Builtin<"write_imageui", [Void, ImageType<imgTy, aQual>, VectorType<Int, 4>, Int, VectorType<UInt, 4>]>;
1771      }
1772    }
1773  }
1774}
1775
1776//--------------------------------------------------------------------
1777// OpenCL Extension v2.0 s18.3 - Creating OpenCL Memory Objects from OpenGL MSAA Textures
1778// --- Table 6.13.14.3 ---
1779multiclass ImageReadMsaa<string aQual> {
1780  foreach imgTy = [Image2dMsaa] in {
1781    def : Builtin<"read_imagef", [VectorType<Float, 4>, ImageType<imgTy, aQual>, VectorType<Int, 2>, Int], Attr.Pure>;
1782    def : Builtin<"read_imagei", [VectorType<Int, 4>, ImageType<imgTy, aQual>, VectorType<Int, 2>, Int], Attr.Pure>;
1783    def : Builtin<"read_imageui", [VectorType<UInt, 4>, ImageType<imgTy, aQual>, VectorType<Int, 2>, Int], Attr.Pure>;
1784  }
1785  foreach imgTy = [Image2dArrayMsaa] in {
1786    def : Builtin<"read_imagef", [VectorType<Float, 4>, ImageType<imgTy, aQual>, VectorType<Int, 4>, Int], Attr.Pure>;
1787    def : Builtin<"read_imagei", [VectorType<Int, 4>, ImageType<imgTy, aQual>, VectorType<Int, 4>, Int], Attr.Pure>;
1788    def : Builtin<"read_imageui", [VectorType<UInt, 4>, ImageType<imgTy, aQual>, VectorType<Int, 4>, Int], Attr.Pure>;
1789  }
1790  foreach name = ["read_imagef"] in {
1791    def : Builtin<name, [Float, ImageType<Image2dMsaaDepth, aQual>, VectorType<Int, 2>, Int], Attr.Pure>;
1792    def : Builtin<name, [Float, ImageType<Image2dArrayMsaaDepth, aQual>, VectorType<Int, 4>, Int], Attr.Pure>;
1793  }
1794}
1795
1796// --- Table 6.13.14.5 ---
1797multiclass ImageQueryMsaa<string aQual> {
1798  foreach imgTy = [Image2dMsaa, Image2dArrayMsaa, Image2dMsaaDepth, Image2dArrayMsaaDepth] in {
1799    foreach name = ["get_image_width", "get_image_height",
1800                    "get_image_channel_data_type", "get_image_channel_order",
1801                    "get_image_num_samples"] in {
1802      def : Builtin<name, [Int, ImageType<imgTy, aQual>], Attr.Const>;
1803    }
1804    def : Builtin<"get_image_dim", [VectorType<Int, 2>, ImageType<imgTy, aQual>], Attr.Const>;
1805  }
1806  foreach imgTy = [Image2dArrayMsaa, Image2dArrayMsaaDepth] in {
1807    def : Builtin<"get_image_array_size", [Size, ImageType<imgTy, aQual>], Attr.Const>;
1808  }
1809}
1810
1811let Extension = FuncExtKhrGlMsaaSharing in {
1812  defm : ImageReadMsaa<"RO">;
1813  defm : ImageQueryMsaa<"RO">;
1814  defm : ImageQueryMsaa<"WO">;
1815}
1816
1817let Extension = FuncExtKhrGlMsaaSharingReadWrite in {
1818  defm : ImageReadMsaa<"RW">;
1819  defm : ImageQueryMsaa<"RW">;
1820}
1821
1822//--------------------------------------------------------------------
1823// OpenCL Extension v2.0 s28 - Subgroups
1824// --- Table 28.2.1 ---
1825let Extension = FuncExtKhrSubgroups in {
1826  foreach name = ["get_sub_group_size", "get_max_sub_group_size",
1827                  "get_num_sub_groups", "get_sub_group_id",
1828                  "get_sub_group_local_id"] in {
1829    def : Builtin<name, [UInt]>;
1830  }
1831  let MinVersion = CL20 in {
1832    foreach name = ["get_enqueued_num_sub_groups"] in {
1833      def : Builtin<name, [UInt]>;
1834    }
1835  }
1836}
1837
1838// --- Table 28.2.2 ---
1839let Extension = FuncExtKhrSubgroups in {
1840  def : Builtin<"sub_group_barrier", [Void, MemFenceFlags], Attr.Convergent>;
1841  def : Builtin<"sub_group_barrier", [Void, MemFenceFlags, MemoryScope], Attr.Convergent>;
1842}
1843
1844// --- Table 28.2.4 ---
1845let Extension = FuncExtKhrSubgroups in {
1846  foreach name = ["sub_group_all", "sub_group_any"] in {
1847    def : Builtin<name, [Int, Int], Attr.Convergent>;
1848  }
1849  foreach name = ["sub_group_broadcast"] in {
1850    def : Builtin<name, [IntLongFloatGenType1, IntLongFloatGenType1, UInt], Attr.Convergent>;
1851  }
1852  foreach name = ["sub_group_reduce_", "sub_group_scan_exclusive_",
1853                  "sub_group_scan_inclusive_"] in {
1854    foreach op = ["add", "min", "max"] in {
1855      def : Builtin<name # op, [IntLongFloatGenType1, IntLongFloatGenType1], Attr.Convergent>;
1856    }
1857  }
1858}
1859
1860// OpenCL Extension v3.0 s38 - Extended Subgroup Functions
1861
1862// Section 38.4.1 - cl_khr_subgroup_extended_types
1863let Extension = FuncExtKhrSubgroupExtendedTypes in {
1864  // For sub_group_broadcast, add scalar char, uchar, short, and ushort support,
1865  def : Builtin<"sub_group_broadcast", [CharShortGenType1, CharShortGenType1, UInt], Attr.Convergent>;
1866  // gentype may additionally be one of the supported built-in vector data types.
1867  def : Builtin<"sub_group_broadcast", [AGenTypeNNoScalar, AGenTypeNNoScalar, UInt], Attr.Convergent>;
1868
1869  foreach name = ["sub_group_reduce_", "sub_group_scan_exclusive_",
1870                  "sub_group_scan_inclusive_"] in {
1871    foreach op = ["add", "min", "max"] in {
1872      def : Builtin<name # op, [CharShortGenType1, CharShortGenType1], Attr.Convergent>;
1873    }
1874  }
1875}
1876
1877// Section 38.5.1 - cl_khr_subgroup_non_uniform_vote
1878let Extension = FuncExtKhrSubgroupNonUniformVote in {
1879  def : Builtin<"sub_group_elect", [Int]>;
1880  def : Builtin<"sub_group_non_uniform_all", [Int, Int]>;
1881  def : Builtin<"sub_group_non_uniform_any", [Int, Int]>;
1882  def : Builtin<"sub_group_non_uniform_all_equal", [Int, AGenType1]>;
1883}
1884
1885// Section 38.6.1 - cl_khr_subgroup_ballot
1886let Extension = FuncExtKhrSubgroupBallot in {
1887  def : Builtin<"sub_group_non_uniform_broadcast", [AGenTypeN, AGenTypeN, UInt]>;
1888  def : Builtin<"sub_group_broadcast_first", [AGenType1, AGenType1]>;
1889  def : Builtin<"sub_group_ballot", [VectorType<UInt, 4>, Int]>;
1890  def : Builtin<"sub_group_inverse_ballot", [Int, VectorType<UInt, 4>], Attr.Const>;
1891  def : Builtin<"sub_group_ballot_bit_extract", [Int, VectorType<UInt, 4>, UInt], Attr.Const>;
1892  def : Builtin<"sub_group_ballot_bit_count", [UInt, VectorType<UInt, 4>], Attr.Const>;
1893  def : Builtin<"sub_group_ballot_inclusive_scan", [UInt, VectorType<UInt, 4>]>;
1894  def : Builtin<"sub_group_ballot_exclusive_scan", [UInt, VectorType<UInt, 4>]>;
1895  def : Builtin<"sub_group_ballot_find_lsb", [UInt, VectorType<UInt, 4>]>;
1896  def : Builtin<"sub_group_ballot_find_msb", [UInt, VectorType<UInt, 4>]>;
1897
1898  foreach op = ["eq", "ge", "gt", "le", "lt"] in {
1899    def : Builtin<"get_sub_group_" # op # "_mask", [VectorType<UInt, 4>], Attr.Const>;
1900  }
1901}
1902
1903// Section 38.7.1 - cl_khr_subgroup_non_uniform_arithmetic
1904let Extension = FuncExtKhrSubgroupNonUniformArithmetic in {
1905  foreach name = ["reduce_", "scan_exclusive_", "scan_inclusive_"] in {
1906    foreach op = ["add", "min", "max", "mul"] in {
1907      def : Builtin<"sub_group_non_uniform_" # name # op, [AGenType1, AGenType1]>;
1908    }
1909    foreach op = ["and", "or", "xor"] in {
1910      def : Builtin<"sub_group_non_uniform_" # name # op, [AIGenType1, AIGenType1]>;
1911    }
1912    foreach op = ["and", "or", "xor"] in {
1913      def : Builtin<"sub_group_non_uniform_" # name # "logical_" # op, [Int, Int]>;
1914    }
1915  }
1916}
1917
1918// Section 38.8.1 - cl_khr_subgroup_shuffle
1919let Extension = FuncExtKhrSubgroupShuffle in {
1920  def : Builtin<"sub_group_shuffle", [AGenType1, AGenType1, UInt]>;
1921  def : Builtin<"sub_group_shuffle_xor", [AGenType1, AGenType1, UInt]>;
1922}
1923
1924// Section 38.9.1 - cl_khr_subgroup_shuffle_relative
1925let Extension = FuncExtKhrSubgroupShuffleRelative in {
1926  def : Builtin<"sub_group_shuffle_up", [AGenType1, AGenType1, UInt]>;
1927  def : Builtin<"sub_group_shuffle_down", [AGenType1, AGenType1, UInt]>;
1928}
1929
1930// Section 38.10.1 - cl_khr_subgroup_clustered_reduce
1931let Extension = FuncExtKhrSubgroupClusteredReduce in {
1932  foreach op = ["add", "min", "max", "mul"] in {
1933    def : Builtin<"sub_group_clustered_reduce_" # op, [AGenType1, AGenType1, UInt]>;
1934  }
1935  foreach op = ["and", "or", "xor"] in {
1936    def : Builtin<"sub_group_clustered_reduce_" # op, [AIGenType1, AIGenType1, UInt]>;
1937  }
1938  foreach op = ["and", "or", "xor"] in {
1939    def : Builtin<"sub_group_clustered_reduce_logical_" # op, [Int, Int, UInt]>;
1940  }
1941}
1942
1943// Section 40.3.1 - cl_khr_extended_bit_ops
1944let Extension = FuncExtKhrExtendedBitOps in {
1945  def : Builtin<"bitfield_insert", [AIGenTypeN, AIGenTypeN, AIGenTypeN, UInt, UInt], Attr.Const>;
1946  def : Builtin<"bitfield_extract_signed", [SGenTypeN, SGenTypeN, UInt, UInt], Attr.Const>;
1947  def : Builtin<"bitfield_extract_signed", [SGenTypeN, UGenTypeN, UInt, UInt], Attr.Const>;
1948  def : Builtin<"bitfield_extract_unsigned", [UGenTypeN, SGenTypeN, UInt, UInt], Attr.Const>;
1949  def : Builtin<"bitfield_extract_unsigned", [UGenTypeN, UGenTypeN, UInt, UInt], Attr.Const>;
1950  def : Builtin<"bit_reverse", [AIGenTypeN, AIGenTypeN], Attr.Const>;
1951}
1952
1953// Section 42.3 - cl_khr_integer_dot_product
1954let Extension = FunctionExtension<"__opencl_c_integer_dot_product_input_4x8bit"> in {
1955  def : Builtin<"dot", [UInt, VectorType<UChar, 4>, VectorType<UChar, 4>], Attr.Const>;
1956  def : Builtin<"dot", [Int, VectorType<Char, 4>, VectorType<Char, 4>], Attr.Const>;
1957  def : Builtin<"dot", [Int, VectorType<UChar, 4>, VectorType<Char, 4>], Attr.Const>;
1958  def : Builtin<"dot", [Int, VectorType<Char, 4>, VectorType<UChar, 4>], Attr.Const>;
1959
1960  def : Builtin<"dot_acc_sat", [UInt, VectorType<UChar, 4>, VectorType<UChar, 4>, UInt], Attr.Const>;
1961  def : Builtin<"dot_acc_sat", [Int, VectorType<Char, 4>, VectorType<Char, 4>, Int], Attr.Const>;
1962  def : Builtin<"dot_acc_sat", [Int, VectorType<UChar, 4>, VectorType<Char, 4>, Int], Attr.Const>;
1963  def : Builtin<"dot_acc_sat", [Int, VectorType<Char, 4>, VectorType<UChar, 4>, Int], Attr.Const>;
1964}
1965
1966let Extension = FunctionExtension<"__opencl_c_integer_dot_product_input_4x8bit_packed"> in {
1967  def : Builtin<"dot_4x8packed_uu_uint", [UInt, UInt, UInt], Attr.Const>;
1968  def : Builtin<"dot_4x8packed_ss_int", [Int, UInt, UInt], Attr.Const>;
1969  def : Builtin<"dot_4x8packed_us_int", [Int, UInt, UInt], Attr.Const>;
1970  def : Builtin<"dot_4x8packed_su_int", [Int, UInt, UInt], Attr.Const>;
1971
1972  def : Builtin<"dot_acc_sat_4x8packed_uu_uint", [UInt, UInt, UInt, UInt], Attr.Const>;
1973  def : Builtin<"dot_acc_sat_4x8packed_ss_int", [Int, UInt, UInt, Int], Attr.Const>;
1974  def : Builtin<"dot_acc_sat_4x8packed_us_int", [Int, UInt, UInt, Int], Attr.Const>;
1975  def : Builtin<"dot_acc_sat_4x8packed_su_int", [Int, UInt, UInt, Int], Attr.Const>;
1976}
1977
1978//--------------------------------------------------------------------
1979// Arm extensions.
1980let Extension = ArmIntegerDotProductInt8 in {
1981  foreach name = ["arm_dot"] in {
1982    def : Builtin<name, [UInt, VectorType<UChar, 4>, VectorType<UChar, 4>]>;
1983    def : Builtin<name, [Int, VectorType<Char, 4>, VectorType<Char, 4>]>;
1984  }
1985}
1986let Extension = ArmIntegerDotProductAccumulateInt8 in {
1987  foreach name = ["arm_dot_acc"] in {
1988    def : Builtin<name, [UInt, VectorType<UChar, 4>, VectorType<UChar, 4>, UInt]>;
1989    def : Builtin<name, [Int, VectorType<Char, 4>, VectorType<Char, 4>, Int]>;
1990  }
1991}
1992let Extension = ArmIntegerDotProductAccumulateInt16 in {
1993  foreach name = ["arm_dot_acc"] in {
1994    def : Builtin<name, [UInt, VectorType<UShort, 2>, VectorType<UShort, 2>, UInt]>;
1995    def : Builtin<name, [Int, VectorType<Short, 2>, VectorType<Short, 2>, Int]>;
1996  }
1997}
1998let Extension = ArmIntegerDotProductAccumulateSaturateInt8 in {
1999  foreach name = ["arm_dot_acc_sat"] in {
2000    def : Builtin<name, [UInt, VectorType<UChar, 4>, VectorType<UChar, 4>, UInt]>;
2001    def : Builtin<name, [Int, VectorType<Char, 4>, VectorType<Char, 4>, Int]>;
2002  }
2003}
2004