[clang] d353d1c - [OpenCL] Support cl_ext_float_atomics
Sven van Haastregt via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 13 04:13:06 PDT 2021
Author: Sven van Haastregt
Date: 2021-09-13T12:12:40+01:00
New Revision: d353d1c50112a1cb315eccdab18ce7bd1563cd06
URL: https://github.com/llvm/llvm-project/commit/d353d1c50112a1cb315eccdab18ce7bd1563cd06
DIFF: https://github.com/llvm/llvm-project/commit/d353d1c50112a1cb315eccdab18ce7bd1563cd06.diff
LOG: [OpenCL] Support cl_ext_float_atomics
See https://github.com/KhronosGroup/OpenCL-Docs/pull/552 for initial
specification.
Patch by Haonan Yang.
Differential Revision: https://reviews.llvm.org/D106343
Added:
Modified:
clang/lib/Headers/opencl-c-base.h
clang/lib/Headers/opencl-c.h
clang/lib/Sema/OpenCLBuiltins.td
clang/test/Headers/opencl-c-header.cl
clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl
Removed:
################################################################################
diff --git a/clang/lib/Headers/opencl-c-base.h b/clang/lib/Headers/opencl-c-base.h
index f3605c659d952..7cc356015d959 100644
--- a/clang/lib/Headers/opencl-c-base.h
+++ b/clang/lib/Headers/opencl-c-base.h
@@ -25,6 +25,25 @@
#define cl_khr_integer_dot_product 1
#define __opencl_c_integer_dot_product_input_4x8bit 1
#define __opencl_c_integer_dot_product_input_4x8bit_packed 1
+#define cl_ext_float_atomics 1
+#ifdef cl_khr_fp16
+#define __opencl_c_ext_fp16_global_atomic_load_store 1
+#define __opencl_c_ext_fp16_local_atomic_load_store 1
+#define __opencl_c_ext_fp16_global_atomic_add 1
+#define __opencl_c_ext_fp16_local_atomic_add 1
+#define __opencl_c_ext_fp16_global_atomic_min_max 1
+#define __opencl_c_ext_fp16_local_atomic_min_max 1
+#endif
+#ifdef cl_khr_fp64
+#define __opencl_c_ext_fp64_global_atomic_add 1
+#define __opencl_c_ext_fp64_local_atomic_add 1
+#define __opencl_c_ext_fp64_global_atomic_min_max 1
+#define __opencl_c_ext_fp64_local_atomic_min_max 1
+#endif
+#define __opencl_c_ext_fp32_global_atomic_add 1
+#define __opencl_c_ext_fp32_local_atomic_add 1
+#define __opencl_c_ext_fp32_global_atomic_min_max 1
+#define __opencl_c_ext_fp32_local_atomic_min_max 1
#endif // defined(__SPIR__)
#endif // (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200)
diff --git a/clang/lib/Headers/opencl-c.h b/clang/lib/Headers/opencl-c.h
index bb3ca6aae20a2..e960228594801 100644
--- a/clang/lib/Headers/opencl-c.h
+++ b/clang/lib/Headers/opencl-c.h
@@ -13637,6 +13637,215 @@ uintptr_t __ovld atomic_fetch_sub_explicit(volatile __local atomic_uintptr_t *ob
#endif //defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics)
#endif //__OPENCL_C_VERSION__ >= CL_VERSION_3_0
+// The functionality added by cl_ext_float_atomics extension
+#if defined(cl_ext_float_atomics)
+
+#if defined(__opencl_c_ext_fp32_global_atomic_min_max)
+float __ovld atomic_fetch_min(volatile __global atomic_float *object,
+ float operand);
+float __ovld atomic_fetch_max(volatile __global atomic_float *object,
+ float operand);
+float __ovld atomic_fetch_min_explicit(volatile __global atomic_float *object,
+ float operand, memory_order order);
+float __ovld atomic_fetch_max_explicit(volatile __global atomic_float *object,
+ float operand, memory_order order);
+float __ovld atomic_fetch_min_explicit(volatile __global atomic_float *object,
+ float operand, memory_order order,
+ memory_scope scope);
+float __ovld atomic_fetch_max_explicit(volatile __global atomic_float *object,
+ float operand, memory_order order,
+ memory_scope scope);
+#endif // defined(__opencl_c_ext_fp32_global_atomic_min_max)
+
+#if defined(__opencl_c_ext_fp32_local_atomic_min_max)
+float __ovld atomic_fetch_min(volatile __local atomic_float *object,
+ float operand);
+float __ovld atomic_fetch_max(volatile __local atomic_float *object,
+ float operand);
+float __ovld atomic_fetch_min_explicit(volatile __local atomic_float *object,
+ float operand, memory_order order);
+float __ovld atomic_fetch_max_explicit(volatile __local atomic_float *object,
+ float operand, memory_order order);
+float __ovld atomic_fetch_min_explicit(volatile __local atomic_float *object,
+ float operand, memory_order order,
+ memory_scope scope);
+float __ovld atomic_fetch_max_explicit(volatile __local atomic_float *object,
+ float operand, memory_order order,
+ memory_scope scope);
+#endif // defined(__opencl_c_ext_fp32_local_atomic_min_max)
+
+#if defined(__opencl_c_ext_fp32_global_atomic_min_max) && \
+ defined(__opencl_c_ext_fp32_local_atomic_min_max)
+float __ovld atomic_fetch_min(volatile atomic_float *object, float operand);
+float __ovld atomic_fetch_max(volatile atomic_float *object, float operand);
+float __ovld atomic_fetch_min_explicit(volatile atomic_float *object,
+ float operand, memory_order order);
+float __ovld atomic_fetch_max_explicit(volatile atomic_float *object,
+ float operand, memory_order order);
+float __ovld atomic_fetch_min_explicit(volatile atomic_float *object,
+ float operand, memory_order order,
+ memory_scope scope);
+float __ovld atomic_fetch_max_explicit(volatile atomic_float *object,
+ float operand, memory_order order,
+ memory_scope scope);
+#endif // defined(__opencl_c_ext_fp32_global_atomic_min_max) && \
+ defined(__opencl_c_ext_fp32_local_atomic_min_max)
+
+#if defined(__opencl_c_ext_fp64_global_atomic_min_max)
+double __ovld atomic_fetch_min(volatile __global atomic_double *object,
+ double operand);
+double __ovld atomic_fetch_max(volatile __global atomic_double *object,
+ double operand);
+double __ovld atomic_fetch_min_explicit(volatile __global atomic_double *object,
+ double operand, memory_order order);
+double __ovld atomic_fetch_max_explicit(volatile __global atomic_double *object,
+ double operand, memory_order order);
+double __ovld atomic_fetch_min_explicit(volatile __global atomic_double *object,
+ double operand, memory_order order,
+ memory_scope scope);
+double __ovld atomic_fetch_max_explicit(volatile __global atomic_double *object,
+ double operand, memory_order order,
+ memory_scope scope);
+#endif // defined(__opencl_c_ext_fp64_global_atomic_min_max)
+
+#if defined(__opencl_c_ext_fp64_local_atomic_min_max)
+double __ovld atomic_fetch_min(volatile __local atomic_double *object,
+ double operand);
+double __ovld atomic_fetch_max(volatile __local atomic_double *object,
+ double operand);
+double __ovld atomic_fetch_min_explicit(volatile __local atomic_double *object,
+ double operand, memory_order order);
+double __ovld atomic_fetch_max_explicit(volatile __local atomic_double *object,
+ double operand, memory_order order);
+double __ovld atomic_fetch_min_explicit(volatile __local atomic_double *object,
+ double operand, memory_order order,
+ memory_scope scope);
+double __ovld atomic_fetch_max_explicit(volatile __local atomic_double *object,
+ double operand, memory_order order,
+ memory_scope scope);
+#endif // defined(__opencl_c_ext_fp64_local_atomic_min_max)
+
+#if defined(__opencl_c_ext_fp64_global_atomic_min_max) && \
+ defined(__opencl_c_ext_fp64_local_atomic_min_max)
+double __ovld atomic_fetch_min(volatile atomic_double *object, double operand);
+double __ovld atomic_fetch_max(volatile atomic_double *object, double operand);
+double __ovld atomic_fetch_min_explicit(volatile atomic_double *object,
+ double operand, memory_order order);
+double __ovld atomic_fetch_max_explicit(volatile atomic_double *object,
+ double operand, memory_order order);
+double __ovld atomic_fetch_min_explicit(volatile atomic_double *object,
+ double operand, memory_order order,
+ memory_scope scope);
+double __ovld atomic_fetch_max_explicit(volatile atomic_double *object,
+ double operand, memory_order order,
+ memory_scope scope);
+#endif // defined(__opencl_c_ext_fp64_global_atomic_min_max) && \
+ defined(__opencl_c_ext_fp64_local_atomic_min_max)
+
+#if defined(__opencl_c_ext_fp32_global_atomic_add)
+float __ovld atomic_fetch_add(volatile __global atomic_float *object,
+ float operand);
+float __ovld atomic_fetch_sub(volatile __global atomic_float *object,
+ float operand);
+float __ovld atomic_fetch_add_explicit(volatile __global atomic_float *object,
+ float operand, memory_order order);
+float __ovld atomic_fetch_sub_explicit(volatile __global atomic_float *object,
+ float operand, memory_order order);
+float __ovld atomic_fetch_add_explicit(volatile __global atomic_float *object,
+ float operand, memory_order order,
+ memory_scope scope);
+float __ovld atomic_fetch_sub_explicit(volatile __global atomic_float *object,
+ float operand, memory_order order,
+ memory_scope scope);
+#endif // defined(__opencl_c_ext_fp32_global_atomic_add)
+
+#if defined(__opencl_c_ext_fp32_local_atomic_add)
+float __ovld atomic_fetch_add(volatile __local atomic_float *object,
+ float operand);
+float __ovld atomic_fetch_sub(volatile __local atomic_float *object,
+ float operand);
+float __ovld atomic_fetch_add_explicit(volatile __local atomic_float *object,
+ float operand, memory_order order);
+float __ovld atomic_fetch_sub_explicit(volatile __local atomic_float *object,
+ float operand, memory_order order);
+float __ovld atomic_fetch_add_explicit(volatile __local atomic_float *object,
+ float operand, memory_order order,
+ memory_scope scope);
+float __ovld atomic_fetch_sub_explicit(volatile __local atomic_float *object,
+ float operand, memory_order order,
+ memory_scope scope);
+#endif // defined(__opencl_c_ext_fp32_local_atomic_add)
+
+#if defined(__opencl_c_ext_fp32_global_atomic_add) && \
+ defined(__opencl_c_ext_fp32_local_atomic_add)
+float __ovld atomic_fetch_add(volatile atomic_float *object, float operand);
+float __ovld atomic_fetch_sub(volatile atomic_float *object, float operand);
+float __ovld atomic_fetch_add_explicit(volatile atomic_float *object,
+ float operand, memory_order order);
+float __ovld atomic_fetch_sub_explicit(volatile atomic_float *object,
+ float operand, memory_order order);
+float __ovld atomic_fetch_add_explicit(volatile atomic_float *object,
+ float operand, memory_order order,
+ memory_scope scope);
+float __ovld atomic_fetch_sub_explicit(volatile atomic_float *object,
+ float operand, memory_order order,
+ memory_scope scope);
+#endif // defined(__opencl_c_ext_fp32_global_atomic_add) && \
+ defined(__opencl_c_ext_fp32_local_atomic_add)
+
+#if defined(__opencl_c_ext_fp64_global_atomic_add)
+double __ovld atomic_fetch_add(volatile __global atomic_double *object,
+ double operand);
+double __ovld atomic_fetch_sub(volatile __global atomic_double *object,
+ double operand);
+double __ovld atomic_fetch_add_explicit(volatile __global atomic_double *object,
+ double operand, memory_order order);
+double __ovld atomic_fetch_sub_explicit(volatile __global atomic_double *object,
+ double operand, memory_order order);
+double __ovld atomic_fetch_add_explicit(volatile __global atomic_double *object,
+ double operand, memory_order order,
+ memory_scope scope);
+double __ovld atomic_fetch_sub_explicit(volatile __global atomic_double *object,
+ double operand, memory_order order,
+ memory_scope scope);
+#endif // defined(__opencl_c_ext_fp64_global_atomic_add)
+
+#if defined(__opencl_c_ext_fp64_local_atomic_add)
+double __ovld atomic_fetch_add(volatile __local atomic_double *object,
+ double operand);
+double __ovld atomic_fetch_sub(volatile __local atomic_double *object,
+ double operand);
+double __ovld atomic_fetch_add_explicit(volatile __local atomic_double *object,
+ double operand, memory_order order);
+double __ovld atomic_fetch_sub_explicit(volatile __local atomic_double *object,
+ double operand, memory_order order);
+double __ovld atomic_fetch_add_explicit(volatile __local atomic_double *object,
+ double operand, memory_order order,
+ memory_scope scope);
+double __ovld atomic_fetch_sub_explicit(volatile __local atomic_double *object,
+ double operand, memory_order order,
+ memory_scope scope);
+#endif // defined(__opencl_c_ext_fp64_local_atomic_add)
+
+#if defined(__opencl_c_ext_fp64_global_atomic_add) && \
+ defined(__opencl_c_ext_fp64_local_atomic_add)
+double __ovld atomic_fetch_add(volatile atomic_double *object, double operand);
+double __ovld atomic_fetch_sub(volatile atomic_double *object, double operand);
+double __ovld atomic_fetch_add_explicit(volatile atomic_double *object,
+ double operand, memory_order order);
+double __ovld atomic_fetch_sub_explicit(volatile atomic_double *object,
+ double operand, memory_order order);
+double __ovld atomic_fetch_add_explicit(volatile atomic_double *object,
+ double operand, memory_order order,
+ memory_scope scope);
+double __ovld atomic_fetch_sub_explicit(volatile atomic_double *object,
+ double operand, memory_order order,
+ memory_scope scope);
+#endif // defined(__opencl_c_ext_fp64_global_atomic_add) && \
+ defined(__opencl_c_ext_fp64_local_atomic_add)
+
+#endif // cl_ext_float_atomics
+
// atomic_store()
#if defined(__opencl_c_atomic_order_seq_cst) && defined(__opencl_c_atomic_scope_device)
diff --git a/clang/lib/Sema/OpenCLBuiltins.td b/clang/lib/Sema/OpenCLBuiltins.td
index cbf66ae043647..5d75c2bb1a844 100644
--- a/clang/lib/Sema/OpenCLBuiltins.td
+++ b/clang/lib/Sema/OpenCLBuiltins.td
@@ -85,6 +85,18 @@ def FuncExtKhrGlMsaaSharing : FunctionExtension<"cl_khr_gl_msaa_sha
def FuncExtOpenCLCPipes : FunctionExtension<"__opencl_c_pipes">;
def FuncExtOpenCLCWGCollectiveFunctions : FunctionExtension<"__opencl_c_work_group_collective_functions">;
+def FuncExtFloatAtomicsFp32GlobalAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_global_atomic_add">;
+def FuncExtFloatAtomicsFp64GlobalAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_global_atomic_add">;
+def FuncExtFloatAtomicsFp32LocalAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_local_atomic_add">;
+def FuncExtFloatAtomicsFp64LocalAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_local_atomic_add">;
+def FuncExtFloatAtomicsFp32GenericAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_local_atomic_add __opencl_c_ext_fp32_global_atomic_add">;
+def FuncExtFloatAtomicsFp64GenericAdd : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_local_atomic_add __opencl_c_ext_fp64_global_atomic_add">;
+def FuncExtFloatAtomicsFp32GlobalMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_global_atomic_min_max">;
+def FuncExtFloatAtomicsFp64GlobalMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_global_atomic_min_max">;
+def FuncExtFloatAtomicsFp32LocalMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_local_atomic_min_max">;
+def FuncExtFloatAtomicsFp64LocalMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_local_atomic_min_max">;
+def FuncExtFloatAtomicsFp32GenericMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp32_local_atomic_min_max __opencl_c_ext_fp32_global_atomic_min_max">;
+def FuncExtFloatAtomicsFp64GenericMinMax : FunctionExtension<"cl_ext_float_atomics __opencl_c_ext_fp64_local_atomic_min_max __opencl_c_ext_fp64_global_atomic_min_max">;
// Not a real extension, but a workaround to add C++ for OpenCL specific builtins.
def FuncExtOpenCLCxx : FunctionExtension<"__cplusplus">;
@@ -1101,6 +1113,110 @@ let MinVersion = CL20 in {
[Bool, PointerType<VolatileType<AtomicFlag>, GenericAS>, MemoryOrder, MemoryScope]>;
}
+// The functionality added by cl_ext_float_atomics extension
+let MinVersion = CL20 in {
+ foreach ModOp = ["add", "sub"] in {
+ let Extension = FuncExtFloatAtomicsFp32GlobalAdd in {
+ def : Builtin<"atomic_fetch_" # ModOp,
+ [Float, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Float]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Float, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Float, MemoryOrder]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Float, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Float, MemoryOrder, MemoryScope]>;
+ }
+ let Extension = FuncExtFloatAtomicsFp64GlobalAdd in {
+ def : Builtin<"atomic_fetch_" # ModOp,
+ [Double, PointerType<VolatileType<AtomicDouble>, GlobalAS>, Double]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Double, PointerType<VolatileType<AtomicDouble>, GlobalAS>, Double, MemoryOrder]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Double, PointerType<VolatileType<AtomicDouble>, GlobalAS>, Double, MemoryOrder, MemoryScope]>;
+ }
+ let Extension = FuncExtFloatAtomicsFp32LocalAdd in {
+ def : Builtin<"atomic_fetch_" # ModOp,
+ [Float, PointerType<VolatileType<AtomicFloat>, LocalAS>, Float]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Float, PointerType<VolatileType<AtomicFloat>, LocalAS>, Float, MemoryOrder]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Float, PointerType<VolatileType<AtomicFloat>, LocalAS>, Float, MemoryOrder, MemoryScope]>;
+ }
+ let Extension = FuncExtFloatAtomicsFp64LocalAdd in {
+ def : Builtin<"atomic_fetch_" # ModOp,
+ [Double, PointerType<VolatileType<AtomicDouble>, LocalAS>, Double]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Double, PointerType<VolatileType<AtomicDouble>, LocalAS>, Double, MemoryOrder]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Double, PointerType<VolatileType<AtomicDouble>, LocalAS>, Double, MemoryOrder, MemoryScope]>;
+ }
+ let Extension = FuncExtFloatAtomicsFp32GenericAdd in {
+ def : Builtin<"atomic_fetch_" # ModOp,
+ [Float, PointerType<VolatileType<AtomicFloat>, GenericAS>, Float]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Float, PointerType<VolatileType<AtomicFloat>, GenericAS>, Float, MemoryOrder]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Float, PointerType<VolatileType<AtomicFloat>, GenericAS>, Float, MemoryOrder, MemoryScope]>;
+ }
+ let Extension = FuncExtFloatAtomicsFp64GenericAdd in {
+ def : Builtin<"atomic_fetch_" # ModOp,
+ [Double, PointerType<VolatileType<AtomicDouble>, GenericAS>, Double]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Double, PointerType<VolatileType<AtomicDouble>, GenericAS>, Double, MemoryOrder]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Double, PointerType<VolatileType<AtomicDouble>, GenericAS>, Double, MemoryOrder, MemoryScope]>;
+ }
+ }
+ foreach ModOp = ["min", "max"] in {
+ let Extension = FuncExtFloatAtomicsFp32GlobalMinMax in {
+ def : Builtin<"atomic_fetch_" # ModOp,
+ [Float, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Float]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Float, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Float, MemoryOrder]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Float, PointerType<VolatileType<AtomicFloat>, GlobalAS>, Float, MemoryOrder, MemoryScope]>;
+ }
+ let Extension = FuncExtFloatAtomicsFp64GlobalMinMax in {
+ def : Builtin<"atomic_fetch_" # ModOp,
+ [Double, PointerType<VolatileType<AtomicDouble>, GlobalAS>, Double]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Double, PointerType<VolatileType<AtomicDouble>, GlobalAS>, Double, MemoryOrder]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Double, PointerType<VolatileType<AtomicDouble>, GlobalAS>, Double, MemoryOrder, MemoryScope]>;
+ }
+ let Extension = FuncExtFloatAtomicsFp32LocalMinMax in {
+ def : Builtin<"atomic_fetch_" # ModOp,
+ [Float, PointerType<VolatileType<AtomicFloat>, LocalAS>, Float]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Float, PointerType<VolatileType<AtomicFloat>, LocalAS>, Float, MemoryOrder]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Float, PointerType<VolatileType<AtomicFloat>, LocalAS>, Float, MemoryOrder, MemoryScope]>;
+ }
+ let Extension = FuncExtFloatAtomicsFp64LocalMinMax in {
+ def : Builtin<"atomic_fetch_" # ModOp,
+ [Double, PointerType<VolatileType<AtomicDouble>, LocalAS>, Double]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Double, PointerType<VolatileType<AtomicDouble>, LocalAS>, Double, MemoryOrder]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Double, PointerType<VolatileType<AtomicDouble>, LocalAS>, Double, MemoryOrder, MemoryScope]>;
+ }
+ let Extension = FuncExtFloatAtomicsFp32GenericMinMax in {
+ def : Builtin<"atomic_fetch_" # ModOp,
+ [Float, PointerType<VolatileType<AtomicFloat>, GenericAS>, Float]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Float, PointerType<VolatileType<AtomicFloat>, GenericAS>, Float, MemoryOrder]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Float, PointerType<VolatileType<AtomicFloat>, GenericAS>, Float, MemoryOrder, MemoryScope]>;
+ }
+ let Extension = FuncExtFloatAtomicsFp64GenericMinMax in {
+ def : Builtin<"atomic_fetch_" # ModOp,
+ [Double, PointerType<VolatileType<AtomicDouble>, GenericAS>, Double]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Double, PointerType<VolatileType<AtomicDouble>, GenericAS>, Double, MemoryOrder]>;
+ def : Builtin<"atomic_fetch_" # ModOp # "_explicit",
+ [Double, PointerType<VolatileType<AtomicDouble>, GenericAS>, Double, MemoryOrder, MemoryScope]>;
+ }
+ }
+}
+
//--------------------------------------------------------------------
// OpenCL v1.1 s6.11.12, v1.2 s6.12.12, v2.0 s6.13.12 - Miscellaneous Vector Functions
// --- Table 19 ---
diff --git a/clang/test/Headers/opencl-c-header.cl b/clang/test/Headers/opencl-c-header.cl
index 50b9ebba8f0d2..d300803f86fbb 100644
--- a/clang/test/Headers/opencl-c-header.cl
+++ b/clang/test/Headers/opencl-c-header.cl
@@ -135,6 +135,51 @@ global atomic_int z = ATOMIC_VAR_INIT(99);
#if __opencl_c_integer_dot_product_input_4x8bit_packed != 1
#error "Incorrectly defined __opencl_c_integer_dot_product_input_4x8bit_packed"
#endif
+#if cl_ext_float_atomics != 1
+#error "Incorrectly defined cl_ext_float_atomics"
+#endif
+#if __opencl_c_ext_fp16_global_atomic_load_store != 1
+#error "Incorrectly defined __opencl_c_ext_fp16_global_atomic_load_store"
+#endif
+#if __opencl_c_ext_fp16_local_atomic_load_store != 1
+#error "Incorrectly defined __opencl_c_ext_fp16_local_atomic_load_store"
+#endif
+#if __opencl_c_ext_fp16_global_atomic_add != 1
+#error "Incorrectly defined __opencl_c_ext_fp16_global_atomic_add"
+#endif
+#if __opencl_c_ext_fp32_global_atomic_add != 1
+#error "Incorrectly defined __opencl_c_ext_fp32_global_atomic_add"
+#endif
+#if __opencl_c_ext_fp64_global_atomic_add != 1
+#error "Incorrectly defined __opencl_c_ext_fp64_global_atomic_add"
+#endif
+#if __opencl_c_ext_fp16_local_atomic_add != 1
+#error "Incorrectly defined __opencl_c_ext_fp16_local_atomic_add"
+#endif
+#if __opencl_c_ext_fp32_local_atomic_add != 1
+#error "Incorrectly defined __opencl_c_ext_fp32_local_atomic_add"
+#endif
+#if __opencl_c_ext_fp64_local_atomic_add != 1
+#error "Incorrectly defined __opencl_c_ext_fp64_local_atomic_add"
+#endif
+#if __opencl_c_ext_fp16_global_atomic_min_max != 1
+#error "Incorrectly defined __opencl_c_ext_fp16_global_atomic_min_max"
+#endif
+#if __opencl_c_ext_fp32_global_atomic_min_max != 1
+#error "Incorrectly defined __opencl_c_ext_fp32_global_atomic_min_max"
+#endif
+#if __opencl_c_ext_fp64_global_atomic_min_max != 1
+#error "Incorrectly defined __opencl_c_ext_fp64_global_atomic_min_max"
+#endif
+#if __opencl_c_ext_fp16_local_atomic_min_max != 1
+#error "Incorrectly defined __opencl_c_ext_fp16_local_atomic_min_max"
+#endif
+#if __opencl_c_ext_fp32_local_atomic_min_max != 1
+#error "Incorrectly defined __opencl_c_ext_fp32_local_atomic_min_max"
+#endif
+#if __opencl_c_ext_fp64_local_atomic_min_max != 1
+#error "Incorrectly defined __opencl_c_ext_fp64_local_atomic_min_max"
+#endif
#else
@@ -171,6 +216,51 @@ global atomic_int z = ATOMIC_VAR_INIT(99);
#ifdef __opencl_c_integer_dot_product_input_4x8bit_packed
#error "Incorrect __opencl_c_integer_dot_product_input_4x8bit_packed define"
#endif
+#ifdef cl_ext_float_atomics
+#error "Incorrect cl_ext_float_atomics define"
+#endif
+#ifdef __opencl_c_ext_fp16_global_atomic_load_store
+#error "Incorrectly __opencl_c_ext_fp16_global_atomic_load_store defined"
+#endif
+#ifdef __opencl_c_ext_fp16_local_atomic_load_store
+#error "Incorrectly __opencl_c_ext_fp16_local_atomic_load_store defined"
+#endif
+#ifdef __opencl_c_ext_fp16_global_atomic_add
+#error "Incorrectly __opencl_c_ext_fp16_global_atomic_add defined"
+#endif
+#ifdef __opencl_c_ext_fp32_global_atomic_add
+#error "Incorrectly __opencl_c_ext_fp32_global_atomic_add defined"
+#endif
+#ifdef __opencl_c_ext_fp64_global_atomic_add
+#error "Incorrectly __opencl_c_ext_fp64_global_atomic_add defined"
+#endif
+#ifdef __opencl_c_ext_fp16_local_atomic_add
+#error "Incorrectly __opencl_c_ext_fp16_local_atomic_add defined"
+#endif
+#ifdef __opencl_c_ext_fp32_local_atomic_add
+#error "Incorrectly __opencl_c_ext_fp32_local_atomic_add defined"
+#endif
+#ifdef __opencl_c_ext_fp64_local_atomic_add
+#error "Incorrectly __opencl_c_ext_fp64_local_atomic_add defined"
+#endif
+#ifdef __opencl_c_ext_fp16_global_atomic_min_max
+#error "Incorrectly __opencl_c_ext_fp16_global_atomic_min_max defined"
+#endif
+#ifdef __opencl_c_ext_fp32_global_atomic_min_max
+#error "Incorrectly __opencl_c_ext_fp32_global_atomic_min_max defined"
+#endif
+#ifdef __opencl_c_ext_fp64_global_atomic_min_max
+#error "Incorrectly __opencl_c_ext_fp64_global_atomic_min_max defined"
+#endif
+#ifdef __opencl_c_ext_fp16_local_atomic_min_max
+#error "Incorrectly __opencl_c_ext_fp16_local_atomic_min_max defined"
+#endif
+#ifdef __opencl_c_ext_fp32_local_atomic_min_max
+#error "Incorrectly __opencl_c_ext_fp32_local_atomic_min_max defined"
+#endif
+#ifdef __opencl_c_ext_fp64_local_atomic_min_max
+#error "Incorrectly __opencl_c_ext_fp64_local_atomic_min_max defined"
+#endif
#endif //(defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200)
diff --git a/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl b/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl
index 32457eb939c03..a6fb06fa52272 100644
--- a/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl
+++ b/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl
@@ -122,6 +122,27 @@ void test_atomic_fetch(volatile __generic atomic_int *a_int,
}
#endif
+#if !defined(NO_HEADER) && !defined(NO_FP64) && __OPENCL_C_VERSION__ >= 200
+// Check added atomic_fetch_ functions by cl_ext_float_atomics
+// extension can be called
+void test_atomic_fetch_with_address_space(volatile __generic atomic_float *a_float,
+ volatile __generic atomic_double *a_double,
+ volatile __local atomic_float *a_float_local,
+ volatile __local atomic_double *a_double_local,
+ volatile __global atomic_float *a_float_global,
+ volatile __global atomic_double *a_double_global) {
+ float f1, resf1;
+ double d1, resd1;
+ resf1 = atomic_fetch_min(a_float, f1);
+ resf1 = atomic_fetch_max_explicit(a_float_local, f1, memory_order_seq_cst);
+ resf1 = atomic_fetch_add_explicit(a_float_global, f1, memory_order_seq_cst, memory_scope_work_group);
+
+ resd1 = atomic_fetch_min(a_double, d1);
+ resd1 = atomic_fetch_max_explicit(a_double_local, d1, memory_order_seq_cst);
+ resd1 = atomic_fetch_add_explicit(a_double_global, d1, memory_order_seq_cst, memory_scope_work_group);
+}
+#endif // !defined(NO_HEADER) && __OPENCL_C_VERSION__ >= 200
+
// Test old atomic overloaded with generic address space in C++ for OpenCL.
#if __OPENCL_C_VERSION__ >= 200
void test_legacy_atomics_cpp(__generic volatile unsigned int *a) {
More information about the cfe-commits
mailing list