From d353d1c50112a1cb315eccdab18ce7bd1563cd06 Mon Sep 17 00:00:00 2001 From: Sven van Haastregt Date: Mon, 13 Sep 2021 12:06:04 +0100 Subject: [PATCH] [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 --- clang/lib/Headers/opencl-c-base.h | 19 ++ clang/lib/Headers/opencl-c.h | 209 ++++++++++++++++++++++ clang/lib/Sema/OpenCLBuiltins.td | 116 ++++++++++++ clang/test/Headers/opencl-c-header.cl | 90 ++++++++++ clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl | 21 +++ 5 files changed, 455 insertions(+) diff --git a/clang/lib/Headers/opencl-c-base.h b/clang/lib/Headers/opencl-c-base.h index f3605c6..7cc3560 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 bb3ca6a..e960228 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 cbf66ae..5d75c2b 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, 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, GlobalAS>, Float]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Float, PointerType, GlobalAS>, Float, MemoryOrder]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Float, PointerType, GlobalAS>, Float, MemoryOrder, MemoryScope]>; + } + let Extension = FuncExtFloatAtomicsFp64GlobalAdd in { + def : Builtin<"atomic_fetch_" # ModOp, + [Double, PointerType, GlobalAS>, Double]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Double, PointerType, GlobalAS>, Double, MemoryOrder]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Double, PointerType, GlobalAS>, Double, MemoryOrder, MemoryScope]>; + } + let Extension = FuncExtFloatAtomicsFp32LocalAdd in { + def : Builtin<"atomic_fetch_" # ModOp, + [Float, PointerType, LocalAS>, Float]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Float, PointerType, LocalAS>, Float, MemoryOrder]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Float, PointerType, LocalAS>, Float, MemoryOrder, MemoryScope]>; + } + let Extension = FuncExtFloatAtomicsFp64LocalAdd in { + def : Builtin<"atomic_fetch_" # ModOp, + [Double, PointerType, LocalAS>, Double]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Double, PointerType, LocalAS>, Double, MemoryOrder]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Double, PointerType, LocalAS>, Double, MemoryOrder, MemoryScope]>; + } + let Extension = FuncExtFloatAtomicsFp32GenericAdd in { + def : Builtin<"atomic_fetch_" # ModOp, + [Float, PointerType, GenericAS>, Float]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Float, PointerType, GenericAS>, Float, MemoryOrder]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Float, PointerType, GenericAS>, Float, MemoryOrder, MemoryScope]>; + } + let Extension = FuncExtFloatAtomicsFp64GenericAdd in { + def : Builtin<"atomic_fetch_" # ModOp, + [Double, PointerType, GenericAS>, Double]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Double, PointerType, GenericAS>, Double, MemoryOrder]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Double, PointerType, GenericAS>, Double, MemoryOrder, MemoryScope]>; + } + } + foreach ModOp = ["min", "max"] in { + let Extension = FuncExtFloatAtomicsFp32GlobalMinMax in { + def : Builtin<"atomic_fetch_" # ModOp, + [Float, PointerType, GlobalAS>, Float]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Float, PointerType, GlobalAS>, Float, MemoryOrder]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Float, PointerType, GlobalAS>, Float, MemoryOrder, MemoryScope]>; + } + let Extension = FuncExtFloatAtomicsFp64GlobalMinMax in { + def : Builtin<"atomic_fetch_" # ModOp, + [Double, PointerType, GlobalAS>, Double]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Double, PointerType, GlobalAS>, Double, MemoryOrder]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Double, PointerType, GlobalAS>, Double, MemoryOrder, MemoryScope]>; + } + let Extension = FuncExtFloatAtomicsFp32LocalMinMax in { + def : Builtin<"atomic_fetch_" # ModOp, + [Float, PointerType, LocalAS>, Float]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Float, PointerType, LocalAS>, Float, MemoryOrder]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Float, PointerType, LocalAS>, Float, MemoryOrder, MemoryScope]>; + } + let Extension = FuncExtFloatAtomicsFp64LocalMinMax in { + def : Builtin<"atomic_fetch_" # ModOp, + [Double, PointerType, LocalAS>, Double]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Double, PointerType, LocalAS>, Double, MemoryOrder]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Double, PointerType, LocalAS>, Double, MemoryOrder, MemoryScope]>; + } + let Extension = FuncExtFloatAtomicsFp32GenericMinMax in { + def : Builtin<"atomic_fetch_" # ModOp, + [Float, PointerType, GenericAS>, Float]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Float, PointerType, GenericAS>, Float, MemoryOrder]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Float, PointerType, GenericAS>, Float, MemoryOrder, MemoryScope]>; + } + let Extension = FuncExtFloatAtomicsFp64GenericMinMax in { + def : Builtin<"atomic_fetch_" # ModOp, + [Double, PointerType, GenericAS>, Double]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Double, PointerType, GenericAS>, Double, MemoryOrder]>; + def : Builtin<"atomic_fetch_" # ModOp # "_explicit", + [Double, PointerType, 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 50b9ebb..d300803 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 32457eb..a6fb06f 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) { -- 2.7.4