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