From 6177e7d95210131567d2891951b45a316a583bb4 Mon Sep 17 00:00:00 2001 From: Anuj Mittal Date: Tue, 19 Apr 2022 15:43:41 +0800 Subject: llvm-project-source: refresh patches Refresh the patches as recommended by the opencl-clang and include support for OpenCL 3.0. Signed-off-by: Anuj Mittal --- ...AGE_SUPPORT__-macro-for-SPIR-since-SPIR-d.patch | 2 +- ...ng-ParseCommandLineOptions-in-BackendUtil.patch | 14 +- .../llvm12-0003-Support-cl_ext_float_atomics.patch | 281 +- ...006-OpenCL-Add-cl_khr_integer_dot_product.patch | 146 + .../files/llvm12-0007-OpenCL-3.0-support.patch | 4628 ++++++++++++++++++++ .../clang/llvm-project-source.bbappend | 2 + 6 files changed, 5033 insertions(+), 40 deletions(-) create mode 100644 dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0006-OpenCL-Add-cl_khr_integer_dot_product.patch create mode 100644 dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0007-OpenCL-3.0-support.patch diff --git a/dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0001-Remove-__IMAGE_SUPPORT__-macro-for-SPIR-since-SPIR-d.patch b/dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0001-Remove-__IMAGE_SUPPORT__-macro-for-SPIR-since-SPIR-d.patch index 7e6c4f92..00f3607a 100644 --- a/dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0001-Remove-__IMAGE_SUPPORT__-macro-for-SPIR-since-SPIR-d.patch +++ b/dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0001-Remove-__IMAGE_SUPPORT__-macro-for-SPIR-since-SPIR-d.patch @@ -4,7 +4,7 @@ Date: Tue, 11 May 2021 11:13:02 +0800 Subject: [PATCH 1/3] Remove __IMAGE_SUPPORT__ macro for SPIR since SPIR doesn't require image support -Upstream-Status: Backport [Taken from opencl-clang patches, https://github.com/intel/opencl-clang/blob/ocl-open-120/patches/clang/0001-Remove-__IMAGE_SUPPORT__-macro-for-SPIR.patch] +Upstream-Status: Inappropriate Signed-off-by: haonanya Signed-off-by: Naveen Saini diff --git a/dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0002-Avoid-calling-ParseCommandLineOptions-in-BackendUtil.patch b/dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0002-Avoid-calling-ParseCommandLineOptions-in-BackendUtil.patch index 4f7d3e51..497db4f5 100644 --- a/dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0002-Avoid-calling-ParseCommandLineOptions-in-BackendUtil.patch +++ b/dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0002-Avoid-calling-ParseCommandLineOptions-in-BackendUtil.patch @@ -1,7 +1,7 @@ -From 06cf750d2ef892eaa4f0ff5d0a9e9e5c49697264 Mon Sep 17 00:00:00 2001 +From 60854c328d8729b2ef10b9bb4dcbcc282f43c5e7 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 1 Apr 2021 18:41:44 +0200 -Subject: [PATCH 2/3] Avoid calling ParseCommandLineOptions in BackendUtil if +Subject: [PATCH] Avoid calling ParseCommandLineOptions in BackendUtil if possible Calling `ParseCommandLineOptions` should only be called from `main` as the @@ -20,18 +20,18 @@ Reviewed By: JDevlieghere Differential Revision: https://reviews.llvm.org/D99740 -Upstream-Status: Backport [Taken from opencl-clang patches; https://github.com/intel/opencl-clang/blob/ocl-open-120/patches/clang/0002-Avoid-calling-ParseCommandLineOptions-in-BackendUtil.patch] - +Upstream-Status: Backport [https://github.com/llvm/llvm-project/commit/60854c328d8729b2ef10b9bb4dcbcc282f43c5e7] Signed-off-by: Naveen Saini + --- clang/lib/CodeGen/BackendUtil.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp -index 52bcd971dc8c..f9f891247530 100644 +index 41eafd13d97c..00d92e7beadd 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp -@@ -850,7 +850,15 @@ static void setCommandLineOpts(const CodeGenOptions &CodeGenOpts) { +@@ -871,7 +871,15 @@ static void setCommandLineOpts(const CodeGenOptions &CodeGenOpts) { BackendArgs.push_back("-limit-float-precision"); BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str()); } @@ -48,5 +48,5 @@ index 52bcd971dc8c..f9f891247530 100644 BackendArgs.data()); } -- -2.17.1 +2.29.2 diff --git a/dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0003-Support-cl_ext_float_atomics.patch b/dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0003-Support-cl_ext_float_atomics.patch index 99dbb81c..c609b08b 100644 --- a/dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0003-Support-cl_ext_float_atomics.patch +++ b/dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0003-Support-cl_ext_float_atomics.patch @@ -1,20 +1,28 @@ -From f1a24eeb89342186c6c718e02dd394775620799f Mon Sep 17 00:00:00 2001 +From 85505bdb386a426310c1fb0a845780beeeec4353 Mon Sep 17 00:00:00 2001 From: haonanya -Date: Wed, 28 Jul 2021 14:20:08 +0800 -Subject: [PATCH 3/3] Support cl_ext_float_atomics +Date: Wed, 9 Feb 2022 09:16:35 +0800 +Subject: [PATCH] Support cl_ext_float_atomics -Upstream-Status: Backport [Taken from opencl-clang patches; https://github.com/intel/opencl-clang/blob/ocl-open-120/patches/clang/0003-OpenCL-Support-cl_ext_float_atomics.patch] +This backports https://reviews.llvm.org/D106343 and https://reviews.llvm.org/D109740 Signed-off-by: haonanya + +Upstream-Status: Backport + +https://github.com/llvm/llvm-project/commit/d353d1c50112a1cb315eccdab18ce7bd1563cd06 +https://github.com/llvm/llvm-project/commit/544d89e847d42ce8856296752b0fb279aa89aace + Signed-off-by: Naveen Saini + --- - clang/lib/Headers/opencl-c-base.h | 19 +++ - clang/lib/Headers/opencl-c.h | 195 ++++++++++++++++++++++++++ - clang/test/Headers/opencl-c-header.cl | 72 ++++++++++ - 3 files changed, 286 insertions(+) + clang/lib/Headers/opencl-c-base.h | 19 ++ + clang/lib/Headers/opencl-c.h | 378 ++++++++++++++++++++++++++ + clang/lib/Sema/Sema.cpp | 3 + + clang/test/Headers/opencl-c-header.cl | 84 ++++++ + 4 files changed, 484 insertions(+) diff --git a/clang/lib/Headers/opencl-c-base.h b/clang/lib/Headers/opencl-c-base.h -index e8dcd70377e5..c8b6d36029ec 100644 +index e8dcd70377e5..d94d64372dbb 100644 --- a/clang/lib/Headers/opencl-c-base.h +++ b/clang/lib/Headers/opencl-c-base.h @@ -21,6 +21,25 @@ @@ -30,7 +38,7 @@ index e8dcd70377e5..c8b6d36029ec 100644 +#define __opencl_c_ext_fp16_global_atomic_min_max 1 +#define __opencl_c_ext_fp16_local_atomic_min_max 1 +#endif -+#ifdef __opencl_c_fp64 ++#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 @@ -44,15 +52,128 @@ index e8dcd70377e5..c8b6d36029ec 100644 #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 ab665628c8e1..6676da858d2a 100644 +index ab665628c8e1..584db7e81e04 100644 --- a/clang/lib/Headers/opencl-c.h +++ b/clang/lib/Headers/opencl-c.h -@@ -13531,6 +13531,201 @@ intptr_t __ovld atomic_fetch_max_explicit(volatile atomic_intptr_t *object, uint +@@ -13531,6 +13531,384 @@ intptr_t __ovld atomic_fetch_max_explicit(volatile atomic_intptr_t *object, uint intptr_t __ovld atomic_fetch_max_explicit(volatile atomic_intptr_t *object, uintptr_t opermax, memory_order minder, memory_scope scope); #endif ++// The functionality added by cl_ext_float_atomics extension +#if defined(cl_ext_float_atomics) + ++#if defined(__opencl_c_ext_fp16_global_atomic_load_store) ++void __ovld atomic_store(volatile __global atomic_half *object, half operand); ++void __ovld atomic_store_explicit(volatile __global atomic_half *object, ++ half operand, memory_order order); ++void __ovld atomic_store_explicit(volatile __global atomic_half *object, ++ half operand, memory_order order, ++ memory_scope scope); ++half __ovld atomic_load(volatile __global atomic_half *object); ++half __ovld atomic_load_explicit(volatile __global atomic_half *object, ++ memory_order order); ++half __ovld atomic_load_explicit(volatile __global atomic_half *object, ++ memory_order order, memory_scope scope); ++half __ovld atomic_exchange(volatile __global atomic_half *object, ++ half operand); ++half __ovld atomic_exchange_explicit(volatile __global atomic_half *object, ++ half operand, memory_order order); ++half __ovld atomic_exchange_explicit(volatile __global atomic_half *object, ++ half operand, memory_order order, ++ memory_scope scope); ++#endif // defined(__opencl_c_ext_fp16_global_atomic_load_store) ++ ++#if defined(__opencl_c_ext_fp16_local_atomic_load_store) ++void __ovld atomic_store(volatile __local atomic_half *object, half operand); ++void __ovld atomic_store_explicit(volatile __local atomic_half *object, ++ half operand, memory_order order); ++void __ovld atomic_store_explicit(volatile __local atomic_half *object, ++ half operand, memory_order order, ++ memory_scope scope); ++half __ovld atomic_load(volatile __local atomic_half *object); ++half __ovld atomic_load_explicit(volatile __local atomic_half *object, ++ memory_order order); ++half __ovld atomic_load_explicit(volatile __local atomic_half *object, ++ memory_order order, memory_scope scope); ++half __ovld atomic_exchange(volatile __local atomic_half *object, half operand); ++half __ovld atomic_exchange_explicit(volatile __local atomic_half *object, ++ half operand, memory_order order); ++half __ovld atomic_exchange_explicit(volatile __local atomic_half *object, ++ half operand, memory_order order, ++ memory_scope scope); ++#endif // defined(__opencl_c_ext_fp16_local_atomic_load_store) ++ ++#if defined(__opencl_c_ext_fp16_global_atomic_load_store) && \ ++ defined(__opencl_c_ext_fp16_local_atomic_load_store) ++void __ovld atomic_store(volatile atomic_half *object, half operand); ++void __ovld atomic_store_explicit(volatile atomic_half *object, half operand, ++ memory_order order); ++void __ovld atomic_store_explicit(volatile atomic_half *object, half operand, ++ memory_order order, memory_scope scope); ++half __ovld atomic_load(volatile atomic_half *object); ++half __ovld atomic_load_explicit(volatile atomic_half *object, ++ memory_order order); ++half __ovld atomic_load_explicit(volatile atomic_half *object, ++ memory_order order, memory_scope scope); ++half __ovld atomic_exchange(volatile atomic_half *object, half operand); ++half __ovld atomic_exchange_explicit(volatile atomic_half *object, half operand, ++ memory_order order); ++half __ovld atomic_exchange_explicit(volatile atomic_half *object, half operand, ++ memory_order order, memory_scope scope); ++#endif // defined(__opencl_c_ext_fp16_global_atomic_load_store) && ++ // defined(__opencl_c_ext_fp16_local_atomic_load_store) ++ ++#if defined(__opencl_c_ext_fp16_global_atomic_min_max) ++half __ovld atomic_fetch_min(volatile __global atomic_half *object, ++ half operand); ++half __ovld atomic_fetch_max(volatile __global atomic_half *object, ++ half operand); ++half __ovld atomic_fetch_min_explicit(volatile __global atomic_half *object, ++ half operand, memory_order order); ++half __ovld atomic_fetch_max_explicit(volatile __global atomic_half *object, ++ half operand, memory_order order); ++half __ovld atomic_fetch_min_explicit(volatile __global atomic_half *object, ++ half operand, memory_order order, ++ memory_scope scope); ++half __ovld atomic_fetch_max_explicit(volatile __global atomic_half *object, ++ half operand, memory_order order, ++ memory_scope scope); ++#endif // defined(__opencl_c_ext_fp16_global_atomic_min_max) ++ ++#if defined(__opencl_c_ext_fp16_local_atomic_min_max) ++half __ovld atomic_fetch_min(volatile __local atomic_half *object, ++ half operand); ++half __ovld atomic_fetch_max(volatile __local atomic_half *object, ++ half operand); ++half __ovld atomic_fetch_min_explicit(volatile __local atomic_half *object, ++ half operand, memory_order order); ++half __ovld atomic_fetch_max_explicit(volatile __local atomic_half *object, ++ half operand, memory_order order); ++half __ovld atomic_fetch_min_explicit(volatile __local atomic_half *object, ++ half operand, memory_order order, ++ memory_scope scope); ++half __ovld atomic_fetch_max_explicit(volatile __local atomic_half *object, ++ half operand, memory_order order, ++ memory_scope scope); ++#endif // defined(__opencl_c_ext_fp16_local_atomic_min_max) ++ ++#if defined(__opencl_c_ext_fp16_global_atomic_min_max) && \ ++ defined(__opencl_c_ext_fp16_local_atomic_min_max) ++half __ovld atomic_fetch_min(volatile atomic_half *object, half operand); ++half __ovld atomic_fetch_max(volatile atomic_half *object, half operand); ++half __ovld atomic_fetch_min_explicit(volatile atomic_half *object, ++ half operand, memory_order order); ++half __ovld atomic_fetch_max_explicit(volatile atomic_half *object, ++ half operand, memory_order order); ++half __ovld atomic_fetch_min_explicit(volatile atomic_half *object, ++ half operand, memory_order order, ++ memory_scope scope); ++half __ovld atomic_fetch_max_explicit(volatile atomic_half *object, ++ half operand, memory_order order, ++ memory_scope scope); ++#endif // defined(__opencl_c_ext_fp16_global_atomic_min_max) && \ ++ defined(__opencl_c_ext_fp16_local_atomic_min_max) ++ +#if defined(__opencl_c_ext_fp32_global_atomic_min_max) +float __ovld atomic_fetch_min(volatile __global atomic_float *object, + float operand); @@ -68,7 +189,8 @@ index ab665628c8e1..6676da858d2a 100644 +float __ovld atomic_fetch_max_explicit(volatile __global atomic_float *object, + float operand, memory_order order, + memory_scope scope); -+#endif ++#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); @@ -84,8 +206,9 @@ index ab665628c8e1..6676da858d2a 100644 +float __ovld atomic_fetch_max_explicit(volatile __local atomic_float *object, + float operand, memory_order order, + memory_scope scope); -+#endif -+#if defined(__opencl_c_ext_fp32_global_atomic_min_max) || \ ++#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); @@ -99,7 +222,10 @@ index ab665628c8e1..6676da858d2a 100644 +float __ovld atomic_fetch_max_explicit(volatile atomic_float *object, + float operand, memory_order order, + memory_scope scope); -+#endif ++#endif // defined(__opencl_c_ext_fp32_global_atomic_min_max) && \ ++ defined(__opencl_c_ext_fp32_local_atomic_min_max) ++ ++#if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) +#if defined(__opencl_c_ext_fp64_global_atomic_min_max) +double __ovld atomic_fetch_min(volatile __global atomic_double *object, + double operand); @@ -115,7 +241,8 @@ index ab665628c8e1..6676da858d2a 100644 +double __ovld atomic_fetch_max_explicit(volatile __global atomic_double *object, + double operand, memory_order order, + memory_scope scope); -+#endif ++#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); @@ -131,8 +258,9 @@ index ab665628c8e1..6676da858d2a 100644 +double __ovld atomic_fetch_max_explicit(volatile __local atomic_double *object, + double operand, memory_order order, + memory_scope scope); -+#endif -+#if defined(__opencl_c_ext_fp64_global_atomic_min_max) || \ ++#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); @@ -146,7 +274,61 @@ index ab665628c8e1..6676da858d2a 100644 +double __ovld atomic_fetch_max_explicit(volatile atomic_double *object, + double operand, memory_order order, + memory_scope scope); -+#endif ++#endif // defined(__opencl_c_ext_fp64_global_atomic_min_max) && \ ++ defined(__opencl_c_ext_fp64_local_atomic_min_max) ++#endif // defined(cl_khr_int64_base_atomics) && ++ // defined(cl_khr_int64_extended_atomics) ++ ++#if defined(__opencl_c_ext_fp16_global_atomic_add) ++half __ovld atomic_fetch_add(volatile __global atomic_half *object, ++ half operand); ++half __ovld atomic_fetch_sub(volatile __global atomic_half *object, ++ half operand); ++half __ovld atomic_fetch_add_explicit(volatile __global atomic_half *object, ++ half operand, memory_order order); ++half __ovld atomic_fetch_sub_explicit(volatile __global atomic_half *object, ++ half operand, memory_order order); ++half __ovld atomic_fetch_add_explicit(volatile __global atomic_half *object, ++ half operand, memory_order order, ++ memory_scope scope); ++half __ovld atomic_fetch_sub_explicit(volatile __global atomic_half *object, ++ half operand, memory_order order, ++ memory_scope scope); ++#endif // defined(__opencl_c_ext_fp16_global_atomic_add) ++ ++#if defined(__opencl_c_ext_fp16_local_atomic_add) ++half __ovld atomic_fetch_add(volatile __local atomic_half *object, ++ half operand); ++half __ovld atomic_fetch_sub(volatile __local atomic_half *object, ++ half operand); ++half __ovld atomic_fetch_add_explicit(volatile __local atomic_half *object, ++ half operand, memory_order order); ++half __ovld atomic_fetch_sub_explicit(volatile __local atomic_half *object, ++ half operand, memory_order order); ++half __ovld atomic_fetch_add_explicit(volatile __local atomic_half *object, ++ half operand, memory_order order, ++ memory_scope scope); ++half __ovld atomic_fetch_sub_explicit(volatile __local atomic_half *object, ++ half operand, memory_order order, ++ memory_scope scope); ++#endif // defined(__opencl_c_ext_fp16_local_atomic_add) ++ ++#if defined(__opencl_c_ext_fp16_global_atomic_add) && \ ++ defined(__opencl_c_ext_fp16_local_atomic_add) ++half __ovld atomic_fetch_add(volatile atomic_half *object, half operand); ++half __ovld atomic_fetch_sub(volatile atomic_half *object, half operand); ++half __ovld atomic_fetch_add_explicit(volatile atomic_half *object, ++ half operand, memory_order order); ++half __ovld atomic_fetch_sub_explicit(volatile atomic_half *object, ++ half operand, memory_order order); ++half __ovld atomic_fetch_add_explicit(volatile atomic_half *object, ++ half operand, memory_order order, ++ memory_scope scope); ++half __ovld atomic_fetch_sub_explicit(volatile atomic_half *object, ++ half operand, memory_order order, ++ memory_scope scope); ++#endif // defined(__opencl_c_ext_fp16_global_atomic_add) && \ ++ defined(__opencl_c_ext_fp16_local_atomic_add) + +#if defined(__opencl_c_ext_fp32_global_atomic_add) +float __ovld atomic_fetch_add(volatile __global atomic_float *object, @@ -163,7 +345,8 @@ index ab665628c8e1..6676da858d2a 100644 +float __ovld atomic_fetch_sub_explicit(volatile __global atomic_float *object, + float operand, memory_order order, + memory_scope scope); -+#endif ++#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); @@ -179,8 +362,9 @@ index ab665628c8e1..6676da858d2a 100644 +float __ovld atomic_fetch_sub_explicit(volatile __local atomic_float *object, + float operand, memory_order order, + memory_scope scope); -+#endif -+#if defined(__opencl_c_ext_fp32_global_atomic_add) || \ ++#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); @@ -194,8 +378,10 @@ index ab665628c8e1..6676da858d2a 100644 +float __ovld atomic_fetch_sub_explicit(volatile atomic_float *object, + float operand, memory_order order, + memory_scope scope); -+#endif ++#endif // defined(__opencl_c_ext_fp32_global_atomic_add) && \ ++ defined(__opencl_c_ext_fp32_local_atomic_add) + ++#if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) +#if defined(__opencl_c_ext_fp64_global_atomic_add) +double __ovld atomic_fetch_add(volatile __global atomic_double *object, + double operand); @@ -211,7 +397,8 @@ index ab665628c8e1..6676da858d2a 100644 +double __ovld atomic_fetch_sub_explicit(volatile __global atomic_double *object, + double operand, memory_order order, + memory_scope scope); -+#endif ++#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); @@ -227,8 +414,9 @@ index ab665628c8e1..6676da858d2a 100644 +double __ovld atomic_fetch_sub_explicit(volatile __local atomic_double *object, + double operand, memory_order order, + memory_scope scope); -+#endif -+#if defined(__opencl_c_ext_fp64_global_atomic_add) || \ ++#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); @@ -242,18 +430,35 @@ index ab665628c8e1..6676da858d2a 100644 +double __ovld atomic_fetch_sub_explicit(volatile atomic_double *object, + double operand, memory_order order, + memory_scope scope); -+#endif ++#endif // defined(__opencl_c_ext_fp64_global_atomic_add) && \ ++ defined(__opencl_c_ext_fp64_local_atomic_add) ++#endif // defined(cl_khr_int64_base_atomics) && ++ // defined(cl_khr_int64_extended_atomics) + +#endif // cl_ext_float_atomics + // atomic_store() void __ovld atomic_store(volatile atomic_int *object, int desired); +diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp +index 450f9c020f7f..a91291c7af38 100644 +--- a/clang/lib/Sema/Sema.cpp ++++ b/clang/lib/Sema/Sema.cpp +@@ -313,6 +313,9 @@ void Sema::Initialize() { + addImplicitTypedef("atomic_long", AtomicLongT); + auto AtomicULongT = Context.getAtomicType(Context.UnsignedLongTy); + addImplicitTypedef("atomic_ulong", AtomicULongT); ++ auto AtomicHalfT = Context.getAtomicType(Context.HalfTy); ++ addImplicitTypedef("atomic_half", AtomicHalfT); ++ setOpenCLExtensionForType(AtomicHalfT, "cl_khr_fp16"); + addImplicitTypedef("atomic_float", + Context.getAtomicType(Context.FloatTy)); + auto AtomicDoubleT = Context.getAtomicType(Context.DoubleTy); diff --git a/clang/test/Headers/opencl-c-header.cl b/clang/test/Headers/opencl-c-header.cl -index 13a3b62481ec..2c02d14f25c3 100644 +index 13a3b62481ec..443f682c711a 100644 --- a/clang/test/Headers/opencl-c-header.cl +++ b/clang/test/Headers/opencl-c-header.cl -@@ -124,6 +124,36 @@ global atomic_int z = ATOMIC_VAR_INIT(99); +@@ -124,6 +124,48 @@ global atomic_int z = ATOMIC_VAR_INIT(99); #if cl_khr_subgroup_clustered_reduce != 1 #error "Incorrectly defined cl_khr_subgroup_clustered_reduce" #endif @@ -269,28 +474,40 @@ index 13a3b62481ec..2c02d14f25c3 100644 +#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 -@@ -148,6 +178,48 @@ global atomic_int z = ATOMIC_VAR_INIT(99); +@@ -148,6 +190,48 @@ global atomic_int z = ATOMIC_VAR_INIT(99); #ifdef cl_khr_subgroup_clustered_reduce #error "Incorrect cl_khr_subgroup_clustered_reduce define" #endif @@ -340,5 +557,5 @@ index 13a3b62481ec..2c02d14f25c3 100644 #endif //(defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200) -- -2.17.1 +2.29.2 diff --git a/dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0006-OpenCL-Add-cl_khr_integer_dot_product.patch b/dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0006-OpenCL-Add-cl_khr_integer_dot_product.patch new file mode 100644 index 00000000..25174047 --- /dev/null +++ b/dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0006-OpenCL-Add-cl_khr_integer_dot_product.patch @@ -0,0 +1,146 @@ +From 54802abece1e4742050795162e3a773f0e143aa3 Mon Sep 17 00:00:00 2001 +From: haonanya +Date: Fri, 24 Dec 2021 15:27:46 +0800 +Subject: [PATCH] [OpenCL] Add cl_khr_integer_dot_product + +This is backporting of https://reviews.llvm.org/D106434 +Add the builtins defined by Section 42 "Integer dot product" in the OpenCL +Extension Specification. + +See https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_Ext.html#cl_khr_integer_dot_product + +Signed-off-by: haonanya + +Upstream-Status: Backport [https://github.com/llvm/llvm-project/commit/989bedec7a6ae95a0db865f23677047f78dc9257] +Signed-off-by: Anuj Mittal +--- + clang/lib/Headers/opencl-c-base.h | 3 +++ + clang/lib/Headers/opencl-c.h | 24 ++++++++++++++++++++++++ + clang/lib/Sema/OpenCLBuiltins.td | 25 +++++++++++++++++++++++++ + clang/test/Headers/opencl-c-header.cl | 18 ++++++++++++++++++ + 4 files changed, 70 insertions(+) + +diff --git a/clang/lib/Headers/opencl-c-base.h b/clang/lib/Headers/opencl-c-base.h +index d94d64372dbb..b55d9601a452 100644 +--- a/clang/lib/Headers/opencl-c-base.h ++++ b/clang/lib/Headers/opencl-c-base.h +@@ -40,6 +40,9 @@ + #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 ++#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 + #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 501a04f6e82b..50dcc03955cb 100644 +--- a/clang/lib/Headers/opencl-c.h ++++ b/clang/lib/Headers/opencl-c.h +@@ -16362,6 +16362,30 @@ double __ovld sub_group_clustered_reduce_max( double value, uint clustersize ); + + #endif // cl_khr_subgroup_clustered_reduce + ++#if defined(__opencl_c_integer_dot_product_input_4x8bit) ++uint __ovld __cnfn dot(uchar4, uchar4); ++int __ovld __cnfn dot(char4, char4); ++int __ovld __cnfn dot(uchar4, char4); ++int __ovld __cnfn dot(char4, uchar4); ++ ++uint __ovld __cnfn dot_acc_sat(uchar4, uchar4, uint); ++int __ovld __cnfn dot_acc_sat(char4, char4, int); ++int __ovld __cnfn dot_acc_sat(uchar4, char4, int); ++int __ovld __cnfn dot_acc_sat(char4, uchar4, int); ++#endif // __opencl_c_integer_dot_product_input_4x8bit ++ ++#if defined(__opencl_c_integer_dot_product_input_4x8bit_packed) ++uint __ovld __cnfn dot_4x8packed_uu_uint(uint, uint); ++int __ovld __cnfn dot_4x8packed_ss_int(uint, uint); ++int __ovld __cnfn dot_4x8packed_us_int(uint, uint); ++int __ovld __cnfn dot_4x8packed_su_int(uint, uint); ++ ++uint __ovld __cnfn dot_acc_sat_4x8packed_uu_uint(uint, uint, uint); ++int __ovld __cnfn dot_acc_sat_4x8packed_ss_int(uint, uint, int); ++int __ovld __cnfn dot_acc_sat_4x8packed_us_int(uint, uint, int); ++int __ovld __cnfn dot_acc_sat_4x8packed_su_int(uint, uint, int); ++#endif // __opencl_c_integer_dot_product_input_4x8bit_packed ++ + #if defined(cl_intel_subgroups) + // Intel-Specific Sub Group Functions + float __ovld __conv intel_sub_group_shuffle( float x, uint c ); +diff --git a/clang/lib/Sema/OpenCLBuiltins.td b/clang/lib/Sema/OpenCLBuiltins.td +index 745363a6b43f..3c5f8821063d 100644 +--- a/clang/lib/Sema/OpenCLBuiltins.td ++++ b/clang/lib/Sema/OpenCLBuiltins.td +@@ -1482,6 +1482,31 @@ let Extension = FuncExtKhrSubgroups in { + } + } + ++// Section 42.3 - cl_khr_integer_dot_product ++let Extension = FunctionExtension<"__opencl_c_integer_dot_product_input_4x8bit"> in { ++ def : Builtin<"dot", [UInt, VectorType, VectorType], Attr.Const>; ++ def : Builtin<"dot", [Int, VectorType, VectorType], Attr.Const>; ++ def : Builtin<"dot", [Int, VectorType, VectorType], Attr.Const>; ++ def : Builtin<"dot", [Int, VectorType, VectorType], Attr.Const>; ++ ++ def : Builtin<"dot_acc_sat", [UInt, VectorType, VectorType, UInt], Attr.Const>; ++ def : Builtin<"dot_acc_sat", [Int, VectorType, VectorType, Int], Attr.Const>; ++ def : Builtin<"dot_acc_sat", [Int, VectorType, VectorType, Int], Attr.Const>; ++ def : Builtin<"dot_acc_sat", [Int, VectorType, VectorType, Int], Attr.Const>; ++} ++ ++let Extension = FunctionExtension<"__opencl_c_integer_dot_product_input_4x8bit_packed"> in { ++ def : Builtin<"dot_4x8packed_uu_uint", [UInt, UInt, UInt], Attr.Const>; ++ def : Builtin<"dot_4x8packed_ss_int", [Int, UInt, UInt], Attr.Const>; ++ def : Builtin<"dot_4x8packed_us_int", [Int, UInt, UInt], Attr.Const>; ++ def : Builtin<"dot_4x8packed_su_int", [Int, UInt, UInt], Attr.Const>; ++ ++ def : Builtin<"dot_acc_sat_4x8packed_uu_uint", [UInt, UInt, UInt, UInt], Attr.Const>; ++ def : Builtin<"dot_acc_sat_4x8packed_ss_int", [Int, UInt, UInt, Int], Attr.Const>; ++ def : Builtin<"dot_acc_sat_4x8packed_us_int", [Int, UInt, UInt, Int], Attr.Const>; ++ def : Builtin<"dot_acc_sat_4x8packed_su_int", [Int, UInt, UInt, Int], Attr.Const>; ++} ++ + //-------------------------------------------------------------------- + // Arm extensions. + let Extension = ArmIntegerDotProductInt8 in { +diff --git a/clang/test/Headers/opencl-c-header.cl b/clang/test/Headers/opencl-c-header.cl +index 443f682c711a..184eefd9f9c3 100644 +--- a/clang/test/Headers/opencl-c-header.cl ++++ b/clang/test/Headers/opencl-c-header.cl +@@ -166,6 +166,15 @@ global atomic_int z = ATOMIC_VAR_INIT(99); + #if __opencl_c_ext_fp64_local_atomic_min_max != 1 + #error "Incorrectly defined __opencl_c_ext_fp64_local_atomic_min_max" + #endif ++#if cl_khr_integer_dot_product != 1 ++#error "Incorrectly defined cl_khr_integer_dot_product" ++#endif ++#if __opencl_c_integer_dot_product_input_4x8bit != 1 ++#error "Incorrectly defined __opencl_c_integer_dot_product_input_4x8bit" ++#endif ++#if __opencl_c_integer_dot_product_input_4x8bit_packed != 1 ++#error "Incorrectly defined __opencl_c_integer_dot_product_input_4x8bit_packed" ++#endif + + #else + +@@ -232,6 +241,15 @@ global atomic_int z = ATOMIC_VAR_INIT(99); + #ifdef __opencl_c_ext_fp64_local_atomic_min_max + #error "Incorrectly __opencl_c_ext_fp64_local_atomic_min_max defined" + #endif ++#ifdef cl_khr_integer_dot_product ++#error "Incorrect cl_khr_integer_dot_product define" ++#endif ++#ifdef __opencl_c_integer_dot_product_input_4x8bit ++#error "Incorrect __opencl_c_integer_dot_product_input_4x8bit define" ++#endif ++#ifdef __opencl_c_integer_dot_product_input_4x8bit_packed ++#error "Incorrect __opencl_c_integer_dot_product_input_4x8bit_packed define" ++#endif + + #endif //(defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200) + +-- +2.17.1 + diff --git a/dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0007-OpenCL-3.0-support.patch b/dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0007-OpenCL-3.0-support.patch new file mode 100644 index 00000000..567db40d --- /dev/null +++ b/dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0007-OpenCL-3.0-support.patch @@ -0,0 +1,4628 @@ +From cc23dafd55bfe102e490c719f8b088e6b2a52561 Mon Sep 17 00:00:00 2001 +From: Haonan Yang +Date: Fri, 15 Apr 2022 15:52:37 +0800 +Subject: [PATCH] OpenCL 3.0 support + +Signed-off-by: Haonan Yang + +Upstream-Status: Submitted +Signed-off-by: Anuj Mittal +--- + clang/docs/OpenCLSupport.rst | 19 +- + .../clang/Basic/DiagnosticCommonKinds.td | 10 + + clang/include/clang/Basic/DiagnosticGroups.td | 2 + + .../clang/Basic/DiagnosticParseKinds.td | 5 +- + .../clang/Basic/DiagnosticSemaKinds.td | 13 +- + clang/include/clang/Basic/LangOptions.def | 2 + + .../include/clang/Basic/OpenCLExtensions.def | 82 +-- + clang/include/clang/Basic/OpenCLOptions.h | 71 ++- + clang/include/clang/Basic/TargetInfo.h | 18 +- + clang/include/clang/Sema/Overload.h | 3 - + clang/include/clang/Sema/Sema.h | 82 --- + clang/include/clang/Serialization/ASTWriter.h | 2 - + clang/lib/Basic/OpenCLOptions.cpp | 103 +++- + clang/lib/Basic/TargetInfo.cpp | 26 + + clang/lib/Basic/Targets.cpp | 43 +- + clang/lib/Basic/Targets/AMDGPU.h | 6 +- + clang/lib/Basic/Targets/NVPTX.h | 1 + + clang/lib/Basic/Targets/X86.cpp | 10 +- + clang/lib/Frontend/CompilerInstance.cpp | 5 + + clang/lib/Frontend/CompilerInvocation.cpp | 3 + + clang/lib/Frontend/InitPreprocessor.cpp | 25 +- + clang/lib/Headers/opencl-c-base.h | 15 + + clang/lib/Headers/opencl-c.h | 493 ++++++++++-------- + clang/lib/Parse/ParseDecl.cpp | 16 +- + clang/lib/Parse/ParsePragma.cpp | 17 +- + clang/lib/Parse/Parser.cpp | 2 - + clang/lib/Sema/DeclSpec.cpp | 3 +- + clang/lib/Sema/Sema.cpp | 185 ++----- + clang/lib/Sema/SemaCast.cpp | 4 +- + clang/lib/Sema/SemaChecking.cpp | 3 +- + clang/lib/Sema/SemaDecl.cpp | 36 +- + clang/lib/Sema/SemaDeclAttr.cpp | 17 +- + clang/lib/Sema/SemaExpr.cpp | 26 +- + clang/lib/Sema/SemaInit.cpp | 8 +- + clang/lib/Sema/SemaLookup.cpp | 22 +- + clang/lib/Sema/SemaOverload.cpp | 17 - + clang/lib/Sema/SemaType.cpp | 56 +- + clang/lib/Serialization/ASTReader.cpp | 27 +- + clang/lib/Serialization/ASTWriter.cpp | 71 +-- + .../CodeGenOpenCL/addr-space-struct-arg.cl | 6 +- + .../address-spaces-conversions.cl | 2 + + .../CodeGenOpenCL/address-spaces-mangling.cl | 6 +- + clang/test/CodeGenOpenCL/address-spaces.cl | 4 + + .../CodeGenOpenCL/amdgpu-sizeof-alignof.cl | 21 +- + .../CodeGenOpenCL/arm-integer-dot-product.cl | 11 +- + clang/test/CodeGenOpenCL/extension-begin.cl | 25 - + clang/test/CodeGenOpenCL/overload.cl | 1 + + clang/test/CodeGenOpenCL/printf.cl | 6 +- + clang/test/Headers/opencl-c-header.cl | 84 +++ + clang/test/Misc/nvptx.unsupported_core.cl | 7 + + clang/test/Misc/warning-flags.c | 2 +- + clang/test/Parser/opencl-atomics-cl20.cl | 104 ++-- + clang/test/SemaOpenCL/access-qualifier.cl | 40 +- + .../address-spaces-conversions-cl2.0.cl | 3 + + clang/test/SemaOpenCL/address-spaces.cl | 1 + + .../SemaOpenCL/arm-integer-dot-product.cl | 42 +- + .../SemaOpenCL/cl20-device-side-enqueue.cl | 4 +- + clang/test/SemaOpenCL/extension-begin.cl | 28 +- + clang/test/SemaOpenCL/extension-begin.h | 9 +- + clang/test/SemaOpenCL/extension-version.cl | 62 ++- + clang/test/SemaOpenCL/extensions.cl | 71 ++- + .../SemaOpenCL/fdeclare-opencl-builtins.cl | 27 +- + clang/test/SemaOpenCL/features.cl | 48 ++ + .../intel-subgroup-avc-ext-types.cl | 69 ++- + clang/test/SemaOpenCL/storageclass.cl | 234 ++++++++- + clang/test/SemaOpenCL/unsupported-image.cl | 69 +++ + 66 files changed, 1502 insertions(+), 1033 deletions(-) + delete mode 100644 clang/test/CodeGenOpenCL/extension-begin.cl + create mode 100644 clang/test/Misc/nvptx.unsupported_core.cl + create mode 100644 clang/test/SemaOpenCL/features.cl + create mode 100644 clang/test/SemaOpenCL/unsupported-image.cl + +diff --git a/clang/docs/OpenCLSupport.rst b/clang/docs/OpenCLSupport.rst +index 0eaf0f300ee4..cba2539a6d11 100644 +--- a/clang/docs/OpenCLSupport.rst ++++ b/clang/docs/OpenCLSupport.rst +@@ -61,7 +61,24 @@ Missing features or with limited support + + .. _opencl_300: + +-OpenCL 3.0 Implementation Status ++OpenCL C 3.0 Usage ++================================ ++ ++OpenCL C 3.0 language standard makes most OpenCL C 2.0 features optional. Optional ++functionality in OpenCL C 3.0 is indicated with the presence of feature-test macros ++(list of feature-test macros is `here `_). ++Command-line flag :ref:`-cl-ext ` can be used to override features supported by a target. ++ ++For cases when there is an associated extension for a specific feature (fp64 and 3d image writes) ++user should specify both (extension and feature) in command-line flag: ++ ++ .. code-block:: console ++ ++ $ clang -cc1 -cl-std=CL3.0 -cl-ext=+cl_khr_fp64,+__opencl_c_fp64 ... ++ $ clang -cc1 -cl-std=CL3.0 -cl-ext=-cl_khr_fp64,-__opencl_c_fp64 ... ++ ++ ++OpenCL C 3.0 Implementation Status + ================================ + + The following table provides an overview of features in OpenCL C 3.0 and their +diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td +index a4f96a97991e..734701ce9d9d 100644 +--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td ++++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td +@@ -347,4 +347,14 @@ def note_suggest_disabling_all_checkers : Note< + def warn_poison_system_directories : Warning < + "include location '%0' is unsafe for cross-compilation">, + InGroup>, DefaultIgnore; ++ ++def warn_opencl_unsupported_core_feature : Warning< ++ "%0 is a core feature in %select{OpenCL C|C++ for OpenCL}1 version %2 but not supported on this target">, ++ InGroup, DefaultIgnore; ++ ++def err_opencl_extension_and_feature_differs : Error< ++ "options %0 and %1 are set to different values">; ++ ++def err_opencl_feature_requires : Error< ++ "feature %0 requires support of %1 feature">; + } +diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td +index 04ba89aa457e..93099dd19a80 100644 +--- a/clang/include/clang/Basic/DiagnosticGroups.td ++++ b/clang/include/clang/Basic/DiagnosticGroups.td +@@ -1247,3 +1247,5 @@ in addition with the pragmas or -fmax-tokens flag to get any warnings. + def WebAssemblyExceptionSpec : DiagGroup<"wasm-exception-spec">; + + def RTTI : DiagGroup<"rtti">; ++ ++def OpenCLCoreFeaturesDiagGroup : DiagGroup<"pedantic-core-features">; +diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td +index 0ed80a481e78..5887cc81e32a 100644 +--- a/clang/include/clang/Basic/DiagnosticParseKinds.td ++++ b/clang/include/clang/Basic/DiagnosticParseKinds.td +@@ -1228,14 +1228,13 @@ def warn_pragma_expected_colon : Warning< + "missing ':' after %0 - ignoring">, InGroup; + def warn_pragma_expected_predicate : Warning< + "expected %select{'enable', 'disable', 'begin' or 'end'|'disable'}0 - ignoring">, InGroup; +-def warn_pragma_begin_end_mismatch : Warning< +- "OpenCL extension end directive mismatches begin directive - ignoring">, InGroup; + def warn_pragma_unknown_extension : Warning< + "unknown OpenCL extension %0 - ignoring">, InGroup; + def warn_pragma_unsupported_extension : Warning< + "unsupported OpenCL extension %0 - ignoring">, InGroup; + def warn_pragma_extension_is_core : Warning< +- "OpenCL extension %0 is core feature or supported optional core feature - ignoring">, InGroup>, DefaultIgnore; ++ "OpenCL extension %0 is core feature or supported optional core feature - ignoring">, ++ InGroup, DefaultIgnore; + + // OpenCL errors. + def err_opencl_taking_function_address_parser : Error< +diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td +index 67c59f3ca09a..7d45654f5ea2 100644 +--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td ++++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td +@@ -118,7 +118,8 @@ def warn_float_underflow : Warning< + "magnitude of floating-point constant too small for type %0; minimum is %1">, + InGroup; + def warn_double_const_requires_fp64 : Warning< +- "double precision constant requires cl_khr_fp64, casting to single precision">; ++ "double precision constant requires %select{cl_khr_fp64|cl_khr_fp64 and __opencl_c_fp64}0, " ++ "casting to single precision">; + def err_half_const_requires_fp16 : Error< + "half precision constant requires cl_khr_fp16">; + +@@ -4279,8 +4280,6 @@ def warn_diagnose_if_succeeded : Warning<"%0">, InGroup, + ShowInSystemHeader; + def note_ovl_candidate_disabled_by_function_cond_attr : Note< + "candidate disabled: %0">; +-def note_ovl_candidate_disabled_by_extension : Note< +- "candidate unavailable as it requires OpenCL extension '%0' to be enabled">; + def err_addrof_function_disabled_by_enable_if_attr : Error< + "cannot take address of function %0 because it has one or more " + "non-tautological enable_if conditions">; +@@ -9892,7 +9891,10 @@ def warn_opencl_attr_deprecated_ignored : Warning < + def err_opencl_variadic_function : Error< + "invalid prototype, variadic arguments are not allowed in OpenCL">; + def err_opencl_requires_extension : Error< +- "use of %select{type|declaration}0 %1 requires %2 extension to be enabled">; ++ "use of %select{type|declaration}0 %1 requires %2 support">; ++def ext_opencl_double_without_pragma : Extension< ++ "Clang permits use of type 'double' regardless pragma if 'cl_khr_fp64' is" ++ " supported">; + def warn_opencl_generic_address_space_arg : Warning< + "passing non-generic address space pointer to %0" + " may cause dynamic conversion affecting performance">, +@@ -9912,7 +9914,8 @@ def err_opencl_builtin_pipe_invalid_access_modifier : Error< + def err_opencl_invalid_access_qualifier : Error< + "access qualifier can only be used for pipe and image type">; + def err_opencl_invalid_read_write : Error< +- "access qualifier %0 can not be used for %1 %select{|prior to OpenCL version 2.0}2">; ++ "access qualifier %0 can not be used for %1 %select{|prior to OpenCL C version 2.0 or in version 3.0 " ++ "and without __opencl_c_read_write_images feature}2">; + def err_opencl_multiple_access_qualifiers : Error< + "multiple access qualifiers">; + def note_opencl_typedef_access_qualifier : Note< +diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def +index c01f0cca9c9c..d41ef34ad5df 100644 +--- a/clang/include/clang/Basic/LangOptions.def ++++ b/clang/include/clang/Basic/LangOptions.def +@@ -215,6 +215,8 @@ LANGOPT(OpenCL , 1, 0, "OpenCL") + LANGOPT(OpenCLVersion , 32, 0, "OpenCL C version") + LANGOPT(OpenCLCPlusPlus , 1, 0, "C++ for OpenCL") + LANGOPT(OpenCLCPlusPlusVersion , 32, 0, "C++ for OpenCL version") ++LANGOPT(OpenCLPipe , 1, 0, "OpenCL pipe keyword") ++LANGOPT(OpenCLGenericAddressSpace, 1, 0, "OpenCL generic keyword") + LANGOPT(NativeHalfType , 1, 0, "Native half type support") + LANGOPT(NativeHalfArgsAndReturns, 1, 0, "Native half args and returns") + LANGOPT(HalfArgsAndReturns, 1, 0, "half args and returns") +diff --git a/clang/include/clang/Basic/OpenCLExtensions.def b/clang/include/clang/Basic/OpenCLExtensions.def +index 801916c3ab94..c5352dadc0de 100644 +--- a/clang/include/clang/Basic/OpenCLExtensions.def ++++ b/clang/include/clang/Basic/OpenCLExtensions.def +@@ -16,8 +16,12 @@ + // If extensions are to be enumerated with information about whether + // an extension is core or optional core and minimum OpenCL version + // when an extension becomes available, +-// define OPENCL_GENERIC_EXTENSION(ext, avail, core, opt) where ++// define OPENCL_GENERIC_EXTENSION(ext, pragma, avail, core, opt) where + // ext - name of the extension or optional core feature. ++// pragma - true if extension needs pragmas or false otherwise. ++// NOTE: extension pragma without any documentation detailing ++// its behavior explicitly is deprecated. Therefore the default ++// value is false. + // avail - minimum OpenCL version supporting it. + // core - OpenCL versions mask when the extension becomes core feature. + // 0U indicates not a core feature. +@@ -50,55 +54,67 @@ + #endif // OPENCL_GENERIC_EXTENSION + + // Declaration helpers +-#define OPENCL_EXTENSION(ext, avail) OPENCL_GENERIC_EXTENSION(ext, avail, 0U, 0U) +-#define OPENCL_COREFEATURE(ext, avail, core) OPENCL_GENERIC_EXTENSION(ext, avail, core, 0U) +-#define OPENCL_OPTIONALCOREFEATURE(ext, avail, opt) OPENCL_GENERIC_EXTENSION(ext, avail, 0U, opt) ++#define OPENCL_EXTENSION(ext, pragma, avail) OPENCL_GENERIC_EXTENSION(ext, pragma, avail, 0U, 0U) ++#define OPENCL_COREFEATURE(ext, pragma, avail, core) OPENCL_GENERIC_EXTENSION(ext, pragma, avail, core, 0U) ++#define OPENCL_OPTIONALCOREFEATURE(ext, pragma, avail, opt) OPENCL_GENERIC_EXTENSION(ext, pragma, avail, 0U, opt) + + // OpenCL 1.0. +-OPENCL_COREFEATURE(cl_khr_byte_addressable_store, 100, OCL_C_11P) +-OPENCL_COREFEATURE(cl_khr_global_int32_base_atomics, 100, OCL_C_11P) +-OPENCL_COREFEATURE(cl_khr_global_int32_extended_atomics, 100, OCL_C_11P) +-OPENCL_COREFEATURE(cl_khr_local_int32_base_atomics, 100, OCL_C_11P) +-OPENCL_COREFEATURE(cl_khr_local_int32_extended_atomics, 100, OCL_C_11P) +-OPENCL_OPTIONALCOREFEATURE(cl_khr_fp64, 100, OCL_C_12P) +-OPENCL_EXTENSION(cl_khr_fp16, 100) +-OPENCL_EXTENSION(cl_khr_int64_base_atomics, 100) +-OPENCL_EXTENSION(cl_khr_int64_extended_atomics, 100) +-OPENCL_GENERIC_EXTENSION(cl_khr_3d_image_writes, 100, OCL_C_20, OCL_C_30) ++OPENCL_COREFEATURE(cl_khr_byte_addressable_store, true, 100, OCL_C_11P) ++OPENCL_COREFEATURE(cl_khr_global_int32_base_atomics, true, 100, OCL_C_11P) ++OPENCL_COREFEATURE(cl_khr_global_int32_extended_atomics, true, 100, OCL_C_11P) ++OPENCL_COREFEATURE(cl_khr_local_int32_base_atomics, true, 100, OCL_C_11P) ++OPENCL_COREFEATURE(cl_khr_local_int32_extended_atomics, true, 100, OCL_C_11P) ++OPENCL_OPTIONALCOREFEATURE(cl_khr_fp64, true, 100, OCL_C_12P) ++OPENCL_EXTENSION(cl_khr_fp16, true, 100) ++OPENCL_EXTENSION(cl_khr_int64_base_atomics, true, 100) ++OPENCL_EXTENSION(cl_khr_int64_extended_atomics, true, 100) ++OPENCL_COREFEATURE(cl_khr_3d_image_writes, true, 100, OCL_C_20) + + // EMBEDDED_PROFILE +-OPENCL_EXTENSION(cles_khr_int64, 110) ++OPENCL_EXTENSION(cles_khr_int64, true, 110) + + // OpenCL 1.2. +-OPENCL_EXTENSION(cl_khr_depth_images, 120) +-OPENCL_EXTENSION(cl_khr_gl_msaa_sharing, 120) ++OPENCL_EXTENSION(cl_khr_depth_images, true, 120) ++OPENCL_EXTENSION(cl_khr_gl_msaa_sharing,true, 120) + + // OpenCL 2.0. +-OPENCL_EXTENSION(cl_khr_mipmap_image, 200) +-OPENCL_EXTENSION(cl_khr_mipmap_image_writes, 200) +-OPENCL_EXTENSION(cl_khr_srgb_image_writes, 200) +-OPENCL_EXTENSION(cl_khr_subgroups, 200) ++OPENCL_EXTENSION(cl_khr_mipmap_image, true, 200) ++OPENCL_EXTENSION(cl_khr_mipmap_image_writes, true, 200) ++OPENCL_EXTENSION(cl_khr_srgb_image_writes, true, 200) ++OPENCL_EXTENSION(cl_khr_subgroups, true, 200) + + // Clang Extensions. +-OPENCL_EXTENSION(cl_clang_storage_class_specifiers, 100) +-OPENCL_EXTENSION(__cl_clang_function_pointers, 100) +-OPENCL_EXTENSION(__cl_clang_variadic_functions, 100) ++OPENCL_EXTENSION(cl_clang_storage_class_specifiers, true, 100) ++OPENCL_EXTENSION(__cl_clang_function_pointers, true, 100) ++OPENCL_EXTENSION(__cl_clang_variadic_functions, true, 100) + + // AMD OpenCL extensions +-OPENCL_EXTENSION(cl_amd_media_ops, 100) +-OPENCL_EXTENSION(cl_amd_media_ops2, 100) ++OPENCL_EXTENSION(cl_amd_media_ops, true, 100) ++OPENCL_EXTENSION(cl_amd_media_ops2, true, 100) + + // ARM OpenCL extensions +-OPENCL_EXTENSION(cl_arm_integer_dot_product_int8, 120) +-OPENCL_EXTENSION(cl_arm_integer_dot_product_accumulate_int8, 120) +-OPENCL_EXTENSION(cl_arm_integer_dot_product_accumulate_int16, 120) +-OPENCL_EXTENSION(cl_arm_integer_dot_product_accumulate_saturate_int8, 120) ++OPENCL_EXTENSION(cl_arm_integer_dot_product_int8, true, 120) ++OPENCL_EXTENSION(cl_arm_integer_dot_product_accumulate_int8, true, 120) ++OPENCL_EXTENSION(cl_arm_integer_dot_product_accumulate_int16, true, 120) ++OPENCL_EXTENSION(cl_arm_integer_dot_product_accumulate_saturate_int8, true, 120) + + // Intel OpenCL extensions +-OPENCL_EXTENSION(cl_intel_subgroups, 120) +-OPENCL_EXTENSION(cl_intel_subgroups_short, 120) +-OPENCL_EXTENSION(cl_intel_device_side_avc_motion_estimation, 120) ++OPENCL_EXTENSION(cl_intel_subgroups, true, 120) ++OPENCL_EXTENSION(cl_intel_subgroups_short, true, 120) ++OPENCL_EXTENSION(cl_intel_device_side_avc_motion_estimation, true, 120) + ++// OpenCL C 3.0 features (6.2.1. Features) ++OPENCL_OPTIONALCOREFEATURE(__opencl_c_pipes, false, 300, OCL_C_30) ++OPENCL_OPTIONALCOREFEATURE(__opencl_c_generic_address_space, false, 300, OCL_C_30) ++OPENCL_OPTIONALCOREFEATURE(__opencl_c_atomic_order_acq_rel, false, 300, OCL_C_30) ++OPENCL_OPTIONALCOREFEATURE(__opencl_c_atomic_order_seq_cst, false, 300, OCL_C_30) ++OPENCL_OPTIONALCOREFEATURE(__opencl_c_subgroups, false, 300, OCL_C_30) ++OPENCL_OPTIONALCOREFEATURE(__opencl_c_3d_image_writes, false, 300, OCL_C_30) ++OPENCL_OPTIONALCOREFEATURE(__opencl_c_device_enqueue, false, 300, OCL_C_30) ++OPENCL_OPTIONALCOREFEATURE(__opencl_c_read_write_images, false, 300, OCL_C_30) ++OPENCL_OPTIONALCOREFEATURE(__opencl_c_program_scope_global_variables, false, 300, OCL_C_30) ++OPENCL_OPTIONALCOREFEATURE(__opencl_c_fp64, false, 300, OCL_C_30) ++OPENCL_OPTIONALCOREFEATURE(__opencl_c_images, false, 300, OCL_C_30) + + #undef OPENCL_OPTIONALCOREFEATURE + #undef OPENCL_COREFEATURE +diff --git a/clang/include/clang/Basic/OpenCLOptions.h b/clang/include/clang/Basic/OpenCLOptions.h +index fe27ef19d4d5..4779ad4d6507 100644 +--- a/clang/include/clang/Basic/OpenCLOptions.h ++++ b/clang/include/clang/Basic/OpenCLOptions.h +@@ -19,6 +19,9 @@ + + namespace clang { + ++class DiagnosticsEngine; ++class TargetInfo; ++ + namespace { + // This enum maps OpenCL version(s) into value. These values are used as + // a mask to indicate in which OpenCL version(s) extension is a core or +@@ -64,15 +67,33 @@ static inline bool isOpenCLVersionIsContainedInMask(const LangOptions &LO, + /// OpenCL supported extensions and optional core features + class OpenCLOptions { + public: ++ // OpenCL C v1.2 s6.5 - All program scope variables must be declared in the ++ // __constant address space. ++ // OpenCL C v2.0 s6.5.1 - Variables defined at program scope and static ++ // variables inside a function can also be declared in the global ++ // address space. ++ // OpenCL C v3.0 s6.7.1 - Variables at program scope or static or extern ++ // variables inside functions can be declared in global address space if ++ // the __opencl_c_program_scope_global_variables feature is supported ++ // C++ for OpenCL inherits rule from OpenCL C v2.0. ++ bool areProgramScopeVariablesSupported(const LangOptions &Opts) const { ++ return Opts.OpenCLCPlusPlus || Opts.OpenCLVersion == 200 || ++ (Opts.OpenCLVersion == 300 && ++ isSupported("__opencl_c_program_scope_global_variables", Opts)); ++ } ++ + struct OpenCLOptionInfo { ++ // Does this option have pragma. ++ bool WithPragma = false; ++ + // Option starts to be available in this OpenCL version +- unsigned Avail; ++ unsigned Avail = 100U; + + // Option becomes core feature in this OpenCL versions +- unsigned Core; ++ unsigned Core = 0U; + + // Option becomes optional core feature in this OpenCL versions +- unsigned Opt; ++ unsigned Opt = 0U; + + // Is this option supported + bool Supported = false; +@@ -80,8 +101,10 @@ public: + // Is this option enabled + bool Enabled = false; + +- OpenCLOptionInfo(unsigned A = 100, unsigned C = 0U, unsigned O = 0U) +- : Avail(A), Core(C), Opt(O) {} ++ OpenCLOptionInfo() = default; ++ OpenCLOptionInfo(bool Pragma, unsigned AvailV, unsigned CoreV, ++ unsigned OptV) ++ : WithPragma(Pragma), Avail(AvailV), Core(CoreV), Opt(OptV) {} + + bool isCore() const { return Core != 0U; } + +@@ -107,7 +130,12 @@ public: + + bool isKnown(llvm::StringRef Ext) const; + +- bool isEnabled(llvm::StringRef Ext) const; ++ // For core or optional core feature check that it is supported ++ // by a target, for any other option (extension) check that it is ++ // enabled via pragma ++ bool isAvailableOption(llvm::StringRef Ext, const LangOptions &LO) const; ++ ++ bool isWithPragma(llvm::StringRef Ext) const; + + // Is supported as either an extension or an (optional) core feature for + // OpenCL version \p LO. +@@ -131,6 +159,11 @@ public: + // For supported core or optional core feature, return false. + bool isSupportedExtension(llvm::StringRef Ext, const LangOptions &LO) const; + ++ // FIXME: Whether extension should accept pragma should not ++ // be reset dynamically. But it currently required when ++ // registering new extensions via pragmas. ++ void acceptsPragma(llvm::StringRef Ext, bool V = true); ++ + void enable(llvm::StringRef Ext, bool V = true); + + /// Enable or disable support for OpenCL extensions +@@ -148,15 +181,35 @@ public: + // Disable all extensions + void disableAll(); + +- // Enable supported core and optional core features +- void enableSupportedCore(const LangOptions &LO); +- + friend class ASTWriter; + friend class ASTReader; + + using OpenCLOptionInfoMap = llvm::StringMap; + ++ template ++ static bool isOpenCLOptionCoreIn(const LangOptions &LO, Args &&... args) { ++ return OpenCLOptionInfo(std::forward(args)...).isCoreIn(LO); ++ } ++ ++ template ++ static bool isOpenCLOptionAvailableIn(const LangOptions &LO, ++ Args &&... args) { ++ return OpenCLOptionInfo(std::forward(args)...).isAvailableIn(LO); ++ } ++ ++ // Diagnose feature dependencies for OpenCL C 3.0. Return false if target ++ // doesn't follow these requirements. ++ static bool diagnoseUnsupportedFeatureDependencies(const TargetInfo &TI, ++ DiagnosticsEngine &Diags); ++ ++ // Diagnose that features and equivalent extension are set to same values. ++ // Return false if target doesn't follow these requirements. ++ static bool diagnoseFeatureExtensionDifferences(const TargetInfo &TI, ++ DiagnosticsEngine &Diags); ++ + private: ++ // Option is enabled via pragma ++ bool isEnabled(llvm::StringRef Ext) const; + OpenCLOptionInfoMap OptMap; + }; + +diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h +index b782172d93a3..ec51758a35d4 100644 +--- a/clang/include/clang/Basic/TargetInfo.h ++++ b/clang/include/clang/Basic/TargetInfo.h +@@ -1192,6 +1192,12 @@ public: + return false; + } + ++ /// Check if target has a given feature enabled ++ virtual bool hasFeatureEnabled(const llvm::StringMap &Features, ++ StringRef Name) const { ++ return Features.lookup(Name); ++ } ++ + /// Enable or disable a specific target feature; + /// the feature name must be valid. + virtual void setFeatureEnabled(llvm::StringMap &Features, +@@ -1439,7 +1445,8 @@ public: + virtual void setSupportedOpenCLOpts() {} + + virtual void supportAllOpenCLOpts(bool V = true) { +-#define OPENCLEXTNAME(Ext) getTargetOpts().OpenCLFeaturesMap[#Ext] = V; ++#define OPENCLEXTNAME(Ext) \ ++ setFeatureEnabled(getTargetOpts().OpenCLFeaturesMap, #Ext, V); + #include "clang/Basic/OpenCLExtensions.def" + } + +@@ -1459,10 +1466,6 @@ public: + } + } + +- /// Define OpenCL macros based on target settings and language version +- void getOpenCLFeatureDefines(const LangOptions &Opts, +- MacroBuilder &Builder) const; +- + /// Get supported OpenCL extensions and optional core features. + llvm::StringMap &getSupportedOpenCLOpts() { + return getTargetOpts().OpenCLFeaturesMap; +@@ -1502,6 +1505,11 @@ public: + return true; + } + ++ /// Check that OpenCL target has valid options setting based on OpenCL ++ /// version. ++ virtual bool validateOpenCLTarget(const LangOptions &Opts, ++ DiagnosticsEngine &Diags) const; ++ + virtual void setAuxTarget(const TargetInfo *Aux) {} + + /// Whether target allows debuginfo types for decl only variables. +diff --git a/clang/include/clang/Sema/Overload.h b/clang/include/clang/Sema/Overload.h +index 5be6a618711c..699c3e808872 100644 +--- a/clang/include/clang/Sema/Overload.h ++++ b/clang/include/clang/Sema/Overload.h +@@ -760,9 +760,6 @@ class Sema; + /// This candidate was not viable because its address could not be taken. + ovl_fail_addr_not_available, + +- /// This candidate was not viable because its OpenCL extension is disabled. +- ovl_fail_ext_disabled, +- + /// This inherited constructor is not viable because it would slice the + /// argument. + ovl_fail_inhctor_slice, +diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h +index 2530a2776373..7e7348d6de2a 100644 +--- a/clang/include/clang/Sema/Sema.h ++++ b/clang/include/clang/Sema/Sema.h +@@ -10106,73 +10106,6 @@ public: + /// potentially-throwing. + bool checkFinalSuspendNoThrow(const Stmt *FinalSuspend); + +- //===--------------------------------------------------------------------===// +- // OpenCL extensions. +- // +-private: +- std::string CurrOpenCLExtension; +- /// Extensions required by an OpenCL type. +- llvm::DenseMap> OpenCLTypeExtMap; +- /// Extensions required by an OpenCL declaration. +- llvm::DenseMap> OpenCLDeclExtMap; +-public: +- llvm::StringRef getCurrentOpenCLExtension() const { +- return CurrOpenCLExtension; +- } +- +- /// Check if a function declaration \p FD associates with any +- /// extensions present in OpenCLDeclExtMap and if so return the +- /// extension(s) name(s). +- std::string getOpenCLExtensionsFromDeclExtMap(FunctionDecl *FD); +- +- /// Check if a function type \p FT associates with any +- /// extensions present in OpenCLTypeExtMap and if so return the +- /// extension(s) name(s). +- std::string getOpenCLExtensionsFromTypeExtMap(FunctionType *FT); +- +- /// Find an extension in an appropriate extension map and return its name +- template +- std::string getOpenCLExtensionsFromExtMap(T* FT, MapT &Map); +- +- void setCurrentOpenCLExtension(llvm::StringRef Ext) { +- CurrOpenCLExtension = std::string(Ext); +- } +- +- /// Set OpenCL extensions for a type which can only be used when these +- /// OpenCL extensions are enabled. If \p Exts is empty, do nothing. +- /// \param Exts A space separated list of OpenCL extensions. +- void setOpenCLExtensionForType(QualType T, llvm::StringRef Exts); +- +- /// Set OpenCL extensions for a declaration which can only be +- /// used when these OpenCL extensions are enabled. If \p Exts is empty, do +- /// nothing. +- /// \param Exts A space separated list of OpenCL extensions. +- void setOpenCLExtensionForDecl(Decl *FD, llvm::StringRef Exts); +- +- /// Set current OpenCL extensions for a type which can only be used +- /// when these OpenCL extensions are enabled. If current OpenCL extension is +- /// empty, do nothing. +- void setCurrentOpenCLExtensionForType(QualType T); +- +- /// Set current OpenCL extensions for a declaration which +- /// can only be used when these OpenCL extensions are enabled. If current +- /// OpenCL extension is empty, do nothing. +- void setCurrentOpenCLExtensionForDecl(Decl *FD); +- +- bool isOpenCLDisabledDecl(Decl *FD); +- +- /// Check if type \p T corresponding to declaration specifier \p DS +- /// is disabled due to required OpenCL extensions being disabled. If so, +- /// emit diagnostics. +- /// \return true if type is disabled. +- bool checkOpenCLDisabledTypeDeclSpec(const DeclSpec &DS, QualType T); +- +- /// Check if declaration \p D used by expression \p E +- /// is disabled due to required OpenCL extensions being disabled. If so, +- /// emit diagnostics. +- /// \return true if type is disabled. +- bool checkOpenCLDisabledDecl(const NamedDecl &D, const Expr &E); +- + //===--------------------------------------------------------------------===// + // OpenMP directives and clauses. + // +@@ -10203,21 +10136,6 @@ private: + /// Pop OpenMP function region for non-capturing function. + void popOpenMPFunctionRegion(const sema::FunctionScopeInfo *OldFSI); + +- /// Checks if a type or a declaration is disabled due to the owning extension +- /// being disabled, and emits diagnostic messages if it is disabled. +- /// \param D type or declaration to be checked. +- /// \param DiagLoc source location for the diagnostic message. +- /// \param DiagInfo information to be emitted for the diagnostic message. +- /// \param SrcRange source range of the declaration. +- /// \param Map maps type or declaration to the extensions. +- /// \param Selector selects diagnostic message: 0 for type and 1 for +- /// declaration. +- /// \return true if the type or declaration is disabled. +- template +- bool checkOpenCLDisabledTypeOrDecl(T D, DiagLocT DiagLoc, DiagInfoT DiagInfo, +- MapT &Map, unsigned Selector = 0, +- SourceRange SrcRange = SourceRange()); +- + /// Helper to keep information about the current `omp begin/end declare + /// variant` nesting. + struct OMPDeclareVariantScope { +diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h +index 12073a38a77a..176badf7a0d1 100644 +--- a/clang/include/clang/Serialization/ASTWriter.h ++++ b/clang/include/clang/Serialization/ASTWriter.h +@@ -510,8 +510,6 @@ private: + void WriteDeclContextVisibleUpdate(const DeclContext *DC); + void WriteFPPragmaOptions(const FPOptionsOverride &Opts); + void WriteOpenCLExtensions(Sema &SemaRef); +- void WriteOpenCLExtensionTypes(Sema &SemaRef); +- void WriteOpenCLExtensionDecls(Sema &SemaRef); + void WriteCUDAPragmas(Sema &SemaRef); + void WriteObjCCategories(); + void WriteLateParsedTemplates(Sema &SemaRef); +diff --git a/clang/lib/Basic/OpenCLOptions.cpp b/clang/lib/Basic/OpenCLOptions.cpp +index 266acc5fe477..d7729ffb09ce 100644 +--- a/clang/lib/Basic/OpenCLOptions.cpp ++++ b/clang/lib/Basic/OpenCLOptions.cpp +@@ -7,6 +7,8 @@ + //===----------------------------------------------------------------------===// + + #include "clang/Basic/OpenCLOptions.h" ++#include "clang/Basic/Diagnostic.h" ++#include "clang/Basic/TargetInfo.h" + + namespace clang { + +@@ -14,9 +16,26 @@ bool OpenCLOptions::isKnown(llvm::StringRef Ext) const { + return OptMap.find(Ext) != OptMap.end(); + } + ++bool OpenCLOptions::isAvailableOption(llvm::StringRef Ext, ++ const LangOptions &LO) const { ++ if (!isKnown(Ext)) ++ return false; ++ ++ auto &OptInfo = OptMap.find(Ext)->getValue(); ++ if (OptInfo.isCoreIn(LO) || OptInfo.isOptionalCoreIn(LO)) ++ return isSupported(Ext, LO); ++ ++ return isEnabled(Ext); ++} ++ + bool OpenCLOptions::isEnabled(llvm::StringRef Ext) const { ++ auto I = OptMap.find(Ext); ++ return I != OptMap.end() && I->getValue().Enabled; ++} ++ ++bool OpenCLOptions::isWithPragma(llvm::StringRef Ext) const { + auto E = OptMap.find(Ext); +- return E != OptMap.end() && E->second.Enabled; ++ return E != OptMap.end() && E->second.WithPragma; + } + + bool OpenCLOptions::isSupported(llvm::StringRef Ext, +@@ -31,22 +50,16 @@ bool OpenCLOptions::isSupported(llvm::StringRef Ext, + + bool OpenCLOptions::isSupportedCore(llvm::StringRef Ext, + const LangOptions &LO) const { +- auto E = OptMap.find(Ext); +- if (E == OptMap.end()) { +- return false; +- } +- auto I = OptMap.find(Ext)->getValue(); +- return I.Supported && I.isCoreIn(LO); ++ auto I = OptMap.find(Ext); ++ return I != OptMap.end() && I->getValue().Supported && ++ I->getValue().isCoreIn(LO); + } + + bool OpenCLOptions::isSupportedOptionalCore(llvm::StringRef Ext, + const LangOptions &LO) const { +- auto E = OptMap.find(Ext); +- if (E == OptMap.end()) { +- return false; +- } +- auto I = OptMap.find(Ext)->getValue(); +- return I.Supported && I.isOptionalCoreIn(LO); ++ auto I = OptMap.find(Ext); ++ return I != OptMap.end() && I->getValue().Supported && ++ I->getValue().isOptionalCoreIn(LO); + } + + bool OpenCLOptions::isSupportedCoreOrOptionalCore(llvm::StringRef Ext, +@@ -56,12 +69,9 @@ bool OpenCLOptions::isSupportedCoreOrOptionalCore(llvm::StringRef Ext, + + bool OpenCLOptions::isSupportedExtension(llvm::StringRef Ext, + const LangOptions &LO) const { +- auto E = OptMap.find(Ext); +- if (E == OptMap.end()) { +- return false; +- } +- auto I = OptMap.find(Ext)->getValue(); +- return I.Supported && I.isAvailableIn(LO) && ++ auto I = OptMap.find(Ext); ++ return I != OptMap.end() && I->getValue().Supported && ++ I->getValue().isAvailableIn(LO) && + !isSupportedCoreOrOptionalCore(Ext, LO); + } + +@@ -69,6 +79,10 @@ void OpenCLOptions::enable(llvm::StringRef Ext, bool V) { + OptMap[Ext].Enabled = V; + } + ++void OpenCLOptions::acceptsPragma(llvm::StringRef Ext, bool V) { ++ OptMap[Ext].WithPragma = V; ++} ++ + void OpenCLOptions::support(llvm::StringRef Ext, bool V) { + assert(!Ext.empty() && "Extension is empty."); + assert(Ext[0] != '+' && Ext[0] != '-'); +@@ -76,11 +90,9 @@ void OpenCLOptions::support(llvm::StringRef Ext, bool V) { + } + + OpenCLOptions::OpenCLOptions() { +-#define OPENCL_GENERIC_EXTENSION(Ext, AvailVer, CoreVer, OptVer) \ +- OptMap[#Ext].Avail = AvailVer; \ +- OptMap[#Ext].Core = CoreVer; \ +- OptMap[#Ext].Opt = OptVer; +-#include "clang/Basic/OpenCLExtensions.def" ++#define OPENCL_GENERIC_EXTENSION(Ext, ...) \ ++ OptMap.insert_or_assign(#Ext, OpenCLOptionInfo{__VA_ARGS__}); ++ #include "clang/Basic/OpenCLExtensions.def" + } + + void OpenCLOptions::addSupport(const llvm::StringMap &FeaturesMap, +@@ -97,10 +109,45 @@ void OpenCLOptions::disableAll() { + Opt.getValue().Enabled = false; + } + +-void OpenCLOptions::enableSupportedCore(const LangOptions &LO) { +- for (auto &Opt : OptMap) +- if (isSupportedCoreOrOptionalCore(Opt.getKey(), LO)) +- Opt.getValue().Enabled = true; ++bool OpenCLOptions::diagnoseUnsupportedFeatureDependencies( ++ const TargetInfo &TI, DiagnosticsEngine &Diags) { ++ // Feature pairs. First feature in a pair requires the second one to be ++ // supported. ++ static const llvm::StringMap DependentFeaturesMap = { ++ {"__opencl_c_read_write_images", "__opencl_c_images"}, ++ {"__opencl_c_3d_image_writes", "__opencl_c_images"}}; ++ ++ auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts(); ++ ++ bool IsValid = true; ++ for (auto &FeaturePair : DependentFeaturesMap) ++ if (TI.hasFeatureEnabled(OpenCLFeaturesMap, FeaturePair.getKey()) && ++ !TI.hasFeatureEnabled(OpenCLFeaturesMap, FeaturePair.getValue())) { ++ IsValid = false; ++ Diags.Report(diag::err_opencl_feature_requires) ++ << FeaturePair.getKey() << FeaturePair.getValue(); ++ } ++ return IsValid; ++} ++ ++bool OpenCLOptions::diagnoseFeatureExtensionDifferences( ++ const TargetInfo &TI, DiagnosticsEngine &Diags) { ++ // Extensions and equivalent feature pairs. ++ static const llvm::StringMap FeatureExtensionMap = { ++ {"cl_khr_fp64", "__opencl_c_fp64"}, ++ {"cl_khr_3d_image_writes", "__opencl_c_3d_image_writes"}}; ++ ++ auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts(); ++ ++ bool IsValid = true; ++ for (auto &ExtAndFeat : FeatureExtensionMap) ++ if (TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.getKey()) != ++ TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.getValue())) { ++ IsValid = false; ++ Diags.Report(diag::err_opencl_extension_and_feature_differs) ++ << ExtAndFeat.getKey() << ExtAndFeat.getValue(); ++ } ++ return IsValid; + } + + } // end namespace clang +diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp +index 642ee753d224..61cfd59ccf28 100644 +--- a/clang/lib/Basic/TargetInfo.cpp ++++ b/clang/lib/Basic/TargetInfo.cpp +@@ -366,6 +366,19 @@ void TargetInfo::adjust(LangOptions &Opts) { + HalfWidth = HalfAlign = 16; + FloatWidth = FloatAlign = 32; + ++ // OpenCL C v3.0 s6.7.5 - The generic address space requires support for ++ // OpenCL C 2.0 or OpenCL C 3.0 with the __opencl_c_generic_address_space ++ // feature ++ // FIXME: OpenCLGenericAddressSpace is also defined in setLangDefaults() ++ // for OpenCL C 2.0 but with no access to target capabilities. Target ++ // should be immutable once created and thus this language option needs ++ // to be defined only once. ++ if (Opts.OpenCLVersion >= 300) { ++ const auto &OpenCLFeaturesMap = getSupportedOpenCLOpts(); ++ Opts.OpenCLGenericAddressSpace = hasFeatureEnabled( ++ OpenCLFeaturesMap, "__opencl_c_generic_address_space"); ++ } ++ + // Embedded 32-bit targets (OpenCL EP) might have double C type + // defined as float. Let's not override this as it might lead + // to generating illegal code that uses 64bit doubles. +@@ -388,6 +401,19 @@ void TargetInfo::adjust(LangOptions &Opts) { + HalfFormat = &llvm::APFloat::IEEEhalf(); + FloatFormat = &llvm::APFloat::IEEEsingle(); + LongDoubleFormat = &llvm::APFloat::IEEEquad(); ++ ++ // OpenCL C v3.0 s6.7.5 - The generic address space requires support for ++ // OpenCL C 2.0 or OpenCL C 3.0 with the __opencl_c_generic_address_space ++ // feature ++ // FIXME: OpenCLGenericAddressSpace is also defined in setLangDefaults() ++ // for OpenCL C 2.0 but with no access to target capabilities. Target ++ // should be immutable once created and thus this language option needs ++ // to be defined only once. ++ if (Opts.OpenCLVersion >= 300) { ++ const auto &OpenCLFeaturesMap = getSupportedOpenCLOpts(); ++ Opts.OpenCLGenericAddressSpace = hasFeatureEnabled( ++ OpenCLFeaturesMap, "__opencl_c_generic_address_space"); ++ } + } + + if (Opts.DoubleSize) { +diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp +index 90a67d03b7b2..c171d2ed7c95 100644 +--- a/clang/lib/Basic/Targets.cpp ++++ b/clang/lib/Basic/Targets.cpp +@@ -715,29 +715,28 @@ TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, + + return Target.release(); + } +- +-/// getOpenCLFeatureDefines - Define OpenCL macros based on target settings +-/// and language version +-void TargetInfo::getOpenCLFeatureDefines(const LangOptions &Opts, +- MacroBuilder &Builder) const { +- +- auto defineOpenCLExtMacro = [&](llvm::StringRef Name, unsigned AvailVer, +- unsigned CoreVersions, +- unsigned OptionalVersions) { +- // Check if extension is supported by target and is available in this +- // OpenCL version +- auto It = getTargetOpts().OpenCLFeaturesMap.find(Name); +- if ((It != getTargetOpts().OpenCLFeaturesMap.end()) && It->getValue() && +- OpenCLOptions::OpenCLOptionInfo(AvailVer, CoreVersions, +- OptionalVersions) +- .isAvailableIn(Opts)) +- Builder.defineMacro(Name); ++/// validateOpenCLTarget - Check that OpenCL target has valid ++/// options setting based on OpenCL version. ++bool TargetInfo::validateOpenCLTarget(const LangOptions &Opts, ++ DiagnosticsEngine &Diags) const { ++ const llvm::StringMap &OpenCLFeaturesMap = getSupportedOpenCLOpts(); ++ ++ auto diagnoseNotSupportedCore = [&](llvm::StringRef Name, auto... OptArgs) { ++ if (OpenCLOptions::isOpenCLOptionCoreIn(Opts, OptArgs...) && ++ !hasFeatureEnabled(OpenCLFeaturesMap, Name)) ++ Diags.Report(diag::warn_opencl_unsupported_core_feature) ++ << Name << Opts.OpenCLCPlusPlus ++ << Opts.getOpenCLVersionTuple().getAsString(); + }; +-#define OPENCL_GENERIC_EXTENSION(Ext, Avail, Core, Opt) \ +- defineOpenCLExtMacro(#Ext, Avail, Core, Opt); ++#define OPENCL_GENERIC_EXTENSION(Ext, ...) \ ++ diagnoseNotSupportedCore(#Ext, __VA_ARGS__); + #include "clang/Basic/OpenCLExtensions.def" + +- // FIXME: OpenCL options which affect language semantics/syntax +- // should be moved into LangOptions, thus macro definitions of +- // such options is better to be done in clang::InitializePreprocessor ++ // Validate that feature macros are set properly for OpenCL C 3.0. ++ // In other cases assume that target is always valid. ++ if (Opts.OpenCLCPlusPlus || Opts.OpenCLVersion < 300) ++ return true; ++ ++ return OpenCLOptions::diagnoseUnsupportedFeatureDependencies(*this, Diags) && ++ OpenCLOptions::diagnoseFeatureExtensionDifferences(*this, Diags); + } +diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h +index 8ee0ca30d305..b11fe212c3a2 100644 +--- a/clang/lib/Basic/Targets/AMDGPU.h ++++ b/clang/lib/Basic/Targets/AMDGPU.h +@@ -291,6 +291,7 @@ public: + bool IsAMDGCN = isAMDGCN(getTriple()); + + Opts["cl_khr_fp64"] = hasFP64(); ++ Opts["__opencl_c_fp64"] = hasFP64(); + + if (IsAMDGCN || GPUKind >= llvm::AMDGPU::GK_CEDAR) { + Opts["cl_khr_byte_addressable_store"] = true; +@@ -307,9 +308,12 @@ public: + Opts["cl_khr_mipmap_image"] = true; + Opts["cl_khr_mipmap_image_writes"] = true; + Opts["cl_khr_subgroups"] = true; +- Opts["cl_khr_3d_image_writes"] = true; + Opts["cl_amd_media_ops"] = true; + Opts["cl_amd_media_ops2"] = true; ++ ++ Opts["__opencl_c_images"] = true; ++ Opts["__opencl_c_3d_image_writes"] = true; ++ Opts["cl_khr_3d_image_writes"] = true; + } + } + +diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h +index 038dec4a28bd..010e640804bf 100644 +--- a/clang/lib/Basic/Targets/NVPTX.h ++++ b/clang/lib/Basic/Targets/NVPTX.h +@@ -132,6 +132,7 @@ public: + Opts["__cl_clang_variadic_functions"] = true; + + Opts["cl_khr_fp64"] = true; ++ Opts["__opencl_c_fp64"] = true; + Opts["cl_khr_byte_addressable_store"] = true; + Opts["cl_khr_global_int32_base_atomics"] = true; + Opts["cl_khr_global_int32_extended_atomics"] = true; +diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp +index c5ad1c7d2c2e..701b03c868d1 100644 +--- a/clang/lib/Basic/Targets/X86.cpp ++++ b/clang/lib/Basic/Targets/X86.cpp +@@ -1397,13 +1397,13 @@ bool X86TargetInfo::validateOperandSize(const llvm::StringMap &FeatureMap, + return Size <= 64; + case 'z': + // XMM0/YMM/ZMM0 +- if (FeatureMap.lookup("avx512f")) ++ if (hasFeatureEnabled(FeatureMap, "avx512f")) + // ZMM0 can be used if target supports AVX512F. + return Size <= 512U; +- else if (FeatureMap.lookup("avx")) ++ else if (hasFeatureEnabled(FeatureMap, "avx")) + // YMM0 can be used if target supports AVX. + return Size <= 256U; +- else if (FeatureMap.lookup("sse")) ++ else if (hasFeatureEnabled(FeatureMap, "sse")) + return Size <= 128U; + return false; + case 'i': +@@ -1417,10 +1417,10 @@ bool X86TargetInfo::validateOperandSize(const llvm::StringMap &FeatureMap, + break; + case 'v': + case 'x': +- if (FeatureMap.lookup("avx512f")) ++ if (hasFeatureEnabled(FeatureMap, "avx512f")) + // 512-bit zmm registers can be used if target supports AVX512F. + return Size <= 512U; +- else if (FeatureMap.lookup("avx")) ++ else if (hasFeatureEnabled(FeatureMap, "avx")) + // 256-bit ymm registers can be used if target supports AVX. + return Size <= 256U; + return Size <= 128U; +diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp +index 956877d34680..3e5c07538662 100644 +--- a/clang/lib/Frontend/CompilerInstance.cpp ++++ b/clang/lib/Frontend/CompilerInstance.cpp +@@ -910,6 +910,11 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) { + } + // FIXME: can we disable FEnvAccess? + } ++ // We should do it here because target knows nothing about ++ // language options when it's being created. ++ if (getLangOpts().OpenCL && ++ !getTarget().validateOpenCLTarget(getLangOpts(), getDiagnostics())) ++ return false; + + // Inform the target of the language options. + // +diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp +index 5c5cf46150e2..e1580b60dd89 100644 +--- a/clang/lib/Frontend/CompilerInvocation.cpp ++++ b/clang/lib/Frontend/CompilerInvocation.cpp +@@ -2041,6 +2041,9 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, + Opts.ZVector = 0; + Opts.setDefaultFPContractMode(LangOptions::FPM_On); + Opts.OpenCLCPlusPlus = Opts.CPlusPlus; ++ Opts.OpenCLPipe = Opts.OpenCLCPlusPlus || Opts.OpenCLVersion == 200; ++ Opts.OpenCLGenericAddressSpace = ++ Opts.OpenCLCPlusPlus || Opts.OpenCLVersion == 200; + + // Include default header file for OpenCL. + if (Opts.IncludeDefaultHeader) { +diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp +index c60972c96e5d..faa02c608540 100644 +--- a/clang/lib/Frontend/InitPreprocessor.cpp ++++ b/clang/lib/Frontend/InitPreprocessor.cpp +@@ -598,6 +598,29 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, + Builder.defineMacro("__cpp_coroutines", "201703L"); + } + ++/// InitializeOpenCLFeatureTestMacros - Define OpenCL macros based on target ++/// settings and language version ++void InitializeOpenCLFeatureTestMacros(const TargetInfo &TI, ++ const LangOptions &Opts, ++ MacroBuilder &Builder) { ++ const llvm::StringMap &OpenCLFeaturesMap = TI.getSupportedOpenCLOpts(); ++ // FIXME: OpenCL options which affect language semantics/syntax ++ // should be moved into LangOptions. ++ auto defineOpenCLExtMacro = [&](llvm::StringRef Name, auto... OptArgs) { ++ // Check if extension is supported by target and is available in this ++ // OpenCL version ++ if (TI.hasFeatureEnabled(OpenCLFeaturesMap, Name) && ++ OpenCLOptions::isOpenCLOptionAvailableIn(Opts, OptArgs...)) ++ Builder.defineMacro(Name); ++ }; ++#define OPENCL_GENERIC_EXTENSION(Ext, ...) \ ++ defineOpenCLExtMacro(#Ext, __VA_ARGS__); ++#include "clang/Basic/OpenCLExtensions.def" ++ ++ // Assume compiling for FULL profile ++ Builder.defineMacro("__opencl_c_int64"); ++} ++ + static void InitializePredefinedMacros(const TargetInfo &TI, + const LangOptions &LangOpts, + const FrontendOptions &FEOpts, +@@ -1120,7 +1143,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI, + + // OpenCL definitions. + if (LangOpts.OpenCL) { +- TI.getOpenCLFeatureDefines(LangOpts, Builder); ++ InitializeOpenCLFeatureTestMacros(TI, LangOpts, Builder); + } + + if (TI.hasInt128Type() && LangOpts.CPlusPlus && LangOpts.GNUMode) { +diff --git a/clang/lib/Headers/opencl-c-base.h b/clang/lib/Headers/opencl-c-base.h +index b55d9601a452..e8f293a0301b 100644 +--- a/clang/lib/Headers/opencl-c-base.h ++++ b/clang/lib/Headers/opencl-c-base.h +@@ -46,6 +46,21 @@ + #endif // defined(__SPIR__) + #endif // (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200) + ++// Define feature macros for OpenCL C 2.0 ++#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ == 200) ++#define __opencl_c_pipes 1 ++#define __opencl_c_generic_address_space 1 ++#define __opencl_c_work_group_collective_functions 1 ++#define __opencl_c_atomic_order_acq_rel 1 ++#define __opencl_c_atomic_order_seq_cst 1 ++#define __opencl_c_atomic_scope_device 1 ++#define __opencl_c_atomic_scope_all_devices 1 ++#define __opencl_c_device_enqueue 1 ++#define __opencl_c_read_write_images 1 ++#define __opencl_c_program_scope_global_variables 1 ++#define __opencl_c_images 1 ++#endif ++ + // built-in scalar data types: + + /** +diff --git a/clang/lib/Headers/opencl-c.h b/clang/lib/Headers/opencl-c.h +index 80d318b16f57..62ff0aab1d40 100644 +--- a/clang/lib/Headers/opencl-c.h ++++ b/clang/lib/Headers/opencl-c.h +@@ -11,11 +11,11 @@ + + #include "opencl-c-base.h" + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_images) + #ifndef cl_khr_depth_images + #define cl_khr_depth_images + #endif //cl_khr_depth_images +-#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#endif //defined(__opencl_c_images) + + #if __OPENCL_C_VERSION__ < CL_VERSION_2_0 + #ifdef cl_khr_3d_image_writes +@@ -7354,7 +7354,7 @@ half16 __ovld __cnfn fmod(half16 x, half16 y); + * Returns fmin(x - floor (x), 0x1.fffffep-1f ). + * floor(x) is returned in iptr. + */ +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_generic_address_space) + float __ovld fract(float x, float *iptr); + float2 __ovld fract(float2 x, float2 *iptr); + float3 __ovld fract(float3 x, float3 *iptr); +@@ -7444,7 +7444,7 @@ half16 __ovld fract(half16 x, __private half16 *iptr); + * magnitude in the interval [1/2, 1) or 0. Each + * component of x equals mantissa returned * 2^exp. + */ +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_generic_address_space) + float __ovld frexp(float x, int *exp); + float2 __ovld frexp(float2 x, int2 *exp); + float3 __ovld frexp(float3 x, int3 *exp); +@@ -7651,7 +7651,7 @@ half8 __ovld __cnfn lgamma(half8 x); + half16 __ovld __cnfn lgamma(half16 x); + #endif //cl_khr_fp16 + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_generic_address_space) + float __ovld lgamma_r(float x, int *signp); + float2 __ovld lgamma_r(float2 x, int2 *signp); + float3 __ovld lgamma_r(float3 x, int3 *signp); +@@ -7957,7 +7957,7 @@ half16 __ovld __cnfn minmag(half16 x, half16 y); + * the argument. It stores the integral part in the object + * pointed to by iptr. + */ +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_generic_address_space) + float __ovld modf(float x, float *iptr); + float2 __ovld modf(float2 x, float2 *iptr); + float3 __ovld modf(float3 x, float3 *iptr); +@@ -8217,7 +8217,7 @@ half16 __ovld __cnfn remainder(half16 x, half16 y); + * sign as x/y. It stores this signed value in the object + * pointed to by quo. + */ +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_generic_address_space) + float __ovld remquo(float x, float y, int *quo); + float2 __ovld remquo(float2 x, float2 y, int2 *quo); + float3 __ovld remquo(float3 x, float3 y, int3 *quo); +@@ -8441,7 +8441,7 @@ half16 __ovld __cnfn sin(half16); + * is the return value and computed cosine is returned + * in cosval. + */ +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_generic_address_space) + float __ovld sincos(float x, float *cosval); + float2 __ovld sincos(float2 x, float2 *cosval); + float3 __ovld sincos(float3 x, float3 *cosval); +@@ -11342,7 +11342,7 @@ half8 __ovld vload8(size_t offset, const __constant half *p); + half16 __ovld vload16(size_t offset, const __constant half *p); + #endif //cl_khr_fp16 + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_generic_address_space) + char2 __ovld vload2(size_t offset, const char *p); + uchar2 __ovld vload2(size_t offset, const uchar *p); + short2 __ovld vload2(size_t offset, const short *p); +@@ -11582,7 +11582,7 @@ half16 __ovld vload16(size_t offset, const __private half *p); + #endif //cl_khr_fp16 + #endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_generic_address_space) + void __ovld vstore2(char2 data, size_t offset, char *p); + void __ovld vstore2(uchar2 data, size_t offset, uchar *p); + void __ovld vstore2(short2 data, size_t offset, short *p); +@@ -11827,7 +11827,7 @@ void __ovld vstore16(half16 data, size_t offset, __private half *p); + * must be 16-bit aligned. + */ + float __ovld vload_half(size_t offset, const __constant half *p); +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_generic_address_space) + float __ovld vload_half(size_t offset, const half *p); + #else + float __ovld vload_half(size_t offset, const __global half *p); +@@ -11848,7 +11848,7 @@ float3 __ovld vload_half3(size_t offset, const __constant half *p); + float4 __ovld vload_half4(size_t offset, const __constant half *p); + float8 __ovld vload_half8(size_t offset, const __constant half *p); + float16 __ovld vload_half16(size_t offset, const __constant half *p); +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_generic_address_space) + float2 __ovld vload_half2(size_t offset, const half *p); + float3 __ovld vload_half3(size_t offset, const half *p); + float4 __ovld vload_half4(size_t offset, const half *p); +@@ -11883,7 +11883,7 @@ float16 __ovld vload_half16(size_t offset, const __private half *p); + * The default current rounding mode is round to + * nearest even. + */ +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_generic_address_space) + void __ovld vstore_half(float data, size_t offset, half *p); + void __ovld vstore_half_rte(float data, size_t offset, half *p); + void __ovld vstore_half_rtz(float data, size_t offset, half *p); +@@ -11942,7 +11942,7 @@ void __ovld vstore_half_rtn(double data, size_t offset, __private half *p); + * The default current rounding mode is round to + * nearest even. + */ +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_generic_address_space) + void __ovld vstore_half2(float2 data, size_t offset, half *p); + void __ovld vstore_half3(float3 data, size_t offset, half *p); + void __ovld vstore_half4(float4 data, size_t offset, half *p); +@@ -12169,7 +12169,7 @@ float3 __ovld vloada_half3(size_t offset, const __constant half *p); + float4 __ovld vloada_half4(size_t offset, const __constant half *p); + float8 __ovld vloada_half8(size_t offset, const __constant half *p); + float16 __ovld vloada_half16(size_t offset, const __constant half *p); +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_generic_address_space) + float __ovld vloada_half(size_t offset, const half *p); + float2 __ovld vloada_half2(size_t offset, const half *p); + float3 __ovld vloada_half3(size_t offset, const half *p); +@@ -12213,7 +12213,7 @@ float16 __ovld vloada_half16(size_t offset, const __private half *p); + * mode. The default current rounding mode is + * round to nearest even. + */ +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_generic_address_space) + void __ovld vstorea_half(float data, size_t offset, half *p); + void __ovld vstorea_half2(float2 data, size_t offset, half *p); + void __ovld vstorea_half3(float3 data, size_t offset, half *p); +@@ -12582,7 +12582,7 @@ void __ovld write_mem_fence(cl_mem_fence_flags flags); + + // OpenCL v2.0 s6.13.9 - Address Space Qualifier Functions + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_generic_address_space) + cl_mem_fence_flags __ovld get_fence(const void *ptr); + cl_mem_fence_flags __ovld get_fence(void *ptr); + +@@ -13397,138 +13397,113 @@ void __ovld atomic_init(volatile atomic_double *object, double value); + void __ovld atomic_work_item_fence(cl_mem_fence_flags flags, memory_order order, memory_scope scope); + + // atomic_fetch() ++// OpenCL v2.0 s6.13.11.7.5: ++// add/sub: atomic type argument can be uintptr_t/intptr_t, value type argument can be ptrdiff_t. + ++#if defined(__opencl_c_atomic_order_seq_cst) && defined(__opencl_c_atomic_scope_device) + int __ovld atomic_fetch_add(volatile atomic_int *object, int operand); +-int __ovld atomic_fetch_add_explicit(volatile atomic_int *object, int operand, memory_order order); +-int __ovld atomic_fetch_add_explicit(volatile atomic_int *object, int operand, memory_order order, memory_scope scope); + uint __ovld atomic_fetch_add(volatile atomic_uint *object, uint operand); +-uint __ovld atomic_fetch_add_explicit(volatile atomic_uint *object, uint operand, memory_order order); +-uint __ovld atomic_fetch_add_explicit(volatile atomic_uint *object, uint operand, memory_order order, memory_scope scope); + int __ovld atomic_fetch_sub(volatile atomic_int *object, int operand); +-int __ovld atomic_fetch_sub_explicit(volatile atomic_int *object, int operand, memory_order order); +-int __ovld atomic_fetch_sub_explicit(volatile atomic_int *object, int operand, memory_order order, memory_scope scope); + uint __ovld atomic_fetch_sub(volatile atomic_uint *object, uint operand); +-uint __ovld atomic_fetch_sub_explicit(volatile atomic_uint *object, uint operand, memory_order order); +-uint __ovld atomic_fetch_sub_explicit(volatile atomic_uint *object, uint operand, memory_order order, memory_scope scope); + int __ovld atomic_fetch_or(volatile atomic_int *object, int operand); +-int __ovld atomic_fetch_or_explicit(volatile atomic_int *object, int operand, memory_order order); +-int __ovld atomic_fetch_or_explicit(volatile atomic_int *object, int operand, memory_order order, memory_scope scope); + uint __ovld atomic_fetch_or(volatile atomic_uint *object, uint operand); +-uint __ovld atomic_fetch_or_explicit(volatile atomic_uint *object, uint operand, memory_order order); +-uint __ovld atomic_fetch_or_explicit(volatile atomic_uint *object, uint operand, memory_order order, memory_scope scope); + int __ovld atomic_fetch_xor(volatile atomic_int *object, int operand); +-int __ovld atomic_fetch_xor_explicit(volatile atomic_int *object, int operand, memory_order order); +-int __ovld atomic_fetch_xor_explicit(volatile atomic_int *object, int operand, memory_order order, memory_scope scope); + uint __ovld atomic_fetch_xor(volatile atomic_uint *object, uint operand); +-uint __ovld atomic_fetch_xor_explicit(volatile atomic_uint *object, uint operand, memory_order order); +-uint __ovld atomic_fetch_xor_explicit(volatile atomic_uint *object, uint operand, memory_order order, memory_scope scope); + int __ovld atomic_fetch_and(volatile atomic_int *object, int operand); +-int __ovld atomic_fetch_and_explicit(volatile atomic_int *object, int operand, memory_order order); +-int __ovld atomic_fetch_and_explicit(volatile atomic_int *object, int operand, memory_order order, memory_scope scope); + uint __ovld atomic_fetch_and(volatile atomic_uint *object, uint operand); +-uint __ovld atomic_fetch_and_explicit(volatile atomic_uint *object, uint operand, memory_order order); +-uint __ovld atomic_fetch_and_explicit(volatile atomic_uint *object, uint operand, memory_order order, memory_scope scope); + int __ovld atomic_fetch_min(volatile atomic_int *object, int operand); +-int __ovld atomic_fetch_min_explicit(volatile atomic_int *object, int operand, memory_order order); +-int __ovld atomic_fetch_min_explicit(volatile atomic_int *object, int operand, memory_order order, memory_scope scope); + uint __ovld atomic_fetch_min(volatile atomic_uint *object, uint operand); +-uint __ovld atomic_fetch_min_explicit(volatile atomic_uint *object, uint operand, memory_order order); +-uint __ovld atomic_fetch_min_explicit(volatile atomic_uint *object, uint operand, memory_order order, memory_scope scope); + int __ovld atomic_fetch_max(volatile atomic_int *object, int operand); +-int __ovld atomic_fetch_max_explicit(volatile atomic_int *object, int operand, memory_order order); +-int __ovld atomic_fetch_max_explicit(volatile atomic_int *object, int operand, memory_order order, memory_scope scope); + uint __ovld atomic_fetch_max(volatile atomic_uint *object, uint operand); +-uint __ovld atomic_fetch_max_explicit(volatile atomic_uint *object, uint operand, memory_order order); +-uint __ovld atomic_fetch_max_explicit(volatile atomic_uint *object, uint operand, memory_order order, memory_scope scope); + + #if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) + long __ovld atomic_fetch_add(volatile atomic_long *object, long operand); +-long __ovld atomic_fetch_add_explicit(volatile atomic_long *object, long operand, memory_order order); +-long __ovld atomic_fetch_add_explicit(volatile atomic_long *object, long operand, memory_order order, memory_scope scope); + ulong __ovld atomic_fetch_add(volatile atomic_ulong *object, ulong operand); +-ulong __ovld atomic_fetch_add_explicit(volatile atomic_ulong *object, ulong operand, memory_order order); +-ulong __ovld atomic_fetch_add_explicit(volatile atomic_ulong *object, ulong operand, memory_order order, memory_scope scope); + long __ovld atomic_fetch_sub(volatile atomic_long *object, long operand); +-long __ovld atomic_fetch_sub_explicit(volatile atomic_long *object, long operand, memory_order order); +-long __ovld atomic_fetch_sub_explicit(volatile atomic_long *object, long operand, memory_order order, memory_scope scope); + ulong __ovld atomic_fetch_sub(volatile atomic_ulong *object, ulong operand); +-ulong __ovld atomic_fetch_sub_explicit(volatile atomic_ulong *object, ulong operand, memory_order order); +-ulong __ovld atomic_fetch_sub_explicit(volatile atomic_ulong *object, ulong operand, memory_order order, memory_scope scope); + long __ovld atomic_fetch_or(volatile atomic_long *object, long operand); +-long __ovld atomic_fetch_or_explicit(volatile atomic_long *object, long operand, memory_order order); +-long __ovld atomic_fetch_or_explicit(volatile atomic_long *object, long operand, memory_order order, memory_scope scope); + ulong __ovld atomic_fetch_or(volatile atomic_ulong *object, ulong operand); +-ulong __ovld atomic_fetch_or_explicit(volatile atomic_ulong *object, ulong operand, memory_order order); +-ulong __ovld atomic_fetch_or_explicit(volatile atomic_ulong *object, ulong operand, memory_order order, memory_scope scope); + long __ovld atomic_fetch_xor(volatile atomic_long *object, long operand); +-long __ovld atomic_fetch_xor_explicit(volatile atomic_long *object, long operand, memory_order order); +-long __ovld atomic_fetch_xor_explicit(volatile atomic_long *object, long operand, memory_order order, memory_scope scope); + ulong __ovld atomic_fetch_xor(volatile atomic_ulong *object, ulong operand); +-ulong __ovld atomic_fetch_xor_explicit(volatile atomic_ulong *object, ulong operand, memory_order order); +-ulong __ovld atomic_fetch_xor_explicit(volatile atomic_ulong *object, ulong operand, memory_order order, memory_scope scope); + long __ovld atomic_fetch_and(volatile atomic_long *object, long operand); +-long __ovld atomic_fetch_and_explicit(volatile atomic_long *object, long operand, memory_order order); +-long __ovld atomic_fetch_and_explicit(volatile atomic_long *object, long operand, memory_order order, memory_scope scope); + ulong __ovld atomic_fetch_and(volatile atomic_ulong *object, ulong operand); +-ulong __ovld atomic_fetch_and_explicit(volatile atomic_ulong *object, ulong operand, memory_order order); +-ulong __ovld atomic_fetch_and_explicit(volatile atomic_ulong *object, ulong operand, memory_order order, memory_scope scope); + long __ovld atomic_fetch_min(volatile atomic_long *object, long operand); +-long __ovld atomic_fetch_min_explicit(volatile atomic_long *object, long operand, memory_order order); +-long __ovld atomic_fetch_min_explicit(volatile atomic_long *object, long operand, memory_order order, memory_scope scope); + ulong __ovld atomic_fetch_min(volatile atomic_ulong *object, ulong operand); +-ulong __ovld atomic_fetch_min_explicit(volatile atomic_ulong *object, ulong operand, memory_order order); +-ulong __ovld atomic_fetch_min_explicit(volatile atomic_ulong *object, ulong operand, memory_order order, memory_scope scope); + long __ovld atomic_fetch_max(volatile atomic_long *object, long operand); +-long __ovld atomic_fetch_max_explicit(volatile atomic_long *object, long operand, memory_order order); +-long __ovld atomic_fetch_max_explicit(volatile atomic_long *object, long operand, memory_order order, memory_scope scope); + ulong __ovld atomic_fetch_max(volatile atomic_ulong *object, ulong operand); +-ulong __ovld atomic_fetch_max_explicit(volatile atomic_ulong *object, ulong operand, memory_order order); +-ulong __ovld atomic_fetch_max_explicit(volatile atomic_ulong *object, ulong operand, memory_order order, memory_scope scope); ++uintptr_t __ovld atomic_fetch_add(volatile atomic_uintptr_t *object, ptrdiff_t operand); ++uintptr_t __ovld atomic_fetch_sub(volatile atomic_uintptr_t *object, ptrdiff_t operand); + #endif //defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) ++#endif + +-// OpenCL v2.0 s6.13.11.7.5: +-// add/sub: atomic type argument can be uintptr_t/intptr_t, value type argument can be ptrdiff_t. +-// or/xor/and/min/max: atomic type argument can be intptr_t/uintptr_t, value type argument can be intptr_t/uintptr_t. +- ++#if defined(__opencl_c_atomic_scope_device) ++int __ovld atomic_fetch_add_explicit(volatile atomic_int *object, int operand, memory_order order); ++uint __ovld atomic_fetch_add_explicit(volatile atomic_uint *object, uint operand, memory_order order); ++int __ovld atomic_fetch_sub_explicit(volatile atomic_int *object, int operand, memory_order order); ++uint __ovld atomic_fetch_sub_explicit(volatile atomic_uint *object, uint operand, memory_order order); ++int __ovld atomic_fetch_or_explicit(volatile atomic_int *object, int operand, memory_order order); ++uint __ovld atomic_fetch_or_explicit(volatile atomic_uint *object, uint operand, memory_order order); ++int __ovld atomic_fetch_xor_explicit(volatile atomic_int *object, int operand, memory_order order); ++uint __ovld atomic_fetch_xor_explicit(volatile atomic_uint *object, uint operand, memory_order order); ++int __ovld atomic_fetch_and_explicit(volatile atomic_int *object, int operand, memory_order order); ++uint __ovld atomic_fetch_and_explicit(volatile atomic_uint *object, uint operand, memory_order order); ++int __ovld atomic_fetch_min_explicit(volatile atomic_int *object, int operand, memory_order order); ++uint __ovld atomic_fetch_min_explicit(volatile atomic_uint *object, uint operand, memory_order order); ++int __ovld atomic_fetch_max_explicit(volatile atomic_int *object, int operand, memory_order order); ++uint __ovld atomic_fetch_max_explicit(volatile atomic_uint *object, uint operand, memory_order order); + #if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) +-uintptr_t __ovld atomic_fetch_add(volatile atomic_uintptr_t *object, ptrdiff_t operand); ++long __ovld atomic_fetch_add_explicit(volatile atomic_long *object, long operand, memory_order order); ++ulong __ovld atomic_fetch_add_explicit(volatile atomic_ulong *object, ulong operand, memory_order order); ++long __ovld atomic_fetch_sub_explicit(volatile atomic_long *object, long operand, memory_order order); ++ulong __ovld atomic_fetch_sub_explicit(volatile atomic_ulong *object, ulong operand, memory_order order); ++long __ovld atomic_fetch_or_explicit(volatile atomic_long *object, long operand, memory_order order); ++ulong __ovld atomic_fetch_or_explicit(volatile atomic_ulong *object, ulong operand, memory_order order); ++long __ovld atomic_fetch_xor_explicit(volatile atomic_long *object, long operand, memory_order order); ++ulong __ovld atomic_fetch_xor_explicit(volatile atomic_ulong *object, ulong operand, memory_order order); ++long __ovld atomic_fetch_and_explicit(volatile atomic_long *object, long operand, memory_order order); ++ulong __ovld atomic_fetch_and_explicit(volatile atomic_ulong *object, ulong operand, memory_order order); ++long __ovld atomic_fetch_min_explicit(volatile atomic_long *object, long operand, memory_order order); ++ulong __ovld atomic_fetch_min_explicit(volatile atomic_ulong *object, ulong operand, memory_order order); ++long __ovld atomic_fetch_max_explicit(volatile atomic_long *object, long operand, memory_order order); ++ulong __ovld atomic_fetch_max_explicit(volatile atomic_ulong *object, ulong operand, memory_order order); + uintptr_t __ovld atomic_fetch_add_explicit(volatile atomic_uintptr_t *object, ptrdiff_t operand, memory_order order); +-uintptr_t __ovld atomic_fetch_add_explicit(volatile atomic_uintptr_t *object, ptrdiff_t operand, memory_order order, memory_scope scope); +-uintptr_t __ovld atomic_fetch_sub(volatile atomic_uintptr_t *object, ptrdiff_t operand); + uintptr_t __ovld atomic_fetch_sub_explicit(volatile atomic_uintptr_t *object, ptrdiff_t operand, memory_order order); +-uintptr_t __ovld atomic_fetch_sub_explicit(volatile atomic_uintptr_t *object, ptrdiff_t operand, memory_order order, memory_scope scope); ++#endif //defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) ++#endif + +-uintptr_t __ovld atomic_fetch_or(volatile atomic_uintptr_t *object, intptr_t operand); +-uintptr_t __ovld atomic_fetch_or_explicit(volatile atomic_uintptr_t *object, intptr_t operand, memory_order order); +-uintptr_t __ovld atomic_fetch_or_explicit(volatile atomic_uintptr_t *object, intptr_t operand, memory_order order, memory_scope scope); +-uintptr_t __ovld atomic_fetch_xor(volatile atomic_uintptr_t *object, intptr_t operand); +-uintptr_t __ovld atomic_fetch_xor_explicit(volatile atomic_uintptr_t *object, intptr_t operand, memory_order order); +-uintptr_t __ovld atomic_fetch_xor_explicit(volatile atomic_uintptr_t *object, intptr_t operand, memory_order order, memory_scope scope); +-uintptr_t __ovld atomic_fetch_and(volatile atomic_uintptr_t *object, intptr_t operand); +-uintptr_t __ovld atomic_fetch_and_explicit(volatile atomic_uintptr_t *object, intptr_t operand, memory_order order); +-uintptr_t __ovld atomic_fetch_and_explicit(volatile atomic_uintptr_t *object, intptr_t operand, memory_order order, memory_scope scope); +-uintptr_t __ovld atomic_fetch_min(volatile atomic_uintptr_t *object, intptr_t opermax); +-uintptr_t __ovld atomic_fetch_min_explicit(volatile atomic_uintptr_t *object, intptr_t opermax, memory_order minder); +-uintptr_t __ovld atomic_fetch_min_explicit(volatile atomic_uintptr_t *object, intptr_t opermax, memory_order minder, memory_scope scope); +-uintptr_t __ovld atomic_fetch_max(volatile atomic_uintptr_t *object, intptr_t opermax); +-uintptr_t __ovld atomic_fetch_max_explicit(volatile atomic_uintptr_t *object, intptr_t opermax, memory_order minder); +-uintptr_t __ovld atomic_fetch_max_explicit(volatile atomic_uintptr_t *object, intptr_t opermax, memory_order minder, memory_scope scope); +- +-intptr_t __ovld atomic_fetch_or(volatile atomic_intptr_t *object, uintptr_t operand); +-intptr_t __ovld atomic_fetch_or_explicit(volatile atomic_intptr_t *object, uintptr_t operand, memory_order order); +-intptr_t __ovld atomic_fetch_or_explicit(volatile atomic_intptr_t *object, uintptr_t operand, memory_order order, memory_scope scope); +-intptr_t __ovld atomic_fetch_xor(volatile atomic_intptr_t *object, uintptr_t operand); +-intptr_t __ovld atomic_fetch_xor_explicit(volatile atomic_intptr_t *object, uintptr_t operand, memory_order order); +-intptr_t __ovld atomic_fetch_xor_explicit(volatile atomic_intptr_t *object, uintptr_t operand, memory_order order, memory_scope scope); +-intptr_t __ovld atomic_fetch_and(volatile atomic_intptr_t *object, uintptr_t operand); +-intptr_t __ovld atomic_fetch_and_explicit(volatile atomic_intptr_t *object, uintptr_t operand, memory_order order); +-intptr_t __ovld atomic_fetch_and_explicit(volatile atomic_intptr_t *object, uintptr_t operand, memory_order order, memory_scope scope); +-intptr_t __ovld atomic_fetch_min(volatile atomic_intptr_t *object, uintptr_t opermax); +-intptr_t __ovld atomic_fetch_min_explicit(volatile atomic_intptr_t *object, uintptr_t opermax, memory_order minder); +-intptr_t __ovld atomic_fetch_min_explicit(volatile atomic_intptr_t *object, uintptr_t opermax, memory_order minder, memory_scope scope); +-intptr_t __ovld atomic_fetch_max(volatile atomic_intptr_t *object, uintptr_t opermax); +-intptr_t __ovld atomic_fetch_max_explicit(volatile atomic_intptr_t *object, uintptr_t opermax, memory_order minder); +-intptr_t __ovld atomic_fetch_max_explicit(volatile atomic_intptr_t *object, uintptr_t opermax, memory_order minder, memory_scope scope); ++int __ovld atomic_fetch_add_explicit(volatile atomic_int *object, int operand, memory_order order, memory_scope scope); ++uint __ovld atomic_fetch_add_explicit(volatile atomic_uint *object, uint operand, memory_order order, memory_scope scope); ++int __ovld atomic_fetch_sub_explicit(volatile atomic_int *object, int operand, memory_order order, memory_scope scope); ++uint __ovld atomic_fetch_sub_explicit(volatile atomic_uint *object, uint operand, memory_order order, memory_scope scope); ++int __ovld atomic_fetch_or_explicit(volatile atomic_int *object, int operand, memory_order order, memory_scope scope); ++uint __ovld atomic_fetch_or_explicit(volatile atomic_uint *object, uint operand, memory_order order, memory_scope scope); ++int __ovld atomic_fetch_xor_explicit(volatile atomic_int *object, int operand, memory_order order, memory_scope scope); ++uint __ovld atomic_fetch_xor_explicit(volatile atomic_uint *object, uint operand, memory_order order, memory_scope scope); ++int __ovld atomic_fetch_and_explicit(volatile atomic_int *object, int operand, memory_order order, memory_scope scope); ++uint __ovld atomic_fetch_and_explicit(volatile atomic_uint *object, uint operand, memory_order order, memory_scope scope); ++int __ovld atomic_fetch_min_explicit(volatile atomic_int *object, int operand, memory_order order, memory_scope scope); ++uint __ovld atomic_fetch_min_explicit(volatile atomic_uint *object, uint operand, memory_order order, memory_scope scope); ++int __ovld atomic_fetch_max_explicit(volatile atomic_int *object, int operand, memory_order order, memory_scope scope); ++uint __ovld atomic_fetch_max_explicit(volatile atomic_uint *object, uint operand, memory_order order, memory_scope scope); ++#if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) ++long __ovld atomic_fetch_add_explicit(volatile atomic_long *object, long operand, memory_order order, memory_scope scope); ++ulong __ovld atomic_fetch_add_explicit(volatile atomic_ulong *object, ulong operand, memory_order order, memory_scope scope); ++long __ovld atomic_fetch_sub_explicit(volatile atomic_long *object, long operand, memory_order order, memory_scope scope); ++ulong __ovld atomic_fetch_sub_explicit(volatile atomic_ulong *object, ulong operand, memory_order order, memory_scope scope); ++long __ovld atomic_fetch_or_explicit(volatile atomic_long *object, long operand, memory_order order, memory_scope scope); ++ulong __ovld atomic_fetch_or_explicit(volatile atomic_ulong *object, ulong operand, memory_order order, memory_scope scope); ++long __ovld atomic_fetch_xor_explicit(volatile atomic_long *object, long operand, memory_order order, memory_scope scope); ++ulong __ovld atomic_fetch_xor_explicit(volatile atomic_ulong *object, ulong operand, memory_order order, memory_scope scope); ++long __ovld atomic_fetch_and_explicit(volatile atomic_long *object, long operand, memory_order order, memory_scope scope); ++ulong __ovld atomic_fetch_and_explicit(volatile atomic_ulong *object, ulong operand, memory_order order, memory_scope scope); ++long __ovld atomic_fetch_min_explicit(volatile atomic_long *object, long operand, memory_order order, memory_scope scope); ++ulong __ovld atomic_fetch_min_explicit(volatile atomic_ulong *object, ulong operand, memory_order order, memory_scope scope); ++long __ovld atomic_fetch_max_explicit(volatile atomic_long *object, long operand, memory_order order, memory_scope scope); ++ulong __ovld atomic_fetch_max_explicit(volatile atomic_ulong *object, ulong operand, memory_order order, memory_scope scope); ++#endif //defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) ++#if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) ++uintptr_t __ovld atomic_fetch_add_explicit(volatile atomic_uintptr_t *object, ptrdiff_t operand, memory_order order, memory_scope scope); ++uintptr_t __ovld atomic_fetch_sub_explicit(volatile atomic_uintptr_t *object, ptrdiff_t operand, memory_order order, memory_scope scope); + #endif + + // The functionality added by cl_ext_float_atomics extension +@@ -13911,155 +13886,213 @@ double __ovld atomic_fetch_sub_explicit(volatile atomic_double *object, + + // atomic_store() + ++#if defined(__opencl_c_atomic_order_seq_cst) && defined(__opencl_c_atomic_scope_device) + void __ovld atomic_store(volatile atomic_int *object, int desired); +-void __ovld atomic_store_explicit(volatile atomic_int *object, int desired, memory_order order); +-void __ovld atomic_store_explicit(volatile atomic_int *object, int desired, memory_order order, memory_scope scope); + void __ovld atomic_store(volatile atomic_uint *object, uint desired); +-void __ovld atomic_store_explicit(volatile atomic_uint *object, uint desired, memory_order order); +-void __ovld atomic_store_explicit(volatile atomic_uint *object, uint desired, memory_order order, memory_scope scope); + void __ovld atomic_store(volatile atomic_float *object, float desired); +-void __ovld atomic_store_explicit(volatile atomic_float *object, float desired, memory_order order); +-void __ovld atomic_store_explicit(volatile atomic_float *object, float desired, memory_order order, memory_scope scope); ++ + #if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) + #ifdef cl_khr_fp64 + void __ovld atomic_store(volatile atomic_double *object, double desired); +-void __ovld atomic_store_explicit(volatile atomic_double *object, double desired, memory_order order); +-void __ovld atomic_store_explicit(volatile atomic_double *object, double desired, memory_order order, memory_scope scope); + #endif //cl_khr_fp64 + void __ovld atomic_store(volatile atomic_long *object, long desired); +-void __ovld atomic_store_explicit(volatile atomic_long *object, long desired, memory_order order); +-void __ovld atomic_store_explicit(volatile atomic_long *object, long desired, memory_order order, memory_scope scope); + void __ovld atomic_store(volatile atomic_ulong *object, ulong desired); ++#endif ++#endif ++ ++#if defined(__opencl_c_atomic_scope_device) ++void __ovld atomic_store_explicit(volatile atomic_int *object, int desired, memory_order order); ++void __ovld atomic_store_explicit(volatile atomic_uint *object, uint desired, memory_order order); ++void __ovld atomic_store_explicit(volatile atomic_float *object, float desired, memory_order order); ++#if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) ++#ifdef cl_khr_fp64 ++void __ovld atomic_store_explicit(volatile atomic_double *object, double desired, memory_order order); ++#endif //cl_khr_fp64 ++void __ovld atomic_store_explicit(volatile atomic_long *object, long desired, memory_order order); + void __ovld atomic_store_explicit(volatile atomic_ulong *object, ulong desired, memory_order order); ++#endif ++#endif ++ ++void __ovld atomic_store_explicit(volatile atomic_int *object, int desired, memory_order order, memory_scope scope); ++void __ovld atomic_store_explicit(volatile atomic_uint *object, uint desired, memory_order order, memory_scope scope); ++void __ovld atomic_store_explicit(volatile atomic_float *object, float desired, memory_order order, memory_scope scope); ++#if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) ++#ifdef cl_khr_fp64 ++void __ovld atomic_store_explicit(volatile atomic_double *object, double desired, memory_order order, memory_scope scope); ++#endif //cl_khr_fp64 ++void __ovld atomic_store_explicit(volatile atomic_long *object, long desired, memory_order order, memory_scope scope); + void __ovld atomic_store_explicit(volatile atomic_ulong *object, ulong desired, memory_order order, memory_scope scope); + #endif + + // atomic_load() +- ++#if defined(__opencl_c_atomic_order_seq_cst) && defined(__opencl_c_atomic_scope_device) + int __ovld atomic_load(volatile atomic_int *object); +-int __ovld atomic_load_explicit(volatile atomic_int *object, memory_order order); +-int __ovld atomic_load_explicit(volatile atomic_int *object, memory_order order, memory_scope scope); + uint __ovld atomic_load(volatile atomic_uint *object); +-uint __ovld atomic_load_explicit(volatile atomic_uint *object, memory_order order); +-uint __ovld atomic_load_explicit(volatile atomic_uint *object, memory_order order, memory_scope scope); + float __ovld atomic_load(volatile atomic_float *object); +-float __ovld atomic_load_explicit(volatile atomic_float *object, memory_order order); +-float __ovld atomic_load_explicit(volatile atomic_float *object, memory_order order, memory_scope scope); + #if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) + #ifdef cl_khr_fp64 + double __ovld atomic_load(volatile atomic_double *object); +-double __ovld atomic_load_explicit(volatile atomic_double *object, memory_order order); +-double __ovld atomic_load_explicit(volatile atomic_double *object, memory_order order, memory_scope scope); + #endif //cl_khr_fp64 + long __ovld atomic_load(volatile atomic_long *object); +-long __ovld atomic_load_explicit(volatile atomic_long *object, memory_order order); +-long __ovld atomic_load_explicit(volatile atomic_long *object, memory_order order, memory_scope scope); + ulong __ovld atomic_load(volatile atomic_ulong *object); ++#endif ++#endif ++ ++#if defined(__opencl_c_atomic_scope_device) ++int __ovld atomic_load_explicit(volatile atomic_int *object, memory_order order); ++uint __ovld atomic_load_explicit(volatile atomic_uint *object, memory_order order); ++float __ovld atomic_load_explicit(volatile atomic_float *object, memory_order order); ++#if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) ++#ifdef cl_khr_fp64 ++double __ovld atomic_load_explicit(volatile atomic_double *object, memory_order order); ++#endif //cl_khr_fp64 ++long __ovld atomic_load_explicit(volatile atomic_long *object, memory_order order); + ulong __ovld atomic_load_explicit(volatile atomic_ulong *object, memory_order order); ++#endif ++#endif ++ ++int __ovld atomic_load_explicit(volatile atomic_int *object, memory_order order, memory_scope scope); ++uint __ovld atomic_load_explicit(volatile atomic_uint *object, memory_order order, memory_scope scope); ++float __ovld atomic_load_explicit(volatile atomic_float *object, memory_order order, memory_scope scope); ++#if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) ++#ifdef cl_khr_fp64 ++double __ovld atomic_load_explicit(volatile atomic_double *object, memory_order order, memory_scope scope); ++#endif //cl_khr_fp64 ++long __ovld atomic_load_explicit(volatile atomic_long *object, memory_order order, memory_scope scope); + ulong __ovld atomic_load_explicit(volatile atomic_ulong *object, memory_order order, memory_scope scope); + #endif + + // atomic_exchange() + ++#if defined(__opencl_c_atomic_order_seq_cst) && defined(__opencl_c_atomic_scope_device) + int __ovld atomic_exchange(volatile atomic_int *object, int desired); +-int __ovld atomic_exchange_explicit(volatile atomic_int *object, int desired, memory_order order); +-int __ovld atomic_exchange_explicit(volatile atomic_int *object, int desired, memory_order order, memory_scope scope); + uint __ovld atomic_exchange(volatile atomic_uint *object, uint desired); +-uint __ovld atomic_exchange_explicit(volatile atomic_uint *object, uint desired, memory_order order); +-uint __ovld atomic_exchange_explicit(volatile atomic_uint *object, uint desired, memory_order order, memory_scope scope); + float __ovld atomic_exchange(volatile atomic_float *object, float desired); +-float __ovld atomic_exchange_explicit(volatile atomic_float *object, float desired, memory_order order); +-float __ovld atomic_exchange_explicit(volatile atomic_float *object, float desired, memory_order order, memory_scope scope); + #if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) + #ifdef cl_khr_fp64 + double __ovld atomic_exchange(volatile atomic_double *object, double desired); +-double __ovld atomic_exchange_explicit(volatile atomic_double *object, double desired, memory_order order); +-double __ovld atomic_exchange_explicit(volatile atomic_double *object, double desired, memory_order order, memory_scope scope); + #endif //cl_khr_fp64 + long __ovld atomic_exchange(volatile atomic_long *object, long desired); +-long __ovld atomic_exchange_explicit(volatile atomic_long *object, long desired, memory_order order); +-long __ovld atomic_exchange_explicit(volatile atomic_long *object, long desired, memory_order order, memory_scope scope); + ulong __ovld atomic_exchange(volatile atomic_ulong *object, ulong desired); ++#endif ++#endif ++ ++#if defined(__opencl_c_atomic_scope_device) ++int __ovld atomic_exchange_explicit(volatile atomic_int *object, int desired, memory_order order); ++uint __ovld atomic_exchange_explicit(volatile atomic_uint *object, uint desired, memory_order order); ++float __ovld atomic_exchange_explicit(volatile atomic_float *object, float desired, memory_order order); ++#if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) ++#ifdef cl_khr_fp64 ++double __ovld atomic_exchange_explicit(volatile atomic_double *object, double desired, memory_order order); ++#endif //cl_khr_fp64 ++long __ovld atomic_exchange_explicit(volatile atomic_long *object, long desired, memory_order order); + ulong __ovld atomic_exchange_explicit(volatile atomic_ulong *object, ulong desired, memory_order order); ++#endif ++#endif ++ ++int __ovld atomic_exchange_explicit(volatile atomic_int *object, int desired, memory_order order, memory_scope scope); ++uint __ovld atomic_exchange_explicit(volatile atomic_uint *object, uint desired, memory_order order, memory_scope scope); ++float __ovld atomic_exchange_explicit(volatile atomic_float *object, float desired, memory_order order, memory_scope scope); ++#if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) ++#ifdef cl_khr_fp64 ++double __ovld atomic_exchange_explicit(volatile atomic_double *object, double desired, memory_order order, memory_scope scope); ++#endif //cl_khr_fp64 ++long __ovld atomic_exchange_explicit(volatile atomic_long *object, long desired, memory_order order, memory_scope scope); + ulong __ovld atomic_exchange_explicit(volatile atomic_ulong *object, ulong desired, memory_order order, memory_scope scope); + #endif + + // atomic_compare_exchange_strong() and atomic_compare_exchange_weak() +- ++#if defined(__opencl_c_atomic_order_seq_cst) && defined(__opencl_c_atomic_scope_device) + bool __ovld atomic_compare_exchange_strong(volatile atomic_int *object, int *expected, int desired); ++bool __ovld atomic_compare_exchange_strong(volatile atomic_uint *object, uint *expected, uint desired); ++bool __ovld atomic_compare_exchange_weak(volatile atomic_int *object, int *expected, int desired); ++bool __ovld atomic_compare_exchange_weak(volatile atomic_uint *object, uint *expected, uint desired); ++bool __ovld atomic_compare_exchange_strong(volatile atomic_float *object, float *expected, float desired); ++bool __ovld atomic_compare_exchange_weak(volatile atomic_float *object, float *expected, float desired); ++ ++#if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) ++#ifdef cl_khr_fp64 ++bool __ovld atomic_compare_exchange_strong(volatile atomic_double *object, double *expected, double desired); ++bool __ovld atomic_compare_exchange_weak(volatile atomic_double *object, double *expected, double desired); ++#endif //cl_khr_fp64 ++bool __ovld atomic_compare_exchange_strong(volatile atomic_long *object, long *expected, long desired); ++bool __ovld atomic_compare_exchange_weak(volatile atomic_long *object, long *expected, long desired); ++bool __ovld atomic_compare_exchange_strong(volatile atomic_ulong *object, ulong *expected, ulong desired); ++bool __ovld atomic_compare_exchange_weak(volatile atomic_ulong *object, ulong *expected, ulong desired); ++#endif ++#endif ++ + bool __ovld atomic_compare_exchange_strong_explicit(volatile atomic_int *object, int *expected, + int desired, memory_order success, memory_order failure); +-bool __ovld atomic_compare_exchange_strong_explicit(volatile atomic_int *object, int *expected, +- int desired, memory_order success, memory_order failure, memory_scope scope); +-bool __ovld atomic_compare_exchange_strong(volatile atomic_uint *object, uint *expected, uint desired); + bool __ovld atomic_compare_exchange_strong_explicit(volatile atomic_uint *object, uint *expected, + uint desired, memory_order success, memory_order failure); +-bool __ovld atomic_compare_exchange_strong_explicit(volatile atomic_uint *object, uint *expected, +- uint desired, memory_order success, memory_order failure, memory_scope scope); +-bool __ovld atomic_compare_exchange_weak(volatile atomic_int *object, int *expected, int desired); + bool __ovld atomic_compare_exchange_weak_explicit(volatile atomic_int *object, int *expected, + int desired, memory_order success, memory_order failure); +-bool __ovld atomic_compare_exchange_weak_explicit(volatile atomic_int *object, int *expected, +- int desired, memory_order success, memory_order failure, memory_scope scope); +-bool __ovld atomic_compare_exchange_weak(volatile atomic_uint *object, uint *expected, uint desired); + bool __ovld atomic_compare_exchange_weak_explicit(volatile atomic_uint *object, uint *expected, + uint desired, memory_order success, memory_order failure); +-bool __ovld atomic_compare_exchange_weak_explicit(volatile atomic_uint *object, uint *expected, +- uint desired, memory_order success, memory_order failure, memory_scope scope); +-bool __ovld atomic_compare_exchange_strong(volatile atomic_float *object, float *expected, float desired); + bool __ovld atomic_compare_exchange_strong_explicit(volatile atomic_float *object, float *expected, + float desired, memory_order success, memory_order failure); +-bool __ovld atomic_compare_exchange_strong_explicit(volatile atomic_float *object, float *expected, +- float desired, memory_order success, memory_order failure, memory_scope scope); +-bool __ovld atomic_compare_exchange_weak(volatile atomic_float *object, float *expected, float desired); + bool __ovld atomic_compare_exchange_weak_explicit(volatile atomic_float *object, float *expected, + float desired, memory_order success, memory_order failure); +-bool __ovld atomic_compare_exchange_weak_explicit(volatile atomic_float *object, float *expected, +- float desired, memory_order success, memory_order failure, memory_scope scope); + #if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) + #ifdef cl_khr_fp64 +-bool __ovld atomic_compare_exchange_strong(volatile atomic_double *object, double *expected, double desired); + bool __ovld atomic_compare_exchange_strong_explicit(volatile atomic_double *object, double *expected, + double desired, memory_order success, memory_order failure); +-bool __ovld atomic_compare_exchange_strong_explicit(volatile atomic_double *object, double *expected, +- double desired, memory_order success, memory_order failure, memory_scope scope); +-bool __ovld atomic_compare_exchange_weak(volatile atomic_double *object, double *expected, double desired); + bool __ovld atomic_compare_exchange_weak_explicit(volatile atomic_double *object, double *expected, + double desired, memory_order success, memory_order failure); +-bool __ovld atomic_compare_exchange_weak_explicit(volatile atomic_double *object, double *expected, +- double desired, memory_order success, memory_order failure, memory_scope scope); + #endif //cl_khr_fp64 +-bool __ovld atomic_compare_exchange_strong(volatile atomic_long *object, long *expected, long desired); + bool __ovld atomic_compare_exchange_strong_explicit(volatile atomic_long *object, long *expected, + long desired, memory_order success, memory_order failure); +-bool __ovld atomic_compare_exchange_strong_explicit(volatile atomic_long *object, long *expected, +- long desired, memory_order success, memory_order failure, memory_scope scope); +-bool __ovld atomic_compare_exchange_weak(volatile atomic_long *object, long *expected, long desired); + bool __ovld atomic_compare_exchange_weak_explicit(volatile atomic_long *object, long *expected, + long desired, memory_order success, memory_order failure); +-bool __ovld atomic_compare_exchange_weak_explicit(volatile atomic_long *object, long *expected, +- long desired, memory_order success, memory_order failure, memory_scope scope); +-bool __ovld atomic_compare_exchange_strong(volatile atomic_ulong *object, ulong *expected, ulong desired); + bool __ovld atomic_compare_exchange_strong_explicit(volatile atomic_ulong *object, ulong *expected, + ulong desired, memory_order success, memory_order failure); +-bool __ovld atomic_compare_exchange_strong_explicit(volatile atomic_ulong *object, ulong *expected, +- ulong desired, memory_order success, memory_order failure, memory_scope scope); +-bool __ovld atomic_compare_exchange_weak(volatile atomic_ulong *object, ulong *expected, ulong desired); + bool __ovld atomic_compare_exchange_weak_explicit(volatile atomic_ulong *object, ulong *expected, + ulong desired, memory_order success, memory_order failure); ++#endif ++ ++bool __ovld atomic_compare_exchange_strong_explicit(volatile atomic_int *object, int *expected, ++ int desired, memory_order success, memory_order failure, memory_scope scope); ++bool __ovld atomic_compare_exchange_strong_explicit(volatile atomic_uint *object, uint *expected, ++ uint desired, memory_order success, memory_order failure, memory_scope scope); ++bool __ovld atomic_compare_exchange_weak_explicit(volatile atomic_int *object, int *expected, ++ int desired, memory_order success, memory_order failure, memory_scope scope); ++bool __ovld atomic_compare_exchange_weak_explicit(volatile atomic_uint *object, uint *expected, ++ uint desired, memory_order success, memory_order failure, memory_scope scope); ++bool __ovld atomic_compare_exchange_strong_explicit(volatile atomic_float *object, float *expected, ++ float desired, memory_order success, memory_order failure, memory_scope scope); ++bool __ovld atomic_compare_exchange_weak_explicit(volatile atomic_float *object, float *expected, ++ float desired, memory_order success, memory_order failure, memory_scope scope); ++#if defined(cl_khr_int64_base_atomics) && defined(cl_khr_int64_extended_atomics) ++#ifdef cl_khr_fp64 ++bool __ovld atomic_compare_exchange_strong_explicit(volatile atomic_double *object, double *expected, ++ double desired, memory_order success, memory_order failure, memory_scope scope); ++bool __ovld atomic_compare_exchange_weak_explicit(volatile atomic_double *object, double *expected, ++ double desired, memory_order success, memory_order failure, memory_scope scope); ++#endif //cl_khr_fp64 ++bool __ovld atomic_compare_exchange_strong_explicit(volatile atomic_long *object, long *expected, ++ long desired, memory_order success, memory_order failure, memory_scope scope); ++bool __ovld atomic_compare_exchange_weak_explicit(volatile atomic_long *object, long *expected, ++ long desired, memory_order success, memory_order failure, memory_scope scope); ++bool __ovld atomic_compare_exchange_strong_explicit(volatile atomic_ulong *object, ulong *expected, ++ ulong desired, memory_order success, memory_order failure, memory_scope scope); + bool __ovld atomic_compare_exchange_weak_explicit(volatile atomic_ulong *object, ulong *expected, + ulong desired, memory_order success, memory_order failure, memory_scope scope); + #endif + + // atomic_flag_test_and_set() and atomic_flag_clear() +- ++#if defined(__opencl_c_atomic_order_seq_cst) && defined(__opencl_c_atomic_scope_device) + bool __ovld atomic_flag_test_and_set(volatile atomic_flag *object); +-bool __ovld atomic_flag_test_and_set_explicit(volatile atomic_flag *object, memory_order order); +-bool __ovld atomic_flag_test_and_set_explicit(volatile atomic_flag *object, memory_order order, memory_scope scope); + void __ovld atomic_flag_clear(volatile atomic_flag *object); ++#endif ++ ++#if defined(__opencl_c_atomic_scope_device) ++bool __ovld atomic_flag_test_and_set_explicit(volatile atomic_flag *object, memory_order order); + void __ovld atomic_flag_clear_explicit(volatile atomic_flag *object, memory_order order); +-void __ovld atomic_flag_clear_explicit(volatile atomic_flag *object, memory_order order, memory_scope scope); ++#endif + ++bool __ovld atomic_flag_test_and_set_explicit(volatile atomic_flag *object, memory_order order, memory_scope scope); ++void __ovld atomic_flag_clear_explicit(volatile atomic_flag *object, memory_order order, memory_scope scope); + #endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) + + // OpenCL v1.1 s6.11.12, v1.2 s6.12.12, v2.0 s6.13.12 - Miscellaneous Vector Functions +@@ -14843,7 +14876,7 @@ half4 __purefn __ovld read_imageh(read_only image1d_buffer_t image, int coord); + #endif //cl_khr_fp16 + + // Image read functions for read_write images +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_read_write_images) + float4 __purefn __ovld read_imagef(read_write image1d_t image, int coord); + int4 __purefn __ovld read_imagei(read_write image1d_t image, int coord); + uint4 __purefn __ovld read_imageui(read_write image1d_t image, int coord); +@@ -14886,7 +14919,6 @@ float __purefn __ovld read_imagef(read_write image2d_msaa_depth_t image, int2 co + float __purefn __ovld read_imagef(read_write image2d_array_msaa_depth_t image, int4 coord, int sample); + #endif //cl_khr_gl_msaa_sharing + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) + #ifdef cl_khr_mipmap_image + float4 __purefn __ovld read_imagef(read_write image1d_t image, sampler_t sampler, float coord, float lod); + int4 __purefn __ovld read_imagei(read_write image1d_t image, sampler_t sampler, float coord, float lod); +@@ -14937,7 +14969,6 @@ int4 __purefn __ovld read_imagei(read_write image3d_t image, sampler_t sampler, + uint4 __purefn __ovld read_imageui(read_write image3d_t image, sampler_t sampler, float4 coord, float4 gradientX, float4 gradientY); + + #endif //cl_khr_mipmap_image +-#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) + + // Image read functions returning half4 type + #ifdef cl_khr_fp16 +@@ -14948,7 +14979,7 @@ half4 __purefn __ovld read_imageh(read_write image1d_array_t image, int2 coord); + half4 __purefn __ovld read_imageh(read_write image2d_array_t image, int4 coord); + half4 __purefn __ovld read_imageh(read_write image1d_buffer_t image, int coord); + #endif //cl_khr_fp16 +-#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#endif //defined(__opencl_c_read_write_images + + /** + * Write color value to location specified by coordinate +@@ -15092,7 +15123,7 @@ void __ovld write_imageh(write_only image1d_buffer_t image, int coord, half4 col + #endif //cl_khr_fp16 + + // Image write functions for read_write images +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_read_write_images) + void __ovld write_imagef(read_write image2d_t image, int2 coord, float4 color); + void __ovld write_imagei(read_write image2d_t image, int2 coord, int4 color); + void __ovld write_imageui(read_write image2d_t image, int2 coord, uint4 color); +@@ -15124,7 +15155,6 @@ void __ovld write_imagef(read_write image2d_depth_t image, int2 coord, float col + void __ovld write_imagef(read_write image2d_array_depth_t image, int4 coord, float color); + #endif //cl_khr_depth_images + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) + #if defined(cl_khr_mipmap_image_writes) + void __ovld write_imagef(read_write image1d_t image, int coord, int lod, float4 color); + void __ovld write_imagei(read_write image1d_t image, int coord, int lod, int4 color); +@@ -15152,7 +15182,6 @@ void __ovld write_imageui(read_write image3d_t image, int4 coord, int lod, uint4 + #endif //cl_khr_3d_image_writes + + #endif //cl_khr_mipmap_image_writes +-#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) + + // Image write functions for half4 type + #ifdef cl_khr_fp16 +@@ -15165,7 +15194,7 @@ void __ovld write_imageh(read_write image1d_array_t image, int2 coord, half4 col + void __ovld write_imageh(read_write image2d_array_t image, int4 coord, half4 color); + void __ovld write_imageh(read_write image1d_buffer_t image, int coord, half4 color); + #endif //cl_khr_fp16 +-#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#endif //defined(__opencl_c_read_write_images) + + // Note: In OpenCL v1.0/1.1/1.2, image argument of image query builtin functions does not have + // access qualifier, which by default assume read_only access qualifier. Image query builtin +@@ -15213,7 +15242,7 @@ int __ovld __cnfn get_image_width(write_only image2d_array_msaa_t image); + int __ovld __cnfn get_image_width(write_only image2d_array_msaa_depth_t image); + #endif //cl_khr_gl_msaa_sharing + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_read_write_images) + int __ovld __cnfn get_image_width(read_write image1d_t image); + int __ovld __cnfn get_image_width(read_write image1d_buffer_t image); + int __ovld __cnfn get_image_width(read_write image2d_t image); +@@ -15230,7 +15259,7 @@ int __ovld __cnfn get_image_width(read_write image2d_msaa_depth_t image); + int __ovld __cnfn get_image_width(read_write image2d_array_msaa_t image); + int __ovld __cnfn get_image_width(read_write image2d_array_msaa_depth_t image); + #endif //cl_khr_gl_msaa_sharing +-#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#endif //defined(__opencl_c_read_write_images) + + /** + * Return the image height in pixels. +@@ -15265,7 +15294,7 @@ int __ovld __cnfn get_image_height(write_only image2d_array_msaa_t image); + int __ovld __cnfn get_image_height(write_only image2d_array_msaa_depth_t image); + #endif //cl_khr_gl_msaa_sharing + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_read_write_images) + int __ovld __cnfn get_image_height(read_write image2d_t image); + int __ovld __cnfn get_image_height(read_write image3d_t image); + int __ovld __cnfn get_image_height(read_write image2d_array_t image); +@@ -15279,7 +15308,7 @@ int __ovld __cnfn get_image_height(read_write image2d_msaa_depth_t image); + int __ovld __cnfn get_image_height(read_write image2d_array_msaa_t image); + int __ovld __cnfn get_image_height(read_write image2d_array_msaa_depth_t image); + #endif //cl_khr_gl_msaa_sharing +-#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#endif //defined(__opencl_c_read_write_images) + + /** + * Return the image depth in pixels. +@@ -15290,9 +15319,9 @@ int __ovld __cnfn get_image_depth(read_only image3d_t image); + int __ovld __cnfn get_image_depth(write_only image3d_t image); + #endif + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_read_write_images) + int __ovld __cnfn get_image_depth(read_write image3d_t image); +-#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#endif //defined(__opencl_c_read_write_images) + + // OpenCL Extension v2.0 s9.18 - Mipmaps + #if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) +@@ -15388,7 +15417,7 @@ int __ovld __cnfn get_image_channel_data_type(write_only image2d_array_msaa_t im + int __ovld __cnfn get_image_channel_data_type(write_only image2d_array_msaa_depth_t image); + #endif //cl_khr_gl_msaa_sharing + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_read_write_images) + int __ovld __cnfn get_image_channel_data_type(read_write image1d_t image); + int __ovld __cnfn get_image_channel_data_type(read_write image1d_buffer_t image); + int __ovld __cnfn get_image_channel_data_type(read_write image2d_t image); +@@ -15405,7 +15434,7 @@ int __ovld __cnfn get_image_channel_data_type(read_write image2d_msaa_depth_t im + int __ovld __cnfn get_image_channel_data_type(read_write image2d_array_msaa_t image); + int __ovld __cnfn get_image_channel_data_type(read_write image2d_array_msaa_depth_t image); + #endif //cl_khr_gl_msaa_sharing +-#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#endif //defined(__opencl_c_read_write_images) + + /** + * Return the image channel order. Valid values are: +@@ -15460,7 +15489,7 @@ int __ovld __cnfn get_image_channel_order(write_only image2d_array_msaa_t image) + int __ovld __cnfn get_image_channel_order(write_only image2d_array_msaa_depth_t image); + #endif //cl_khr_gl_msaa_sharing + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_read_write_images) + int __ovld __cnfn get_image_channel_order(read_write image1d_t image); + int __ovld __cnfn get_image_channel_order(read_write image1d_buffer_t image); + int __ovld __cnfn get_image_channel_order(read_write image2d_t image); +@@ -15477,7 +15506,7 @@ int __ovld __cnfn get_image_channel_order(read_write image2d_msaa_depth_t image) + int __ovld __cnfn get_image_channel_order(read_write image2d_array_msaa_t image); + int __ovld __cnfn get_image_channel_order(read_write image2d_array_msaa_depth_t image); + #endif //cl_khr_gl_msaa_sharing +-#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#endif //defined(__opencl_c_read_write_images) + + /** + * Return the 2D image width and height as an int2 +@@ -15510,7 +15539,7 @@ int2 __ovld __cnfn get_image_dim(write_only image2d_array_msaa_t image); + int2 __ovld __cnfn get_image_dim(write_only image2d_array_msaa_depth_t image); + #endif //cl_khr_gl_msaa_sharing + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_read_write_images) + int2 __ovld __cnfn get_image_dim(read_write image2d_t image); + int2 __ovld __cnfn get_image_dim(read_write image2d_array_t image); + #ifdef cl_khr_depth_images +@@ -15523,7 +15552,7 @@ int2 __ovld __cnfn get_image_dim(read_write image2d_msaa_depth_t image); + int2 __ovld __cnfn get_image_dim(read_write image2d_array_msaa_t image); + int2 __ovld __cnfn get_image_dim(read_write image2d_array_msaa_depth_t image); + #endif //cl_khr_gl_msaa_sharing +-#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#endif //defined(__opencl_c_read_write_images) + + /** + * Return the 3D image width, height, and depth as an +@@ -15535,9 +15564,9 @@ int4 __ovld __cnfn get_image_dim(read_only image3d_t image); + #ifdef cl_khr_3d_image_writes + int4 __ovld __cnfn get_image_dim(write_only image3d_t image); + #endif +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_read_write_images) + int4 __ovld __cnfn get_image_dim(read_write image3d_t image); +-#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#endif //defined(__opencl_c_read_write_images) + + /** + * Return the image array size. +@@ -15563,7 +15592,7 @@ size_t __ovld __cnfn get_image_array_size(write_only image2d_array_msaa_t image_ + size_t __ovld __cnfn get_image_array_size(write_only image2d_array_msaa_depth_t image_array); + #endif //cl_khr_gl_msaa_sharing + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_read_write_images) + size_t __ovld __cnfn get_image_array_size(read_write image1d_array_t image_array); + size_t __ovld __cnfn get_image_array_size(read_write image2d_array_t image_array); + #ifdef cl_khr_depth_images +@@ -15573,7 +15602,7 @@ size_t __ovld __cnfn get_image_array_size(read_write image2d_array_depth_t image + size_t __ovld __cnfn get_image_array_size(read_write image2d_array_msaa_t image_array); + size_t __ovld __cnfn get_image_array_size(read_write image2d_array_msaa_depth_t image_array); + #endif //cl_khr_gl_msaa_sharing +-#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#endif //defined(__opencl_c_read_write_images) + + /** + * Return the number of samples associated with image +@@ -15589,12 +15618,12 @@ int __ovld get_image_num_samples(write_only image2d_msaa_depth_t image); + int __ovld get_image_num_samples(write_only image2d_array_msaa_t image); + int __ovld get_image_num_samples(write_only image2d_array_msaa_depth_t image); + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_read_write_images) + int __ovld get_image_num_samples(read_write image2d_msaa_t image); + int __ovld get_image_num_samples(read_write image2d_msaa_depth_t image); + int __ovld get_image_num_samples(read_write image2d_array_msaa_t image); + int __ovld get_image_num_samples(read_write image2d_array_msaa_depth_t image); +-#endif //defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#endif //defined(__opencl_c_read_write_images) + #endif + + // OpenCL v2.0 s6.13.15 - Work-group Functions +@@ -16630,34 +16659,38 @@ uint16 __ovld __conv intel_sub_group_shuffle_xor( uint16 x, uint c ); + long __ovld __conv intel_sub_group_shuffle_xor( long x, uint c ); + ulong __ovld __conv intel_sub_group_shuffle_xor( ulong x, uint c ); + ++#if defined(__opencl_c_images) + uint __ovld __conv intel_sub_group_block_read( read_only image2d_t image, int2 coord ); + uint2 __ovld __conv intel_sub_group_block_read2( read_only image2d_t image, int2 coord ); + uint4 __ovld __conv intel_sub_group_block_read4( read_only image2d_t image, int2 coord ); + uint8 __ovld __conv intel_sub_group_block_read8( read_only image2d_t image, int2 coord ); ++#endif + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_read_write_images) + uint __ovld __conv intel_sub_group_block_read(read_write image2d_t image, int2 coord); + uint2 __ovld __conv intel_sub_group_block_read2(read_write image2d_t image, int2 coord); + uint4 __ovld __conv intel_sub_group_block_read4(read_write image2d_t image, int2 coord); + uint8 __ovld __conv intel_sub_group_block_read8(read_write image2d_t image, int2 coord); +-#endif // defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#endif // defined(__opencl_c_read_write_images) + + uint __ovld __conv intel_sub_group_block_read( const __global uint* p ); + uint2 __ovld __conv intel_sub_group_block_read2( const __global uint* p ); + uint4 __ovld __conv intel_sub_group_block_read4( const __global uint* p ); + uint8 __ovld __conv intel_sub_group_block_read8( const __global uint* p ); + ++#if defined(__opencl_c_images) + void __ovld __conv intel_sub_group_block_write(write_only image2d_t image, int2 coord, uint data); + void __ovld __conv intel_sub_group_block_write2(write_only image2d_t image, int2 coord, uint2 data); + void __ovld __conv intel_sub_group_block_write4(write_only image2d_t image, int2 coord, uint4 data); + void __ovld __conv intel_sub_group_block_write8(write_only image2d_t image, int2 coord, uint8 data); ++#endif // defined(__opencl_c_images) + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_read_write_images) + void __ovld __conv intel_sub_group_block_write(read_write image2d_t image, int2 coord, uint data); + void __ovld __conv intel_sub_group_block_write2(read_write image2d_t image, int2 coord, uint2 data); + void __ovld __conv intel_sub_group_block_write4(read_write image2d_t image, int2 coord, uint4 data); + void __ovld __conv intel_sub_group_block_write8(read_write image2d_t image, int2 coord, uint8 data); +-#endif // defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#endif // defined(__opencl_c_read_write_images) + + void __ovld __conv intel_sub_group_block_write( __global uint* p, uint data ); + void __ovld __conv intel_sub_group_block_write2( __global uint* p, uint2 data ); +@@ -16770,68 +16803,76 @@ ushort __ovld __conv intel_sub_group_scan_inclusive_min( ushort x ); + short __ovld __conv intel_sub_group_scan_inclusive_max( short x ); + ushort __ovld __conv intel_sub_group_scan_inclusive_max( ushort x ); + ++#if defined(__opencl_c_images) + uint __ovld __conv intel_sub_group_block_read_ui( read_only image2d_t image, int2 byte_coord ); + uint2 __ovld __conv intel_sub_group_block_read_ui2( read_only image2d_t image, int2 byte_coord ); + uint4 __ovld __conv intel_sub_group_block_read_ui4( read_only image2d_t image, int2 byte_coord ); + uint8 __ovld __conv intel_sub_group_block_read_ui8( read_only image2d_t image, int2 byte_coord ); ++#endif // defined(__opencl_c_images) + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_read_write_images) + uint __ovld __conv intel_sub_group_block_read_ui( read_write image2d_t image, int2 byte_coord ); + uint2 __ovld __conv intel_sub_group_block_read_ui2( read_write image2d_t image, int2 byte_coord ); + uint4 __ovld __conv intel_sub_group_block_read_ui4( read_write image2d_t image, int2 byte_coord ); + uint8 __ovld __conv intel_sub_group_block_read_ui8( read_write image2d_t image, int2 byte_coord ); +-#endif // defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#endif // defined(__opencl_c_read_write_images) + + uint __ovld __conv intel_sub_group_block_read_ui( const __global uint* p ); + uint2 __ovld __conv intel_sub_group_block_read_ui2( const __global uint* p ); + uint4 __ovld __conv intel_sub_group_block_read_ui4( const __global uint* p ); + uint8 __ovld __conv intel_sub_group_block_read_ui8( const __global uint* p ); + ++#if defined(__opencl_c_images) + void __ovld __conv intel_sub_group_block_write_ui( read_only image2d_t image, int2 byte_coord, uint data ); + void __ovld __conv intel_sub_group_block_write_ui2( read_only image2d_t image, int2 byte_coord, uint2 data ); + void __ovld __conv intel_sub_group_block_write_ui4( read_only image2d_t image, int2 byte_coord, uint4 data ); + void __ovld __conv intel_sub_group_block_write_ui8( read_only image2d_t image, int2 byte_coord, uint8 data ); ++#endif //defined(__opencl_c_images) + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_read_write_images) + void __ovld __conv intel_sub_group_block_write_ui( read_write image2d_t image, int2 byte_coord, uint data ); + void __ovld __conv intel_sub_group_block_write_ui2( read_write image2d_t image, int2 byte_coord, uint2 data ); + void __ovld __conv intel_sub_group_block_write_ui4( read_write image2d_t image, int2 byte_coord, uint4 data ); + void __ovld __conv intel_sub_group_block_write_ui8( read_write image2d_t image, int2 byte_coord, uint8 data ); +-#endif // defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#endif // defined(__opencl_c_read_write_images) + + void __ovld __conv intel_sub_group_block_write_ui( __global uint* p, uint data ); + void __ovld __conv intel_sub_group_block_write_ui2( __global uint* p, uint2 data ); + void __ovld __conv intel_sub_group_block_write_ui4( __global uint* p, uint4 data ); + void __ovld __conv intel_sub_group_block_write_ui8( __global uint* p, uint8 data ); + ++#if defined(__opencl_c_images) + ushort __ovld __conv intel_sub_group_block_read_us( read_only image2d_t image, int2 coord ); + ushort2 __ovld __conv intel_sub_group_block_read_us2( read_only image2d_t image, int2 coord ); + ushort4 __ovld __conv intel_sub_group_block_read_us4( read_only image2d_t image, int2 coord ); + ushort8 __ovld __conv intel_sub_group_block_read_us8( read_only image2d_t image, int2 coord ); ++#endif // defined(__opencl_c_images) + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_read_write_images) + ushort __ovld __conv intel_sub_group_block_read_us(read_write image2d_t image, int2 coord); + ushort2 __ovld __conv intel_sub_group_block_read_us2(read_write image2d_t image, int2 coord); + ushort4 __ovld __conv intel_sub_group_block_read_us4(read_write image2d_t image, int2 coord); + ushort8 __ovld __conv intel_sub_group_block_read_us8(read_write image2d_t image, int2 coord); +-#endif // defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#endif // defined(__opencl_c_read_write_images) + + ushort __ovld __conv intel_sub_group_block_read_us( const __global ushort* p ); + ushort2 __ovld __conv intel_sub_group_block_read_us2( const __global ushort* p ); + ushort4 __ovld __conv intel_sub_group_block_read_us4( const __global ushort* p ); + ushort8 __ovld __conv intel_sub_group_block_read_us8( const __global ushort* p ); + ++#if defined(__opencl_c_images) + void __ovld __conv intel_sub_group_block_write_us(write_only image2d_t image, int2 coord, ushort data); + void __ovld __conv intel_sub_group_block_write_us2(write_only image2d_t image, int2 coord, ushort2 data); + void __ovld __conv intel_sub_group_block_write_us4(write_only image2d_t image, int2 coord, ushort4 data); + void __ovld __conv intel_sub_group_block_write_us8(write_only image2d_t image, int2 coord, ushort8 data); ++#endif // defined(__opencl_c_images) + +-#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#if defined(__opencl_c_read_write_images) + void __ovld __conv intel_sub_group_block_write_us(read_write image2d_t image, int2 coord, ushort data); + void __ovld __conv intel_sub_group_block_write_us2(read_write image2d_t image, int2 coord, ushort2 data); + void __ovld __conv intel_sub_group_block_write_us4(read_write image2d_t image, int2 coord, ushort4 data); + void __ovld __conv intel_sub_group_block_write_us8(read_write image2d_t image, int2 coord, ushort8 data); +-#endif // defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0) ++#endif // defined(__opencl_c_read_write_images) + + void __ovld __conv intel_sub_group_block_write_us( __global ushort* p, ushort data ); + void __ovld __conv intel_sub_group_block_write_us2( __global ushort* p, ushort2 data ); +@@ -16949,6 +16990,7 @@ short2 __ovld intel_sub_group_avc_ime_adjust_ref_offset( + short2 ref_offset, ushort2 src_coord, ushort2 ref_window_size, + ushort2 image_size); + ++#if defined(__opencl_c_images) + intel_sub_group_avc_ime_result_t __ovld + intel_sub_group_avc_ime_evaluate_with_single_reference( + read_only image2d_t src_image, read_only image2d_t ref_image, +@@ -16989,6 +17031,7 @@ intel_sub_group_avc_ime_evaluate_with_dual_reference_streaminout( + read_only image2d_t bwd_ref_image, sampler_t vme_media_sampler, + intel_sub_group_avc_ime_payload_t payload, + intel_sub_group_avc_ime_dual_reference_streamin_t streamin_components); ++#endif + + intel_sub_group_avc_ime_single_reference_streamin_t __ovld + intel_sub_group_avc_ime_get_single_reference_streamin( +@@ -17053,6 +17096,7 @@ intel_sub_group_avc_ref_payload_t __ovld + intel_sub_group_avc_ref_set_bilinear_filter_enable( + intel_sub_group_avc_ref_payload_t payload); + ++#if defined(__opencl_c_images) + intel_sub_group_avc_ref_result_t __ovld + intel_sub_group_avc_ref_evaluate_with_single_reference( + read_only image2d_t src_image, read_only image2d_t ref_image, +@@ -17071,6 +17115,7 @@ intel_sub_group_avc_ref_evaluate_with_multi_reference( + read_only image2d_t src_image, uint packed_reference_ids, + uchar packed_reference_field_polarities, sampler_t vme_media_sampler, + intel_sub_group_avc_ref_payload_t payload); ++#endif //defined(__opencl_c_images) + + // SIC built-in functions + intel_sub_group_avc_sic_payload_t __ovld +@@ -17121,6 +17166,7 @@ intel_sub_group_avc_sic_set_block_based_raw_skip_sad( + uchar block_based_skip_type, + intel_sub_group_avc_sic_payload_t payload); + ++#if defined(__opencl_c_images) + intel_sub_group_avc_sic_result_t __ovld + intel_sub_group_avc_sic_evaluate_ipe( + read_only image2d_t src_image, sampler_t vme_media_sampler, +@@ -17143,6 +17189,7 @@ intel_sub_group_avc_sic_evaluate_with_multi_reference( + read_only image2d_t src_image, uint packed_reference_ids, + uchar packed_reference_field_polarities, sampler_t vme_media_sampler, + intel_sub_group_avc_sic_payload_t payload); ++#endif //defined(__opencl_c_images) + + uchar __ovld intel_sub_group_avc_sic_get_ipe_luma_shape( + intel_sub_group_avc_sic_result_t result); +@@ -17529,31 +17576,23 @@ uint16 __ovld amd_sadw(uint16 src0, uint16 src1, uint16 src2); + #endif // cl_amd_media_ops2 + + #if defined(cl_arm_integer_dot_product_int8) +-#pragma OPENCL EXTENSION cl_arm_integer_dot_product_int8 : begin + uint __ovld arm_dot(uchar4 a, uchar4 b); + int __ovld arm_dot(char4 a, char4 b); +-#pragma OPENCL EXTENSION cl_arm_integer_dot_product_int8 : end + #endif // defined(cl_arm_integer_dot_product_int8) + + #if defined(cl_arm_integer_dot_product_accumulate_int8) +-#pragma OPENCL EXTENSION cl_arm_integer_dot_product_accumulate_int8 : begin + uint __ovld arm_dot_acc(uchar4 a, uchar4 b, uint c); + int __ovld arm_dot_acc(char4 a, char4 b, int c); +-#pragma OPENCL EXTENSION cl_arm_integer_dot_product_accumulate_int8 : end + #endif // defined(cl_arm_integer_dot_product_accumulate_int8) + + #if defined(cl_arm_integer_dot_product_accumulate_int16) +-#pragma OPENCL EXTENSION cl_arm_integer_dot_product_accumulate_int16 : begin + uint __ovld arm_dot_acc(ushort2 a, ushort2 b, uint c); + int __ovld arm_dot_acc(short2 a, short2 b, int c); +-#pragma OPENCL EXTENSION cl_arm_integer_dot_product_accumulate_int16 : end + #endif // defined(cl_arm_integer_dot_product_accumulate_int16) + + #if defined(cl_arm_integer_dot_product_accumulate_saturate_int8) +-#pragma OPENCL EXTENSION cl_arm_integer_dot_product_accumulate_saturate_int8 : begin + uint __ovld arm_dot_acc_sat(uchar4 a, uchar4 b, uint c); + int __ovld arm_dot_acc_sat(char4 a, char4 b, int c); +-#pragma OPENCL EXTENSION cl_arm_integer_dot_product_accumulate_saturate_int8 : end + #endif // defined(cl_arm_integer_dot_product_accumulate_saturate_int8) + + // Disable any extensions we may have enabled previously. +diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp +index 347d992b1643..c489c8c75623 100644 +--- a/clang/lib/Parse/ParseDecl.cpp ++++ b/clang/lib/Parse/ParseDecl.cpp +@@ -3631,8 +3631,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, + // C++ for OpenCL does not allow virtual function qualifier, to avoid + // function pointers restricted in OpenCL v2.0 s6.9.a. + if (getLangOpts().OpenCLCPlusPlus && +- !getActions().getOpenCLOptions().isEnabled( +- "__cl_clang_function_pointers")) { ++ !getActions().getOpenCLOptions().isAvailableOption( ++ "__cl_clang_function_pointers", getLangOpts())) { + DiagID = diag::err_openclcxx_virtual_function; + PrevSpec = Tok.getIdentifierInfo()->getNameStart(); + isInvalid = true; +@@ -4002,8 +4002,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, + case tok::kw___generic: + // generic address space is introduced only in OpenCL v2.0 + // see OpenCL C Spec v2.0 s6.5.5 +- if (Actions.getLangOpts().OpenCLVersion < 200 && +- !Actions.getLangOpts().OpenCLCPlusPlus) { ++ // OpenCL v3.0 introduces __opencl_c_generic_address_space ++ // feature macro to indicate if generic address space is supported ++ if (!Actions.getLangOpts().OpenCLGenericAddressSpace) { + DiagID = diag::err_opencl_unknown_type_specifier; + PrevSpec = Tok.getIdentifierInfo()->getNameStart(); + isInvalid = true; +@@ -5059,8 +5060,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { + default: return false; + + case tok::kw_pipe: +- return (getLangOpts().OpenCL && getLangOpts().OpenCLVersion >= 200) || +- getLangOpts().OpenCLCPlusPlus; ++ return getLangOpts().OpenCLPipe; + + case tok::identifier: // foo::bar + // Unfortunate hack to support "Class.factoryMethod" notation. +@@ -5587,9 +5587,7 @@ static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang, + DeclaratorContext TheContext) { + if (Kind == tok::star || Kind == tok::caret) + return true; +- +- if (Kind == tok::kw_pipe && +- ((Lang.OpenCL && Lang.OpenCLVersion >= 200) || Lang.OpenCLCPlusPlus)) ++ if (Kind == tok::kw_pipe && Lang.OpenCLPipe) + return true; + + if (!Lang.CPlusPlus) +diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp +index f9b852826775..948e04eafa41 100644 +--- a/clang/lib/Parse/ParsePragma.cpp ++++ b/clang/lib/Parse/ParsePragma.cpp +@@ -771,22 +771,21 @@ void Parser::HandlePragmaOpenCLExtension() { + // overriding all previously issued extension directives, but only if the + // behavior is set to disable." + if (Name == "all") { +- if (State == Disable) { ++ if (State == Disable) + Opt.disableAll(); +- Opt.enableSupportedCore(getLangOpts()); +- } else { ++ else + PP.Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1; +- } + } else if (State == Begin) { + if (!Opt.isKnown(Name) || !Opt.isSupported(Name, getLangOpts())) { + Opt.support(Name); ++ // FIXME: Default behavior of the extension pragma is not defined. ++ // Therefore, it should never be added by default. ++ Opt.acceptsPragma(Name); + } +- Actions.setCurrentOpenCLExtension(Name); + } else if (State == End) { +- if (Name != Actions.getCurrentOpenCLExtension()) +- PP.Diag(NameLoc, diag::warn_pragma_begin_end_mismatch); +- Actions.setCurrentOpenCLExtension(""); +- } else if (!Opt.isKnown(Name)) ++ // There is no behavior for this directive. We only accept this for ++ // backward compatibility. ++ } else if (!Opt.isKnown(Name) || !Opt.isWithPragma(Name)) + PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident; + else if (Opt.isSupportedExtension(Name, getLangOpts())) + Opt.enable(Name, State == Enable); +diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp +index 9b0f921b4269..b3b02f8d266a 100644 +--- a/clang/lib/Parse/Parser.cpp ++++ b/clang/lib/Parse/Parser.cpp +@@ -1079,8 +1079,6 @@ Parser::ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs, + Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none, + DS, AnonRecord); + DS.complete(TheDecl); +- if (getLangOpts().OpenCL) +- Actions.setCurrentOpenCLExtensionForDecl(TheDecl); + if (AnonRecord) { + Decl* decls[] = {AnonRecord, TheDecl}; + return Actions.BuildDeclaratorGroup(decls); +diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp +index da42db3e8f7b..f60708d7dc01 100644 +--- a/clang/lib/Sema/DeclSpec.cpp ++++ b/clang/lib/Sema/DeclSpec.cpp +@@ -625,7 +625,8 @@ bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, + // OpenCL v1.2 s6.8 changes this to "The auto and register storage-class + // specifiers are not supported." + if (S.getLangOpts().OpenCL && +- !S.getOpenCLOptions().isEnabled("cl_clang_storage_class_specifiers")) { ++ !S.getOpenCLOptions().isAvailableOption( ++ "cl_clang_storage_class_specifiers", S.getLangOpts())) { + switch (SC) { + case SCS_extern: + case SCS_private_extern: +diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp +index a91291c7af38..95ba22ddf2a7 100644 +--- a/clang/lib/Sema/Sema.cpp ++++ b/clang/lib/Sema/Sema.cpp +@@ -299,7 +299,6 @@ void Sema::Initialize() { + if (getLangOpts().OpenCL) { + getOpenCLOptions().addSupport( + Context.getTargetInfo().getSupportedOpenCLOpts(), getLangOpts()); +- getOpenCLOptions().enableSupportedCore(getLangOpts()); + addImplicitTypedef("sampler_t", Context.OCLSamplerTy); + addImplicitTypedef("event_t", Context.OCLEventTy); + if (getLangOpts().OpenCLCPlusPlus || getLangOpts().OpenCLVersion >= 200) { +@@ -309,28 +308,13 @@ void Sema::Initialize() { + addImplicitTypedef("atomic_int", Context.getAtomicType(Context.IntTy)); + addImplicitTypedef("atomic_uint", + Context.getAtomicType(Context.UnsignedIntTy)); +- auto AtomicLongT = Context.getAtomicType(Context.LongTy); +- addImplicitTypedef("atomic_long", AtomicLongT); +- auto AtomicULongT = Context.getAtomicType(Context.UnsignedLongTy); +- addImplicitTypedef("atomic_ulong", AtomicULongT); + auto AtomicHalfT = Context.getAtomicType(Context.HalfTy); + addImplicitTypedef("atomic_half", AtomicHalfT); +- setOpenCLExtensionForType(AtomicHalfT, "cl_khr_fp16"); + addImplicitTypedef("atomic_float", + Context.getAtomicType(Context.FloatTy)); +- auto AtomicDoubleT = Context.getAtomicType(Context.DoubleTy); +- addImplicitTypedef("atomic_double", AtomicDoubleT); + // OpenCLC v2.0, s6.13.11.6 requires that atomic_flag is implemented as + // 32-bit integer and OpenCLC v2.0, s6.1.1 int is always 32-bit wide. + addImplicitTypedef("atomic_flag", Context.getAtomicType(Context.IntTy)); +- auto AtomicIntPtrT = Context.getAtomicType(Context.getIntPtrType()); +- addImplicitTypedef("atomic_intptr_t", AtomicIntPtrT); +- auto AtomicUIntPtrT = Context.getAtomicType(Context.getUIntPtrType()); +- addImplicitTypedef("atomic_uintptr_t", AtomicUIntPtrT); +- auto AtomicSizeT = Context.getAtomicType(Context.getSizeType()); +- addImplicitTypedef("atomic_size_t", AtomicSizeT); +- auto AtomicPtrDiffT = Context.getAtomicType(Context.getPointerDiffType()); +- addImplicitTypedef("atomic_ptrdiff_t", AtomicPtrDiffT); + + // OpenCL v2.0 s6.13.11.6: + // - The atomic_long and atomic_ulong types are supported if the +@@ -343,31 +327,47 @@ void Sema::Initialize() { + // atomic_intptr_t, atomic_uintptr_t, atomic_size_t and + // atomic_ptrdiff_t are supported if the cl_khr_int64_base_atomics and + // cl_khr_int64_extended_atomics extensions are supported. +- std::vector Atomic64BitTypes; +- Atomic64BitTypes.push_back(AtomicLongT); +- Atomic64BitTypes.push_back(AtomicULongT); +- Atomic64BitTypes.push_back(AtomicDoubleT); +- if (Context.getTypeSize(AtomicSizeT) == 64) { +- Atomic64BitTypes.push_back(AtomicSizeT); +- Atomic64BitTypes.push_back(AtomicIntPtrT); +- Atomic64BitTypes.push_back(AtomicUIntPtrT); +- Atomic64BitTypes.push_back(AtomicPtrDiffT); ++ auto AddPointerSizeDependentTypes = [&]() { ++ auto AtomicSizeT = Context.getAtomicType(Context.getSizeType()); ++ auto AtomicIntPtrT = Context.getAtomicType(Context.getIntPtrType()); ++ auto AtomicUIntPtrT = Context.getAtomicType(Context.getUIntPtrType()); ++ auto AtomicPtrDiffT = ++ Context.getAtomicType(Context.getPointerDiffType()); ++ addImplicitTypedef("atomic_size_t", AtomicSizeT); ++ addImplicitTypedef("atomic_intptr_t", AtomicIntPtrT); ++ addImplicitTypedef("atomic_uintptr_t", AtomicUIntPtrT); ++ addImplicitTypedef("atomic_ptrdiff_t", AtomicPtrDiffT); ++ }; ++ ++ if (Context.getTypeSize(Context.getSizeType()) == 32) { ++ AddPointerSizeDependentTypes(); + } +- for (auto &I : Atomic64BitTypes) +- setOpenCLExtensionForType(I, +- "cl_khr_int64_base_atomics cl_khr_int64_extended_atomics"); + +- setOpenCLExtensionForType(AtomicDoubleT, "cl_khr_fp64"); ++ std::vector Atomic64BitTypes; ++ if (getOpenCLOptions().isSupported("cl_khr_int64_base_atomics", ++ getLangOpts()) && ++ getOpenCLOptions().isSupported("cl_khr_int64_extended_atomics", ++ getLangOpts())) { ++ if (getOpenCLOptions().isSupported("cl_khr_fp64", getLangOpts())) { ++ auto AtomicDoubleT = Context.getAtomicType(Context.DoubleTy); ++ addImplicitTypedef("atomic_double", AtomicDoubleT); ++ Atomic64BitTypes.push_back(AtomicDoubleT); ++ } ++ auto AtomicLongT = Context.getAtomicType(Context.LongTy); ++ auto AtomicULongT = Context.getAtomicType(Context.UnsignedLongTy); ++ ++ addImplicitTypedef("atomic_long", AtomicLongT); ++ addImplicitTypedef("atomic_ulong", AtomicULongT); ++ if (Context.getTypeSize(Context.getSizeType()) == 64) { ++ AddPointerSizeDependentTypes(); ++ } ++ } + } + +- setOpenCLExtensionForType(Context.DoubleTy, "cl_khr_fp64"); +- +-#define GENERIC_IMAGE_TYPE_EXT(Type, Id, Ext) \ +- setOpenCLExtensionForType(Context.Id, Ext); +-#include "clang/Basic/OpenCLImageTypes.def" +-#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ +- addImplicitTypedef(#ExtType, Context.Id##Ty); \ +- setOpenCLExtensionForType(Context.Id##Ty, #Ext); ++#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ ++ if (getOpenCLOptions().isSupported(#Ext, getLangOpts())) { \ ++ addImplicitTypedef(#ExtType, Context.Id##Ty); \ ++ } + #include "clang/Basic/OpenCLExtensionTypes.def" + } + +@@ -2451,114 +2451,3 @@ const llvm::MapVector & + Sema::getMismatchingDeleteExpressions() const { + return DeleteExprs; + } +- +-void Sema::setOpenCLExtensionForType(QualType T, llvm::StringRef ExtStr) { +- if (ExtStr.empty()) +- return; +- llvm::SmallVector Exts; +- ExtStr.split(Exts, " ", /* limit */ -1, /* keep empty */ false); +- auto CanT = T.getCanonicalType().getTypePtr(); +- for (auto &I : Exts) +- OpenCLTypeExtMap[CanT].insert(I.str()); +-} +- +-void Sema::setOpenCLExtensionForDecl(Decl *FD, StringRef ExtStr) { +- llvm::SmallVector Exts; +- ExtStr.split(Exts, " ", /* limit */ -1, /* keep empty */ false); +- if (Exts.empty()) +- return; +- for (auto &I : Exts) +- OpenCLDeclExtMap[FD].insert(I.str()); +-} +- +-void Sema::setCurrentOpenCLExtensionForType(QualType T) { +- if (CurrOpenCLExtension.empty()) +- return; +- setOpenCLExtensionForType(T, CurrOpenCLExtension); +-} +- +-void Sema::setCurrentOpenCLExtensionForDecl(Decl *D) { +- if (CurrOpenCLExtension.empty()) +- return; +- setOpenCLExtensionForDecl(D, CurrOpenCLExtension); +-} +- +-std::string Sema::getOpenCLExtensionsFromDeclExtMap(FunctionDecl *FD) { +- if (!OpenCLDeclExtMap.empty()) +- return getOpenCLExtensionsFromExtMap(FD, OpenCLDeclExtMap); +- +- return ""; +-} +- +-std::string Sema::getOpenCLExtensionsFromTypeExtMap(FunctionType *FT) { +- if (!OpenCLTypeExtMap.empty()) +- return getOpenCLExtensionsFromExtMap(FT, OpenCLTypeExtMap); +- +- return ""; +-} +- +-template +-std::string Sema::getOpenCLExtensionsFromExtMap(T *FDT, MapT &Map) { +- auto Loc = Map.find(FDT); +- return llvm::join(Loc->second, " "); +-} +- +-bool Sema::isOpenCLDisabledDecl(Decl *FD) { +- auto Loc = OpenCLDeclExtMap.find(FD); +- if (Loc == OpenCLDeclExtMap.end()) +- return false; +- for (auto &I : Loc->second) { +- if (!getOpenCLOptions().isEnabled(I)) +- return true; +- } +- return false; +-} +- +-template +-bool Sema::checkOpenCLDisabledTypeOrDecl(T D, DiagLocT DiagLoc, +- DiagInfoT DiagInfo, MapT &Map, +- unsigned Selector, +- SourceRange SrcRange) { +- auto Loc = Map.find(D); +- if (Loc == Map.end()) +- return false; +- bool Disabled = false; +- for (auto &I : Loc->second) { +- if (I != CurrOpenCLExtension && !getOpenCLOptions().isEnabled(I)) { +- Diag(DiagLoc, diag::err_opencl_requires_extension) << Selector << DiagInfo +- << I << SrcRange; +- Disabled = true; +- } +- } +- return Disabled; +-} +- +-bool Sema::checkOpenCLDisabledTypeDeclSpec(const DeclSpec &DS, QualType QT) { +- // Check extensions for declared types. +- Decl *Decl = nullptr; +- if (auto TypedefT = dyn_cast(QT.getTypePtr())) +- Decl = TypedefT->getDecl(); +- if (auto TagT = dyn_cast(QT.getCanonicalType().getTypePtr())) +- Decl = TagT->getDecl(); +- auto Loc = DS.getTypeSpecTypeLoc(); +- +- // Check extensions for vector types. +- // e.g. double4 is not allowed when cl_khr_fp64 is absent. +- if (QT->isExtVectorType()) { +- auto TypePtr = QT->castAs()->getElementType().getTypePtr(); +- return checkOpenCLDisabledTypeOrDecl(TypePtr, Loc, QT, OpenCLTypeExtMap); +- } +- +- if (checkOpenCLDisabledTypeOrDecl(Decl, Loc, QT, OpenCLDeclExtMap)) +- return true; +- +- // Check extensions for builtin types. +- return checkOpenCLDisabledTypeOrDecl(QT.getCanonicalType().getTypePtr(), Loc, +- QT, OpenCLTypeExtMap); +-} +- +-bool Sema::checkOpenCLDisabledDecl(const NamedDecl &D, const Expr &E) { +- IdentifierInfo *FnName = D.getIdentifier(); +- return checkOpenCLDisabledTypeOrDecl(&D, E.getBeginLoc(), FnName, +- OpenCLDeclExtMap, 1, D.getSourceRange()); +-} +diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp +index 671820afd485..22ec2c7ed8bb 100644 +--- a/clang/lib/Sema/SemaCast.cpp ++++ b/clang/lib/Sema/SemaCast.cpp +@@ -2916,8 +2916,8 @@ void CastOperation::CheckCStyleCast() { + } + } + +- if (Self.getLangOpts().OpenCL && +- !Self.getOpenCLOptions().isEnabled("cl_khr_fp16")) { ++ if (Self.getLangOpts().OpenCL && !Self.getOpenCLOptions().isAvailableOption( ++ "cl_khr_fp16", Self.getLangOpts())) { + if (DestType->isHalfType()) { + Self.Diag(SrcExpr.get()->getBeginLoc(), diag::err_opencl_cast_to_half) + << DestType << SrcExpr.get()->getSourceRange(); +diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp +index 2b55712d44c2..b35ac5af9d75 100644 +--- a/clang/lib/Sema/SemaChecking.cpp ++++ b/clang/lib/Sema/SemaChecking.cpp +@@ -837,7 +837,8 @@ static bool checkOpenCLBlockArgs(Sema &S, Expr *BlockArg) { + } + + static bool checkOpenCLSubgroupExt(Sema &S, CallExpr *Call) { +- if (!S.getOpenCLOptions().isEnabled("cl_khr_subgroups")) { ++ if (!S.getOpenCLOptions().isAvailableOption("cl_khr_subgroups", ++ S.getLangOpts())) { + S.Diag(Call->getBeginLoc(), diag::err_opencl_requires_extension) + << 1 << Call->getDirectCallee() << "cl_khr_subgroups"; + return true; +diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp +index 1f7ab49ccdd7..420ba7a5498f 100644 +--- a/clang/lib/Sema/SemaDecl.cpp ++++ b/clang/lib/Sema/SemaDecl.cpp +@@ -5559,9 +5559,6 @@ Decl *Sema::ActOnDeclarator(Scope *S, Declarator &D) { + Dcl && Dcl->getDeclContext()->isFileContext()) + Dcl->setTopLevelDeclInObjCContainer(); + +- if (getLangOpts().OpenCL) +- setCurrentOpenCLExtensionForDecl(Dcl); +- + return Dcl; + } + +@@ -6341,7 +6338,11 @@ void Sema::deduceOpenCLAddressSpace(ValueDecl *Decl) { + if (Type->isSamplerT() || Type->isVoidType()) + return; + LangAS ImplAS = LangAS::opencl_private; +- if ((getLangOpts().OpenCLCPlusPlus || getLangOpts().OpenCLVersion >= 200) && ++ // OpenCL C v3.0 s6.7.8 - For OpenCL C 2.0 or with the ++ // __opencl_c_program_scope_global_variables feature, the address space ++ // for a variable at program scope or a static or extern variable inside ++ // a function are inferred to be __global. ++ if (getOpenCLOptions().areProgramScopeVariablesSupported(getLangOpts()) && + Var->hasGlobalStorage()) + ImplAS = LangAS::opencl_global; + // If the original type from a decayed type is an array type and that array +@@ -6757,7 +6758,8 @@ static bool diagnoseOpenCLTypes(Scope *S, Sema &Se, Declarator &D, + } + + // OpenCL v1.0 s6.8.a.3: Pointers to functions are not allowed. +- if (!Se.getOpenCLOptions().isEnabled("__cl_clang_function_pointers")) { ++ if (!Se.getOpenCLOptions().isAvailableOption("__cl_clang_function_pointers", ++ Se.getLangOpts())) { + QualType NR = R; + while (NR->isPointerType() || NR->isMemberFunctionPointerType()) { + if (NR->isFunctionPointerType() || NR->isMemberFunctionPointerType()) { +@@ -6769,7 +6771,8 @@ static bool diagnoseOpenCLTypes(Scope *S, Sema &Se, Declarator &D, + } + } + +- if (!Se.getOpenCLOptions().isEnabled("cl_khr_fp16")) { ++ if (!Se.getOpenCLOptions().isAvailableOption("cl_khr_fp16", ++ Se.getLangOpts())) { + // OpenCL v1.2 s6.1.1.1: reject declaring variables of the half and + // half array type (unless the cl_khr_fp16 extension is enabled). + if (Se.Context.getBaseElementType(R)->isHalfType()) { +@@ -7878,7 +7881,8 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { + // OpenCL v1.2 s6.8 - The static qualifier is valid only in program + // scope. + if (getLangOpts().OpenCLVersion == 120 && +- !getOpenCLOptions().isEnabled("cl_clang_storage_class_specifiers") && ++ !getOpenCLOptions().isAvailableOption("cl_clang_storage_class_specifiers", ++ getLangOpts()) && + NewVD->isStaticLocal()) { + Diag(NewVD->getLocation(), diag::err_static_function_scope); + NewVD->setInvalidDecl(); +@@ -7907,23 +7911,16 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { + return; + } + } +- // OpenCL C v1.2 s6.5 - All program scope variables must be declared in the +- // __constant address space. +- // OpenCL C v2.0 s6.5.1 - Variables defined at program scope and static +- // variables inside a function can also be declared in the global +- // address space. +- // C++ for OpenCL inherits rule from OpenCL C v2.0. + // FIXME: Adding local AS in C++ for OpenCL might make sense. + if (NewVD->isFileVarDecl() || NewVD->isStaticLocal() || + NewVD->hasExternalStorage()) { +- if (!T->isSamplerT() && +- !T->isDependentType() && ++ if (!T->isSamplerT() && !T->isDependentType() && + !(T.getAddressSpace() == LangAS::opencl_constant || + (T.getAddressSpace() == LangAS::opencl_global && +- (getLangOpts().OpenCLVersion == 200 || +- getLangOpts().OpenCLCPlusPlus)))) { ++ getOpenCLOptions().areProgramScopeVariablesSupported( ++ getLangOpts())))) { + int Scope = NewVD->isStaticLocal() | NewVD->hasExternalStorage() << 1; +- if (getLangOpts().OpenCLVersion == 200 || getLangOpts().OpenCLCPlusPlus) ++ if (getOpenCLOptions().areProgramScopeVariablesSupported(getLangOpts())) + Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space) + << Scope << "global or constant"; + else +@@ -8650,7 +8647,8 @@ static OpenCLParamType getOpenCLKernelParameterType(Sema &S, QualType PT) { + // OpenCL extension spec v1.2 s9.5: + // This extension adds support for half scalar and vector types as built-in + // types that can be used for arithmetic operations, conversions etc. +- if (!S.getOpenCLOptions().isEnabled("cl_khr_fp16") && PT->isHalfType()) ++ if (!S.getOpenCLOptions().isAvailableOption("cl_khr_fp16", S.getLangOpts()) && ++ PT->isHalfType()) + return InvalidKernelParam; + + if (PT->isRecordType()) +diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp +index 30d08b3d4ac0..a06fcfb8cc22 100644 +--- a/clang/lib/Sema/SemaDeclAttr.cpp ++++ b/clang/lib/Sema/SemaDeclAttr.cpp +@@ -7308,16 +7308,21 @@ static void handleOpenCLAccessAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + } + } + +- // OpenCL v2.0 s6.6 - read_write can be used for image types to specify that an +- // image object can be read and written. +- // OpenCL v2.0 s6.13.6 - A kernel cannot read from and write to the same pipe +- // object. Using the read_write (or __read_write) qualifier with the pipe +- // qualifier is a compilation error. ++ // OpenCL v2.0 s6.6 - read_write can be used for image types to specify that ++ // an image object can be read and written. OpenCL v2.0 s6.13.6 - A kernel ++ // cannot read from and write to the same pipe object. Using the read_write ++ // (or __read_write) qualifier with the pipe qualifier is a compilation error. ++ // OpenCL v3.0 s6.8 - For OpenCL C 2.0, or with the ++ // __opencl_c_read_write_images feature, image objects specified as arguments ++ // to a kernel can additionally be declared to be read-write. + if (const auto *PDecl = dyn_cast(D)) { + const Type *DeclTy = PDecl->getType().getCanonicalType().getTypePtr(); + if (AL.getAttrName()->getName().find("read_write") != StringRef::npos) { + if ((!S.getLangOpts().OpenCLCPlusPlus && +- S.getLangOpts().OpenCLVersion < 200) || ++ (S.getLangOpts().OpenCLVersion < 200) || ++ (S.getLangOpts().OpenCLVersion == 300 && ++ !S.getOpenCLOptions().isSupported("__opencl_c_read_write_images", ++ S.getLangOpts()))) || + DeclTy->isPipeType()) { + S.Diag(AL.getLoc(), diag::err_opencl_invalid_read_write) + << AL << PDecl->getType() << DeclTy->isImageType(); +diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp +index ae8508d6c601..cc29938c5ea5 100644 +--- a/clang/lib/Sema/SemaExpr.cpp ++++ b/clang/lib/Sema/SemaExpr.cpp +@@ -657,7 +657,8 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) { + return E; + + // OpenCL usually rejects direct accesses to values of 'half' type. +- if (getLangOpts().OpenCL && !getOpenCLOptions().isEnabled("cl_khr_fp16") && ++ if (getLangOpts().OpenCL && ++ !getOpenCLOptions().isAvailableOption("cl_khr_fp16", getLangOpts()) && + T->isHalfType()) { + Diag(E->getExprLoc(), diag::err_opencl_half_load_store) + << 0 << T; +@@ -829,10 +830,10 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) { + if (BTy && (BTy->getKind() == BuiltinType::Half || + BTy->getKind() == BuiltinType::Float)) { + if (getLangOpts().OpenCL && +- !getOpenCLOptions().isEnabled("cl_khr_fp64")) { +- if (BTy->getKind() == BuiltinType::Half) { +- E = ImpCastExprToType(E, Context.FloatTy, CK_FloatingCast).get(); +- } ++ !getOpenCLOptions().isAvailableOption("cl_khr_fp64", getLangOpts())) { ++ if (BTy->getKind() == BuiltinType::Half) { ++ E = ImpCastExprToType(E, Context.FloatTy, CK_FloatingCast).get(); ++ } + } else { + E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).get(); + } +@@ -3819,7 +3820,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { + } else if (Literal.isFloatingLiteral()) { + QualType Ty; + if (Literal.isHalf){ +- if (getOpenCLOptions().isEnabled("cl_khr_fp16")) ++ if (getOpenCLOptions().isAvailableOption("cl_khr_fp16", getLangOpts())) + Ty = Context.HalfTy; + else { + Diag(Tok.getLocation(), diag::err_half_const_requires_fp16); +@@ -3843,10 +3844,11 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { + if (Ty->castAs()->getKind() != BuiltinType::Float) { + Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get(); + } +- } else if (getLangOpts().OpenCL && +- !getOpenCLOptions().isEnabled("cl_khr_fp64")) { ++ } else if (getLangOpts().OpenCL && !getOpenCLOptions().isAvailableOption( ++ "cl_khr_fp64", getLangOpts())) { + // Impose single-precision float type when cl_khr_fp64 is not enabled. +- Diag(Tok.getLocation(), diag::warn_double_const_requires_fp64); ++ Diag(Tok.getLocation(), diag::warn_double_const_requires_fp64) ++ << (getLangOpts().OpenCLVersion >= 300); + Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get(); + } + } +@@ -6468,9 +6470,6 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc, + FD, /*Complain=*/true, Fn->getBeginLoc())) + return ExprError(); + +- if (getLangOpts().OpenCL && checkOpenCLDisabledDecl(*FD, *Fn)) +- return ExprError(); +- + checkDirectCallValidity(*this, Fn, FD, ArgExprs); + } + +@@ -12900,7 +12899,8 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, + // OpenCL v1.2 s6.1.1.1 p2: + // The half data type can only be used to declare a pointer to a buffer that + // contains half values +- if (getLangOpts().OpenCL && !getOpenCLOptions().isEnabled("cl_khr_fp16") && ++ if (getLangOpts().OpenCL && ++ !getOpenCLOptions().isAvailableOption("cl_khr_fp16", getLangOpts()) && + LHSType->isHalfType()) { + Diag(Loc, diag::err_opencl_half_load_store) << 1 + << LHSType.getUnqualifiedType(); +diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp +index f4493d84238d..0e4259bfce09 100644 +--- a/clang/lib/Sema/SemaInit.cpp ++++ b/clang/lib/Sema/SemaInit.cpp +@@ -5572,8 +5572,8 @@ static bool TryOCLZeroOpaqueTypeInitialization(Sema &S, + // We should allow zero initialization for all types defined in the + // cl_intel_device_side_avc_motion_estimation extension, except + // intel_sub_group_avc_mce_payload_t and intel_sub_group_avc_mce_result_t. +- if (S.getOpenCLOptions().isEnabled( +- "cl_intel_device_side_avc_motion_estimation") && ++ if (S.getOpenCLOptions().isAvailableOption( ++ "cl_intel_device_side_avc_motion_estimation", S.getLangOpts()) && + DestType->isOCLIntelSubgroupAVCType()) { + if (DestType->isOCLIntelSubgroupAVCMcePayloadType() || + DestType->isOCLIntelSubgroupAVCMceResultType()) +@@ -8758,8 +8758,8 @@ ExprResult InitializationSequence::Perform(Sema &S, + unsigned AddressingMode = (0x0E & SamplerValue) >> 1; + unsigned FilterMode = (0x30 & SamplerValue) >> 4; + if (FilterMode != 1 && FilterMode != 2 && +- !S.getOpenCLOptions().isEnabled( +- "cl_intel_device_side_avc_motion_estimation")) ++ !S.getOpenCLOptions().isAvailableOption( ++ "cl_intel_device_side_avc_motion_estimation", S.getLangOpts())) + S.Diag(Kind.getLocation(), + diag::warn_sampler_initializer_invalid_bits) + << "Filter Mode"; +diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp +index 29038ab9fe1c..12f58556c9dd 100644 +--- a/clang/lib/Sema/SemaLookup.cpp ++++ b/clang/lib/Sema/SemaLookup.cpp +@@ -743,18 +743,6 @@ static void GetOpenCLBuiltinFctOverloads( + } + } + +-/// Add extensions to the function declaration. +-/// \param S (in/out) The Sema instance. +-/// \param BIDecl (in) Description of the builtin. +-/// \param FDecl (in/out) FunctionDecl instance. +-static void AddOpenCLExtensions(Sema &S, const OpenCLBuiltinStruct &BIDecl, +- FunctionDecl *FDecl) { +- // Fetch extension associated with a function prototype. +- StringRef E = FunctionExtensionTable[BIDecl.Extension]; +- if (E != "") +- S.setOpenCLExtensionForDecl(FDecl, E); +-} +- + /// When trying to resolve a function name, if isOpenCLBuiltin() returns a + /// non-null pair, then the name is referencing an OpenCL + /// builtin function. Add all candidate signatures to the LookUpResult. +@@ -789,7 +777,13 @@ static void InsertOCLBuiltinDeclarationsFromTable(Sema &S, LookupResult &LR, + if ((OpenCLBuiltin.MaxVersion != 0) && + (OpenCLVersion >= OpenCLBuiltin.MaxVersion)) + continue; +- ++ ++ // Ignore this builtin function if it carries an extension macro that is ++ // not defined. This indicates that the extension is not supported by the ++ // target, so the builtin function should not be available. ++ StringRef Ext = FunctionExtensionTable[OpenCLBuiltin.Extension]; ++ if (!Ext.empty() && !S.getPreprocessor().isMacroDefined(Ext)) ++ continue; + SmallVector RetTypes; + SmallVector, 5> ArgTypes; + +@@ -843,8 +837,6 @@ static void InsertOCLBuiltinDeclarationsFromTable(Sema &S, LookupResult &LR, + if (!S.getLangOpts().OpenCLCPlusPlus) + NewOpenCLBuiltin->addAttr(OverloadableAttr::CreateImplicit(Context)); + +- AddOpenCLExtensions(S, OpenCLBuiltin, NewOpenCLBuiltin); +- + LR.addDecl(NewOpenCLBuiltin); + } + } +diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp +index 7fe7466725fa..05815bb6e38d 100644 +--- a/clang/lib/Sema/SemaOverload.cpp ++++ b/clang/lib/Sema/SemaOverload.cpp +@@ -6479,12 +6479,6 @@ void Sema::AddOverloadCandidate( + Candidate.DeductionFailure.Data = FailedAttr; + return; + } +- +- if (LangOpts.OpenCL && isOpenCLDisabledDecl(Function)) { +- Candidate.Viable = false; +- Candidate.FailureKind = ovl_fail_ext_disabled; +- return; +- } + } + + ObjCMethodDecl * +@@ -11092,14 +11086,6 @@ static void DiagnoseFailedExplicitSpec(Sema &S, OverloadCandidate *Cand) { + << (ES.getExpr() ? ES.getExpr()->getSourceRange() : SourceRange()); + } + +-static void DiagnoseOpenCLExtensionDisabled(Sema &S, OverloadCandidate *Cand) { +- FunctionDecl *Callee = Cand->Function; +- +- S.Diag(Callee->getLocation(), +- diag::note_ovl_candidate_disabled_by_extension) +- << S.getOpenCLExtensionsFromDeclExtMap(Callee); +-} +- + /// Generates a 'note' diagnostic for an overload candidate. We've + /// already generated a primary error at the call site. + /// +@@ -11195,9 +11181,6 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, + case ovl_fail_explicit: + return DiagnoseFailedExplicitSpec(S, Cand); + +- case ovl_fail_ext_disabled: +- return DiagnoseOpenCLExtensionDisabled(S, Cand); +- + case ovl_fail_inhctor_slice: + // It's generally not interesting to note copy/move constructors here. + if (cast(Fn)->isCopyOrMoveConstructor()) +diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp +index 4178024d1264..e44a25c6aead 100644 +--- a/clang/lib/Sema/SemaType.cpp ++++ b/clang/lib/Sema/SemaType.cpp +@@ -1548,6 +1548,16 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { + Result = Context.LongDoubleTy; + else + Result = Context.DoubleTy; ++ if (S.getLangOpts().OpenCL) { ++ if (!S.getOpenCLOptions().isSupported("cl_khr_fp64", S.getLangOpts())) ++ S.Diag(DS.getTypeSpecTypeLoc(), diag::err_opencl_requires_extension) ++ << 0 << Result ++ << (S.getLangOpts().OpenCLVersion == 300 ++ ? "cl_khr_fp64 and __opencl_c_fp64" ++ : "cl_khr_fp64"); ++ else if (!S.getOpenCLOptions().isAvailableOption("cl_khr_fp64", S.getLangOpts())) ++ S.Diag(DS.getTypeSpecTypeLoc(), diag::ext_opencl_double_without_pragma); ++ } + break; + case DeclSpec::TST_float128: + if (!S.Context.getTargetInfo().hasFloat128Type() && +@@ -1723,10 +1733,33 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { + if (Result->containsErrors()) + declarator.setInvalidType(); + +- if (S.getLangOpts().OpenCL && +- S.checkOpenCLDisabledTypeDeclSpec(DS, Result)) +- declarator.setInvalidType(true); +- ++ if (S.getLangOpts().OpenCL) { ++ const auto &OpenCLOptions = S.getOpenCLOptions(); ++ bool IsOpenCLC30 = (S.getLangOpts().OpenCLVersion == 300); ++ // OpenCL C v3.0 s6.3.3 - OpenCL image types require __opencl_c_images ++ // support. ++ // OpenCL C v3.0 s6.2.1 - OpenCL 3d image write types requires support ++ // for OpenCL C 2.0, or OpenCL C 3.0 or newer and the ++ // __opencl_c_3d_image_writes feature. OpenCL C v3.0 API s4.2 - For devices ++ // that support OpenCL 3.0, cl_khr_3d_image_writes must be returned when and ++ // only when the optional feature is supported ++ if ((Result->isImageType() || Result->isSamplerT()) && ++ (IsOpenCLC30 && ++ !OpenCLOptions.isSupported("__opencl_c_images", S.getLangOpts()))) { ++ S.Diag(DS.getTypeSpecTypeLoc(), diag::err_opencl_requires_extension) ++ << 0 << Result << "__opencl_c_images"; ++ declarator.setInvalidType(); ++ } else if (Result->isOCLImage3dWOType() && ++ !OpenCLOptions.isSupported("cl_khr_3d_image_writes", ++ S.getLangOpts())) { ++ S.Diag(DS.getTypeSpecTypeLoc(), diag::err_opencl_requires_extension) ++ << 0 << Result ++ << (IsOpenCLC30 ++ ? "cl_khr_3d_image_writes and __opencl_c_3d_image_writes" ++ : "cl_khr_3d_image_writes"); ++ declarator.setInvalidType(); ++ } ++ } + bool IsFixedPointType = DS.getTypeSpecType() == DeclSpec::TST_accum || + DS.getTypeSpecType() == DeclSpec::TST_fract; + +@@ -2060,8 +2093,7 @@ static QualType deduceOpenCLPointeeAddrSpace(Sema &S, QualType PointeeType) { + !PointeeType->isSamplerT() && + !PointeeType.hasAddressSpace()) + PointeeType = S.getASTContext().getAddrSpaceQualType( +- PointeeType, +- S.getLangOpts().OpenCLCPlusPlus || S.getLangOpts().OpenCLVersion == 200 ++ PointeeType, S.getLangOpts().OpenCLGenericAddressSpace + ? LangAS::opencl_generic + : LangAS::opencl_private); + return PointeeType; +@@ -2090,7 +2122,8 @@ QualType Sema::BuildPointerType(QualType T, + } + + if (T->isFunctionType() && getLangOpts().OpenCL && +- !getOpenCLOptions().isEnabled("__cl_clang_function_pointers")) { ++ !getOpenCLOptions().isAvailableOption("__cl_clang_function_pointers", ++ getLangOpts())) { + Diag(Loc, diag::err_opencl_function_pointer); + return QualType(); + } +@@ -4994,7 +5027,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, + // FIXME: This really should be in BuildFunctionType. + if (T->isHalfType()) { + if (S.getLangOpts().OpenCL) { +- if (!S.getOpenCLOptions().isEnabled("cl_khr_fp16")) { ++ if (!S.getOpenCLOptions().isAvailableOption("cl_khr_fp16", ++ S.getLangOpts())) { + S.Diag(D.getIdentifierLoc(), diag::err_opencl_invalid_return) + << T << 0 /*pointer hint*/; + D.setInvalidType(true); +@@ -5019,7 +5053,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, + // (s6.9.e and s6.12.5 OpenCL v2.0) except for printf. + // We also allow here any toolchain reserved identifiers. + if (FTI.isVariadic && +- !S.getOpenCLOptions().isEnabled("__cl_clang_variadic_functions") && ++ !S.getOpenCLOptions().isAvailableOption( ++ "__cl_clang_variadic_functions", S.getLangOpts()) && + !(D.getIdentifier() && + ((D.getIdentifier()->getName() == "printf" && + (LangOpts.OpenCLCPlusPlus || LangOpts.OpenCLVersion >= 120)) || +@@ -5214,7 +5249,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, + // Disallow half FP parameters. + // FIXME: This really should be in BuildFunctionType. + if (S.getLangOpts().OpenCL) { +- if (!S.getOpenCLOptions().isEnabled("cl_khr_fp16")) { ++ if (!S.getOpenCLOptions().isAvailableOption("cl_khr_fp16", ++ S.getLangOpts())) { + S.Diag(Param->getLocation(), diag::err_opencl_invalid_param) + << ParamTy << 0; + D.setInvalidType(); +diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp +index 1f68f6bc3e38..aa5eaf7fe2dc 100644 +--- a/clang/lib/Serialization/ASTReader.cpp ++++ b/clang/lib/Serialization/ASTReader.cpp +@@ -3611,36 +3611,13 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { + auto &OptInfo = OpenCLExtensions.OptMap[Name]; + OptInfo.Supported = Record[I++] != 0; + OptInfo.Enabled = Record[I++] != 0; ++ OptInfo.WithPragma = Record[I++] != 0; + OptInfo.Avail = Record[I++]; + OptInfo.Core = Record[I++]; + OptInfo.Opt = Record[I++]; + } + break; + +- case OPENCL_EXTENSION_TYPES: +- for (unsigned I = 0, E = Record.size(); I != E;) { +- auto TypeID = static_cast<::TypeID>(Record[I++]); +- auto *Type = GetType(TypeID).getTypePtr(); +- auto NumExt = static_cast(Record[I++]); +- for (unsigned II = 0; II != NumExt; ++II) { +- auto Ext = ReadString(Record, I); +- OpenCLTypeExtMap[Type].insert(Ext); +- } +- } +- break; +- +- case OPENCL_EXTENSION_DECLS: +- for (unsigned I = 0, E = Record.size(); I != E;) { +- auto DeclID = static_cast<::DeclID>(Record[I++]); +- auto *Decl = GetDecl(DeclID); +- auto NumExt = static_cast(Record[I++]); +- for (unsigned II = 0; II != NumExt; ++II) { +- auto Ext = ReadString(Record, I); +- OpenCLDeclExtMap[Decl].insert(Ext); +- } +- } +- break; +- + case TENTATIVE_DEFINITIONS: + for (unsigned I = 0, N = Record.size(); I != N; ++I) + TentativeDefinitions.push_back(getGlobalDeclID(F, Record[I])); +@@ -7869,8 +7846,6 @@ void ASTReader::InitializeSema(Sema &S) { + } + + SemaObj->OpenCLFeatures = OpenCLExtensions; +- SemaObj->OpenCLTypeExtMap = OpenCLTypeExtMap; +- SemaObj->OpenCLDeclExtMap = OpenCLDeclExtMap; + + UpdateSema(); + } +diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp +index 40900af6f9e0..d6e5269d24fd 100644 +--- a/clang/lib/Serialization/ASTWriter.cpp ++++ b/clang/lib/Serialization/ASTWriter.cpp +@@ -3976,6 +3976,7 @@ void ASTWriter::WriteOpenCLExtensions(Sema &SemaRef) { + auto V = I.getValue(); + Record.push_back(V.Supported ? 1 : 0); + Record.push_back(V.Enabled ? 1 : 0); ++ Record.push_back(V.WithPragma ? 1 : 0); + Record.push_back(V.Avail); + Record.push_back(V.Core); + Record.push_back(V.Opt); +@@ -3983,71 +3984,6 @@ void ASTWriter::WriteOpenCLExtensions(Sema &SemaRef) { + Stream.EmitRecord(OPENCL_EXTENSIONS, Record); + } + +-void ASTWriter::WriteOpenCLExtensionTypes(Sema &SemaRef) { +- if (!SemaRef.Context.getLangOpts().OpenCL) +- return; +- +- // Sort the elements of the map OpenCLTypeExtMap by TypeIDs, +- // without copying them. +- const llvm::DenseMap> &OpenCLTypeExtMap = +- SemaRef.OpenCLTypeExtMap; +- using ElementTy = std::pair *>; +- llvm::SmallVector StableOpenCLTypeExtMap; +- StableOpenCLTypeExtMap.reserve(OpenCLTypeExtMap.size()); +- +- for (const auto &I : OpenCLTypeExtMap) +- StableOpenCLTypeExtMap.emplace_back( +- getTypeID(I.first->getCanonicalTypeInternal()), &I.second); +- +- auto CompareByTypeID = [](const ElementTy &E1, const ElementTy &E2) -> bool { +- return E1.first < E2.first; +- }; +- llvm::sort(StableOpenCLTypeExtMap, CompareByTypeID); +- +- RecordData Record; +- for (const ElementTy &E : StableOpenCLTypeExtMap) { +- Record.push_back(E.first); // TypeID +- const std::set *ExtSet = E.second; +- Record.push_back(static_cast(ExtSet->size())); +- for (const std::string &Ext : *ExtSet) +- AddString(Ext, Record); +- } +- +- Stream.EmitRecord(OPENCL_EXTENSION_TYPES, Record); +-} +- +-void ASTWriter::WriteOpenCLExtensionDecls(Sema &SemaRef) { +- if (!SemaRef.Context.getLangOpts().OpenCL) +- return; +- +- // Sort the elements of the map OpenCLDeclExtMap by DeclIDs, +- // without copying them. +- const llvm::DenseMap> &OpenCLDeclExtMap = +- SemaRef.OpenCLDeclExtMap; +- using ElementTy = std::pair *>; +- llvm::SmallVector StableOpenCLDeclExtMap; +- StableOpenCLDeclExtMap.reserve(OpenCLDeclExtMap.size()); +- +- for (const auto &I : OpenCLDeclExtMap) +- StableOpenCLDeclExtMap.emplace_back(getDeclID(I.first), &I.second); +- +- auto CompareByDeclID = [](const ElementTy &E1, const ElementTy &E2) -> bool { +- return E1.first < E2.first; +- }; +- llvm::sort(StableOpenCLDeclExtMap, CompareByDeclID); +- +- RecordData Record; +- for (const ElementTy &E : StableOpenCLDeclExtMap) { +- Record.push_back(E.first); // DeclID +- const std::set *ExtSet = E.second; +- Record.push_back(static_cast(ExtSet->size())); +- for (const std::string &Ext : *ExtSet) +- AddString(Ext, Record); +- } +- +- Stream.EmitRecord(OPENCL_EXTENSION_DECLS, Record); +-} +- + void ASTWriter::WriteCUDAPragmas(Sema &SemaRef) { + if (SemaRef.ForceCUDAHostDeviceDepth > 0) { + RecordData::value_type Record[] = {SemaRef.ForceCUDAHostDeviceDepth}; +@@ -4792,17 +4728,12 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, + WriteIdentifierTable(PP, SemaRef.IdResolver, isModule); + WriteFPPragmaOptions(SemaRef.CurFPFeatureOverrides()); + WriteOpenCLExtensions(SemaRef); +- WriteOpenCLExtensionTypes(SemaRef); + WriteCUDAPragmas(SemaRef); + + // If we're emitting a module, write out the submodule information. + if (WritingModule) + WriteSubmodules(WritingModule); + +- // We need to have information about submodules to correctly deserialize +- // decls from OpenCLExtensionDecls block +- WriteOpenCLExtensionDecls(SemaRef); +- + Stream.EmitRecord(SPECIAL_TYPES, SpecialTypes); + + // Write the record containing external, unnamed definitions. +diff --git a/clang/test/CodeGenOpenCL/addr-space-struct-arg.cl b/clang/test/CodeGenOpenCL/addr-space-struct-arg.cl +index 21e0f2b05747..d24c9c5f85a4 100644 +--- a/clang/test/CodeGenOpenCL/addr-space-struct-arg.cl ++++ b/clang/test/CodeGenOpenCL/addr-space-struct-arg.cl +@@ -2,6 +2,8 @@ + // RUN: %clang_cc1 %s -emit-llvm -o - -O0 -triple amdgcn | FileCheck -enable-var-scope -check-prefixes=ALL,AMDGCN %s + // RUN: %clang_cc1 %s -emit-llvm -o - -cl-std=CL2.0 -O0 -triple amdgcn | FileCheck -enable-var-scope -check-prefixes=ALL,AMDGCN,AMDGCN20 %s + // RUN: %clang_cc1 %s -emit-llvm -o - -cl-std=CL1.2 -O0 -triple spir-unknown-unknown-unknown | FileCheck -enable-var-scope -check-prefixes=SPIR %s ++// RUN: %clang_cc1 %s -emit-llvm -o - -cl-std=CL3.0 -O0 -triple amdgcn -cl-ext=+__opencl_c_program_scope_global_variables | FileCheck -enable-var-scope -check-prefixes=ALL,AMDGCN,AMDGCN20 %s ++// RUN: %clang_cc1 %s -emit-llvm -o - -cl-std=CL3.0 -O0 -triple amdgcn | FileCheck -enable-var-scope -check-prefixes=ALL,AMDGCN %s + + typedef int int2 __attribute__((ext_vector_type(2))); + +@@ -39,7 +41,7 @@ struct LargeStructTwoMember { + int2 y[20]; + }; + +-#if __OPENCL_C_VERSION__ >= 200 ++#if (__OPENCL_C_VERSION__ == 200) || (__OPENCL_C_VERSION__ >= 300 && defined(__opencl_c_program_scope_global_variables)) + struct LargeStructOneMember g_s; + #endif + +@@ -98,7 +100,7 @@ void FuncOneLargeMember(struct LargeStructOneMember u) { + // AMDGCN20: %[[r0:.*]] = bitcast %struct.LargeStructOneMember addrspace(5)* %[[byval_temp]] to i8 addrspace(5)* + // AMDGCN20: call void @llvm.memcpy.p5i8.p1i8.i64(i8 addrspace(5)* align 8 %[[r0]], i8 addrspace(1)* align 8 bitcast (%struct.LargeStructOneMember addrspace(1)* @g_s to i8 addrspace(1)*), i64 800, i1 false) + // AMDGCN20: call void @FuncOneLargeMember(%struct.LargeStructOneMember addrspace(5)* byval(%struct.LargeStructOneMember) align 8 %[[byval_temp]]) +-#if __OPENCL_C_VERSION__ >= 200 ++#if (__OPENCL_C_VERSION__ == 200) || (__OPENCL_C_VERSION__ >= 300 && defined(__opencl_c_program_scope_global_variables)) + void test_indirect_arg_globl(void) { + FuncOneLargeMember(g_s); + } +diff --git a/clang/test/CodeGenOpenCL/address-spaces-conversions.cl b/clang/test/CodeGenOpenCL/address-spaces-conversions.cl +index cd3099e0a1a4..8fdb46184bed 100644 +--- a/clang/test/CodeGenOpenCL/address-spaces-conversions.cl ++++ b/clang/test/CodeGenOpenCL/address-spaces-conversions.cl +@@ -1,5 +1,7 @@ + // RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -O0 -ffake-address-space-map -cl-std=CL2.0 -emit-llvm -o - | FileCheck %s ++// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -O0 -ffake-address-space-map -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -emit-llvm -o - | FileCheck %s + // RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -O0 -cl-std=CL2.0 -emit-llvm -o - | FileCheck --check-prefix=CHECK-NOFAKE %s ++// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -O0 -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -emit-llvm -o - | FileCheck --check-prefix=CHECK-NOFAKE %s + // When -ffake-address-space-map is not used, all addr space mapped to 0 for x86_64. + + // test that we generate address space casts everywhere we need conversions of +diff --git a/clang/test/CodeGenOpenCL/address-spaces-mangling.cl b/clang/test/CodeGenOpenCL/address-spaces-mangling.cl +index 50622f099143..b46834c2a678 100644 +--- a/clang/test/CodeGenOpenCL/address-spaces-mangling.cl ++++ b/clang/test/CodeGenOpenCL/address-spaces-mangling.cl +@@ -2,10 +2,14 @@ + // RUN: %clang_cc1 %s -cl-std=CL2.0 -ffake-address-space-map -faddress-space-map-mangling=yes -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes="ASMANG,ASMANG20" %s + // RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes="NOASMANG,NOASMANG10" %s + // RUN: %clang_cc1 %s -cl-std=CL2.0 -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes="NOASMANG,NOASMANG20" %s ++// RUN: %clang_cc1 %s -cl-std=CL3.0 -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes="NOASMANG,NOASMANG20" %s ++// RUN: %clang_cc1 %s -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -ffake-address-space-map -faddress-space-map-mangling=yes -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes="ASMANG,ASMANG20" %s + + // We check that the address spaces are mangled the same in both version of OpenCL + // RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL2.0 -emit-llvm -o - | FileCheck -check-prefix=OCL-20 %s + // RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL1.2 -emit-llvm -o - | FileCheck -check-prefix=OCL-12 %s ++// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -emit-llvm -o - | FileCheck -check-prefix=OCL-20 %s ++// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL3.0 -cl-ext=-__opencl_c_generic_address_space -emit-llvm -o - | FileCheck -check-prefix=OCL-12 %s + + // We can't name this f as private is equivalent to default + // no specifier given address space so we get multiple definition +@@ -47,7 +51,7 @@ void f(constant int *arg) { } + // OCL-20-DAG: @_Z1fPU3AS2i + // OCL-12-DAG: @_Z1fPU3AS2i + +-#if __OPENCL_C_VERSION__ >= 200 ++#if (__OPENCL_C_VERSION__ == 200) || defined(__opencl_c_generic_address_space) + __attribute__((overloadable)) + void f(generic int *arg) { } + // ASMANG20: @_Z1fPU3AS4i +diff --git a/clang/test/CodeGenOpenCL/address-spaces.cl b/clang/test/CodeGenOpenCL/address-spaces.cl +index ebd227a6a9c7..be131c7820f9 100644 +--- a/clang/test/CodeGenOpenCL/address-spaces.cl ++++ b/clang/test/CodeGenOpenCL/address-spaces.cl +@@ -1,9 +1,13 @@ + // RUN: %clang_cc1 %s -O0 -ffake-address-space-map -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,SPIR ++// RUN: %clang_cc1 %s -O0 -cl-std=CL3.0 -cl-ext=-__opencl_c_generic_address_space -ffake-address-space-map -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,SPIR + // RUN: %clang_cc1 %s -O0 -DCL20 -cl-std=CL2.0 -ffake-address-space-map -emit-llvm -o - | FileCheck %s --check-prefixes=CL20,CL20SPIR + // RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -emit-llvm -o - | FileCheck --check-prefixes=CHECK,AMDGCN %s ++// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL3.0 -emit-llvm -o - | FileCheck --check-prefixes=CHECK,AMDGCN %s + // RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -DCL20 -cl-std=CL2.0 -emit-llvm -o - | FileCheck %s --check-prefixes=CL20,CL20AMDGCN + // RUN: %clang_cc1 %s -O0 -triple amdgcn-mesa-mesa3d -emit-llvm -o - | FileCheck --check-prefixes=CHECK,AMDGCN %s ++// RUN: %clang_cc1 %s -O0 -triple amdgcn-mesa-mesa3d -cl-std=CL3.0 -emit-llvm -o - | FileCheck --check-prefixes=CHECK,AMDGCN %s + // RUN: %clang_cc1 %s -O0 -triple r600-- -emit-llvm -o - | FileCheck --check-prefixes=CHECK,AMDGCN %s ++// RUN: %clang_cc1 %s -O0 -triple r600-- -emit-llvm -cl-std=CL3.0 -o - | FileCheck --check-prefixes=CHECK,AMDGCN %s + + // SPIR: %struct.S = type { i32, i32, i32* } + // CL20SPIR: %struct.S = type { i32, i32, i32 addrspace(4)* } +diff --git a/clang/test/CodeGenOpenCL/amdgpu-sizeof-alignof.cl b/clang/test/CodeGenOpenCL/amdgpu-sizeof-alignof.cl +index a5d438933fa4..3bd395da6d45 100644 +--- a/clang/test/CodeGenOpenCL/amdgpu-sizeof-alignof.cl ++++ b/clang/test/CodeGenOpenCL/amdgpu-sizeof-alignof.cl +@@ -5,6 +5,18 @@ + // RUN: %clang_cc1 -triple amdgcn---amdgizcl -cl-std=CL1.2 %s -emit-llvm -o - | FileCheck %s + // RUN: %clang_cc1 -triple amdgcn---amdgizcl -cl-std=CL2.0 %s -emit-llvm -o - | FileCheck %s + ++// RUN: %clang_cc1 -triple r600 -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s ++// RUN: %clang_cc1 -triple amdgcn-mesa-mesa3d -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s ++// RUN: %clang_cc1 -triple amdgcn---opencl -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s ++// RUN: %clang_cc1 -triple amdgcn---amdgizcl -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s ++// RUN: %clang_cc1 -triple amdgcn-mesa-mesa3d -cl-ext=+__opencl_c_generic_address_space -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s ++// RUN: %clang_cc1 -triple amdgcn---opencl -cl-ext=+__opencl_c_generic_address_space -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s ++// RUN: %clang_cc1 -triple amdgcn---amdgizcl -cl-ext=+__opencl_c_generic_address_space -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s ++// RUN: %clang_cc1 -triple r600 -cl-ext=+cl_khr_fp64,+__opencl_c_fp64 -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s ++// RUN: %clang_cc1 -triple amdgcn-mesa-mesa3d -cl-ext=+cl_khr_fp64,+__opencl_c_fp64 -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s ++// RUN: %clang_cc1 -triple amdgcn---opencl -cl-ext=+cl_khr_fp64,+__opencl_c_fp64 -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s ++// RUN: %clang_cc1 -triple amdgcn---amdgizcl -cl-ext=+cl_khr_fp64,+__opencl_c_fp64 -cl-std=CL3.0 %s -emit-llvm -o - | FileCheck %s ++ + #ifdef __AMDGCN__ + #define PTSIZE 8 + #else +@@ -58,9 +70,12 @@ void test() { + check(sizeof(double) == 8); + check(__alignof__(double) == 8); + #endif +- +- check(sizeof(void*) == (__OPENCL_C_VERSION__ >= 200 ? 8 : 4)); +- check(__alignof__(void*) == (__OPENCL_C_VERSION__ >= 200 ? 8 : 4)); ++ check(sizeof(private void*) == 4); ++ check(__alignof__(private void*) == 4); ++#if (__OPENCL_C_VERSION__ == 200) || defined(__opencl_c_generic_address_space) ++ check(sizeof(generic void*) == 8); ++ check(__alignof__(generic void*) == 8); ++#endif + check(sizeof(global_ptr_t) == PTSIZE); + check(__alignof__(global_ptr_t) == PTSIZE); + check(sizeof(constant_ptr_t) == PTSIZE); +diff --git a/clang/test/CodeGenOpenCL/arm-integer-dot-product.cl b/clang/test/CodeGenOpenCL/arm-integer-dot-product.cl +index d1ab6aceac5c..cc62d1df4275 100644 +--- a/clang/test/CodeGenOpenCL/arm-integer-dot-product.cl ++++ b/clang/test/CodeGenOpenCL/arm-integer-dot-product.cl +@@ -1,38 +1,39 @@ + // RUN: %clang_cc1 %s -triple spir-unknown-unknown -finclude-default-header -cl-std=CL1.2 -emit-llvm -o - -O0 | FileCheck %s + ++// Pragmas are only accepted for backward compatibility. ++ + #pragma OPENCL EXTENSION cl_arm_integer_dot_product_int8 : enable ++#pragma OPENCL EXTENSION cl_arm_integer_dot_product_int8 : disable + void test_int8(uchar4 ua, uchar4 ub, char4 sa, char4 sb) { + uint ur = arm_dot(ua, ub); + // CHECK: call spir_func i32 @_Z7arm_dotDv4_hS_ + int sr = arm_dot(sa, sb); + // CHECK: call spir_func i32 @_Z7arm_dotDv4_cS_ + } +-#pragma OPENCL EXTENSION cl_arm_integer_dot_product_int8 : disable + + #pragma OPENCL EXTENSION cl_arm_integer_dot_product_accumulate_int8 : enable ++#pragma OPENCL EXTENSION cl_arm_integer_dot_product_accumulate_int8 : disable + void test_accumulate_int8(uchar4 ua, uchar4 ub, uint uc, char4 sa, char4 sb, int c) { + uint ur = arm_dot_acc(ua, ub, uc); + // CHECK: call spir_func i32 @_Z11arm_dot_accDv4_hS_j + int sr = arm_dot_acc(sa, sb, c); + // CHECK: call spir_func i32 @_Z11arm_dot_accDv4_cS_i + } +-#pragma OPENCL EXTENSION cl_arm_integer_dot_product_accumulate_int8 : disable + + #pragma OPENCL EXTENSION cl_arm_integer_dot_product_accumulate_int16 : enable ++#pragma OPENCL EXTENSION cl_arm_integer_dot_product_accumulate_int16 : disable + void test_accumulate_int16(ushort2 ua, ushort2 ub, uint uc, short2 sa, short2 sb, int c) { + uint ur = arm_dot_acc(ua, ub, uc); + // CHECK: call spir_func i32 @_Z11arm_dot_accDv2_tS_j + int sr = arm_dot_acc(sa, sb, c); + // CHECK: call spir_func i32 @_Z11arm_dot_accDv2_sS_i + } +-#pragma OPENCL EXTENSION cl_arm_integer_dot_product_accumulate_int16 : disable + + #pragma OPENCL EXTENSION cl_arm_integer_dot_product_accumulate_saturate_int8 : enable ++#pragma OPENCL EXTENSION cl_arm_integer_dot_product_accumulate_saturate_int8 : disable + void test_accumulate_saturate_int8(uchar4 ua, uchar4 ub, uint uc, char4 sa, char4 sb, int c) { + uint ur = arm_dot_acc_sat(ua, ub, uc); + // CHECK: call spir_func i32 @_Z15arm_dot_acc_satDv4_hS_j + int sr = arm_dot_acc_sat(sa, sb, c); + // CHECK: call spir_func i32 @_Z15arm_dot_acc_satDv4_cS_i + } +-#pragma OPENCL EXTENSION cl_arm_integer_dot_product_accumulate_saturate_int8 : disable +- +diff --git a/clang/test/CodeGenOpenCL/extension-begin.cl b/clang/test/CodeGenOpenCL/extension-begin.cl +deleted file mode 100644 +index 89b4256b2b11..000000000000 +--- a/clang/test/CodeGenOpenCL/extension-begin.cl ++++ /dev/null +@@ -1,25 +0,0 @@ +-// RUN: %clang_cc1 %s -triple spir-unknown-unknown -emit-llvm -o - | FileCheck %s +- +-__attribute__((overloadable)) void f(int x); +- +-#pragma OPENCL EXTENSION my_ext : begin +- +-__attribute__((overloadable)) void f(long x); +- +-#pragma OPENCL EXTENSION my_ext : end +- +-#pragma OPENCL EXTENSION my_ext : enable +- +-//CHECK: define{{.*}} spir_func void @test_f1(i64 %x) +-//CHECK: call spir_func void @_Z1fl(i64 %{{.*}}) +-void test_f1(long x) { +- f(x); +-} +- +-#pragma OPENCL EXTENSION my_ext : disable +- +-//CHECK: define{{.*}} spir_func void @test_f2(i64 %x) +-//CHECK: call spir_func void @_Z1fi(i32 %{{.*}}) +-void test_f2(long x) { +- f(x); +-} +diff --git a/clang/test/CodeGenOpenCL/overload.cl b/clang/test/CodeGenOpenCL/overload.cl +index f182cb5fd2af..bc844595a59a 100644 +--- a/clang/test/CodeGenOpenCL/overload.cl ++++ b/clang/test/CodeGenOpenCL/overload.cl +@@ -1,4 +1,5 @@ + // RUN: %clang_cc1 -cl-std=CL2.0 -emit-llvm -o - -triple spir-unknown-unknown %s | FileCheck %s ++// RUN: %clang_cc1 -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -emit-llvm -o - -triple spir-unknown-unknown %s | FileCheck %s + + typedef short short4 __attribute__((ext_vector_type(4))); + +diff --git a/clang/test/CodeGenOpenCL/printf.cl b/clang/test/CodeGenOpenCL/printf.cl +index fc139d776db6..c68c43bcc286 100644 +--- a/clang/test/CodeGenOpenCL/printf.cl ++++ b/clang/test/CodeGenOpenCL/printf.cl +@@ -1,10 +1,12 @@ + // RUN: %clang_cc1 -cl-std=CL1.2 -cl-ext=-+cl_khr_fp64 -triple spir-unknown-unknown -disable-llvm-passes -emit-llvm -o - %s | FileCheck -check-prefixes=FP64,ALL %s + // RUN: %clang_cc1 -cl-std=CL1.2 -cl-ext=-cl_khr_fp64 -triple spir-unknown-unknown -disable-llvm-passes -emit-llvm -o - %s | FileCheck -check-prefixes=NOFP64,ALL %s ++// RUN: %clang_cc1 -cl-std=CL3.0 -cl-ext=+__opencl_c_fp64,+cl_khr_fp64 -triple spir-unknown-unknown -disable-llvm-passes -emit-llvm -o - %s | FileCheck -check-prefixes=FP64,ALL %s ++// RUN: %clang_cc1 -cl-std=CL3.0 -cl-ext=-__opencl_c_fp64,-cl_khr_fp64 -triple spir-unknown-unknown -disable-llvm-passes -emit-llvm -o - %s | FileCheck -check-prefixes=NOFP64,ALL %s + + typedef __attribute__((ext_vector_type(2))) float float2; + typedef __attribute__((ext_vector_type(2))) half half2; + +-#ifdef cl_khr_fp64 ++#if defined(cl_khr_fp64) || defined(__opencl_c_fp64) + typedef __attribute__((ext_vector_type(2))) double double2; + #endif + +@@ -28,7 +30,7 @@ kernel void test_printf_half2(half2 arg) { + printf("%v2hf", arg); + } + +-#ifdef cl_khr_fp64 ++#if defined(cl_khr_fp64) || defined(__opencl_c_fp64) + // FP64-LABEL: @test_printf_double2( + // FP64: call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([6 x i8], [6 x i8] addrspace(2)* @.str.2, i32 0, i32 0), <2 x double> %0) + kernel void test_printf_double2(double2 arg) { +diff --git a/clang/test/Headers/opencl-c-header.cl b/clang/test/Headers/opencl-c-header.cl +index 184eefd9f9c3..1c671acb174e 100644 +--- a/clang/test/Headers/opencl-c-header.cl ++++ b/clang/test/Headers/opencl-c-header.cl +@@ -253,4 +253,88 @@ global atomic_int z = ATOMIC_VAR_INIT(99); + + #endif //(defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200) + ++// OpenCL C features. ++#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ == 200) ++ ++#ifndef __opencl_c_pipes ++#error "Feature macro __opencl_c_pipes should be defined" ++#endif ++#ifndef __opencl_c_generic_address_space ++#error "Feature macro __opencl_c_generic_address_space should be defined" ++#endif ++#ifndef __opencl_c_work_group_collective_functions ++#error "Feature macro __opencl_c_work_group_collective_functions should be defined" ++#endif ++#ifndef __opencl_c_atomic_order_acq_rel ++#error "Feature macro __opencl_c_atomic_order_acq_rel should be defined" ++#endif ++#ifndef __opencl_c_atomic_order_seq_cst ++#error "Feature macro __opencl_c_atomic_order_seq_cst should be defined" ++#endif ++#ifndef __opencl_c_atomic_scope_device ++#error "Feature macro __opencl_c_atomic_scope_device should be defined" ++#endif ++#ifndef __opencl_c_atomic_scope_all_devices ++#error "Feature macro __opencl_c_atomic_scope_all_devices should be defined" ++#endif ++#ifndef __opencl_c_device_enqueue ++#error "Feature macro __opencl_c_device_enqueue should be defined" ++#endif ++#ifndef __opencl_c_read_write_images ++#error "Feature macro __opencl_c_read_write_images should be defined" ++#endif ++#ifndef __opencl_c_program_scope_global_variables ++#error "Feature macro __opencl_c_program_scope_global_variables should be defined" ++#endif ++#ifndef __opencl_c_images ++#error "Feature macro __opencl_c_images should be defined" ++#endif ++ ++#elif (__OPENCL_C_VERSION__ < 200) ++ ++#ifdef __opencl_c_pipes ++#error "Incorret feature macro __opencl_c_pipes define" ++#endif ++#ifdef __opencl_c_generic_address_space ++#error "Incorret feature macro __opencl_c_generic_address_space define" ++#endif ++#ifdef __opencl_c_work_group_collective_functions ++#error "Incorret feature macro __opencl_c_work_group_collective_functions define" ++#endif ++#ifdef __opencl_c_atomic_order_acq_rel ++#error "Incorret feature macro __opencl_c_atomic_order_acq_rel define" ++#endif ++#ifdef __opencl_c_atomic_order_seq_cst ++#error "Incorret feature macro __opencl_c_atomic_order_seq_cst define" ++#endif ++#ifdef __opencl_c_atomic_scope_device ++#error "Incorret feature macro __opencl_c_atomic_scope_device define" ++#endif ++#ifdef __opencl_c_atomic_scope_all_devices ++#error "Incorret feature macro __opencl_c_atomic_scope_all_devices define" ++#endif ++#ifdef __opencl_c_device_enqueue ++#error "Incorret feature macro __opencl_c_device_enqueue define" ++#endif ++#ifdef __opencl_c_read_write_images ++#error "Incorret feature macro __opencl_c_read_write_images define" ++#endif ++#ifdef __opencl_c_program_scope_global_variables ++#error "Incorret feature macro __opencl_c_program_scope_global_variables define" ++#endif ++#ifdef __opencl_c_images ++#error "Incorret feature macro __opencl_c_images define" ++#endif ++#ifdef __opencl_c_3d_image_writes ++#error "Incorret feature macro __opencl_c_3d_image_writes define" ++#endif ++#ifdef __opencl_c_fp64 ++#error "Incorret feature macro __opencl_c_fp64 define" ++#endif ++#ifdef __opencl_c_subgroups ++#error "Incorret feature macro __opencl_c_subgroups define" ++#endif ++ ++#endif //(defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ == 200) ++ + #endif // defined(__SPIR__) +diff --git a/clang/test/Misc/nvptx.unsupported_core.cl b/clang/test/Misc/nvptx.unsupported_core.cl +new file mode 100644 +index 000000000000..b56a4828914e +--- /dev/null ++++ b/clang/test/Misc/nvptx.unsupported_core.cl +@@ -0,0 +1,7 @@ ++// RUN: %clang_cc1 -cl-std=CL2.0 -triple nvptx-unknown-unknown -Wpedantic-core-features %s 2> %t ++// RUN: FileCheck --check-prefixes=CHECK-C < %t %s ++// RUN: %clang_cc1 -cl-std=CLC++ -triple nvptx-unknown-unknown -Wpedantic-core-features %s 2> %t ++// RUN: FileCheck --check-prefixes=CHECK-CPP < %t %s ++ ++// CHECK-C: cl_khr_3d_image_writes is a core feature in OpenCL C version 2.0 but not supported on this target ++// CHECK-CPP: cl_khr_3d_image_writes is a core feature in C++ for OpenCL version 1.0 but not supported on this target +diff --git a/clang/test/Misc/warning-flags.c b/clang/test/Misc/warning-flags.c +index 54e36e1e0884..e4f9069b88c8 100644 +--- a/clang/test/Misc/warning-flags.c ++++ b/clang/test/Misc/warning-flags.c +@@ -91,4 +91,4 @@ CHECK-NEXT: warn_weak_import + + The list of warnings in -Wpedantic should NEVER grow. + +-CHECK: Number in -Wpedantic (not covered by other -W flags): 26 ++CHECK: Number in -Wpedantic (not covered by other -W flags): 27 +diff --git a/clang/test/Parser/opencl-atomics-cl20.cl b/clang/test/Parser/opencl-atomics-cl20.cl +index 844902e847f7..c3f86b6a44c4 100644 +--- a/clang/test/Parser/opencl-atomics-cl20.cl ++++ b/clang/test/Parser/opencl-atomics-cl20.cl +@@ -1,66 +1,78 @@ + // RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only +-// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -fsyntax-only -cl-std=CL2.0 -DCL20 +-// RUN: %clang_cc1 %s -triple spir64-unknown-unknown -verify -fsyntax-only -cl-std=CL2.0 -DCL20 +-// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -fsyntax-only -cl-std=CL2.0 -DCL20 -DEXT -Wpedantic-core-features ++// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -fsyntax-only -cl-std=CL2.0 -cl-ext=-cl_khr_int64_base_atomics ++// RUN: %clang_cc1 %s -triple spir64-unknown-unknown -verify -fsyntax-only -cl-std=CL2.0 ++// RUN: %clang_cc1 %s -triple spir64-unknown-unknown -verify -fsyntax-only -cl-std=CLC++ ++// RUN: %clang_cc1 %s -triple spir64-unknown-unknown -verify -fsyntax-only -cl-std=CL2.0 -cl-ext=-cl_khr_int64_base_atomics + +-#ifdef EXT +-#pragma OPENCL EXTENSION cl_khr_int64_base_atomics:enable +-#pragma OPENCL EXTENSION cl_khr_int64_extended_atomics:enable +-#pragma OPENCL EXTENSION cl_khr_fp64:enable +-#if __OPENCL_C_VERSION__ >= CL_VERSION_1_2 +-// expected-warning@-2{{OpenCL extension 'cl_khr_fp64' is core feature or supported optional core feature - ignoring}} +-#endif ++#if defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= CL_VERSION_1_2 ++#define LANG_VER_OK + #endif + + void atomic_types_test() { + // OpenCL v2.0 s6.13.11.6 defines supported atomic types. ++ ++// Non-optional types + atomic_int i; + atomic_uint ui; ++ atomic_float f; ++ atomic_flag fl; ++#if !defined(LANG_VER_OK) ++// expected-error@-5 {{use of undeclared identifier 'atomic_int'}} ++// expected-error@-5 {{use of undeclared identifier 'atomic_uint'}} ++// expected-error@-5 {{use of undeclared identifier 'atomic_float'}} ++// expected-error@-5 {{use of undeclared identifier 'atomic_flag'}} ++#endif ++ ++// Optional types + atomic_long l; + atomic_ulong ul; +- atomic_float f; + atomic_double d; +- atomic_flag fl; ++ atomic_size_t s; + atomic_intptr_t ip; + atomic_uintptr_t uip; +- atomic_size_t s; + atomic_ptrdiff_t pd; +-// OpenCL v2.0 s6.13.11.8, _Atomic type specifier and _Atomic type qualifier +-// are not supported by OpenCL. +- _Atomic int i; // expected-error {{use of undeclared identifier '_Atomic'}} +-} +-#ifndef CL20 +-// expected-error@-16 {{use of undeclared identifier 'atomic_int'}} +-// expected-error@-16 {{use of undeclared identifier 'atomic_uint'}} +-// expected-error@-16 {{use of undeclared identifier 'atomic_long'}} +-// expected-error@-16 {{use of undeclared identifier 'atomic_ulong'}} +-// expected-error@-16 {{use of undeclared identifier 'atomic_float'}} +-// expected-error@-16 {{use of undeclared identifier 'atomic_double'}} +-// expected-error@-16 {{use of undeclared identifier 'atomic_flag'}} +-// expected-error@-16 {{use of undeclared identifier 'atomic_intptr_t'}} +-// expected-error@-16 {{use of undeclared identifier 'atomic_uintptr_t'}} +-// expected-error@-16 {{use of undeclared identifier 'atomic_size_t'}} ++// Optional type identifiers are not added in earlier version or if at least ++// one of the extensions is not supported. Here we check with ++// `cl_khr_int64_base_atomics` only. ++#if !defined(LANG_VER_OK) || !defined(cl_khr_int64_base_atomics) ++// expected-error@-11 {{use of undeclared identifier 'atomic_long'}} ++// expected-error@-11 {{use of undeclared identifier 'atomic_ulong'}} ++// expected-error@-11 {{use of undeclared identifier 'atomic_double'}} ++#if defined(LANG_VER_OK) ++// expected-error@-15 {{expected ';' after expression}} ++// expected-error@-16 {{use of undeclared identifier 'l'}} ++// expected-error@-16 {{expected ';' after expression}} ++// expected-error@-17 {{use of undeclared identifier 'ul'}} ++#endif ++#if !defined(LANG_VER_OK) || defined(__SPIR64__) ++// expected-error@-18 {{use of undeclared identifier 'atomic_size_t'}} + // expected-error@-16 {{use of undeclared identifier 'atomic_ptrdiff_t'}} +-#elif !EXT +-// expected-error@-26 {{use of type 'atomic_long' (aka '_Atomic(long)') requires cl_khr_int64_base_atomics extension to be enabled}} +-// expected-error@-27 {{use of type 'atomic_long' (aka '_Atomic(long)') requires cl_khr_int64_extended_atomics extension to be enabled}} +-// expected-error@-27 {{use of type 'atomic_ulong' (aka '_Atomic(unsigned long)') requires cl_khr_int64_base_atomics extension to be enabled}} +-// expected-error@-28 {{use of type 'atomic_ulong' (aka '_Atomic(unsigned long)') requires cl_khr_int64_extended_atomics extension to be enabled}} +-// expected-error@-27 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_base_atomics extension to be enabled}} +-// expected-error@-28 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_extended_atomics extension to be enabled}} +-#if __LP64__ +-// expected-error-re@-28 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} +-// expected-error-re@-29 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} +-// expected-error-re@-29 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} +-// expected-error-re@-30 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} +-// expected-error-re@-30 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} +-// expected-error-re@-31 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} +-// expected-error-re@-31 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} +-// expected-error-re@-32 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} ++#if !defined(LANG_VER_OK) ++// expected-error@-20 {{use of undeclared identifier 'atomic_intptr_t'}} ++// expected-error@-20 {{use of undeclared identifier 'atomic_uintptr_t'}} ++#else ++// expected-error@-24 {{expected ';' after expression}} ++// expected-error@-25 {{use of undeclared identifier 's'}} ++// expected-error@-25 {{unknown type name 'atomic_intptr_t'; did you mean 'atomic_int'?}} ++// expected-note@* {{'atomic_int' declared here}} ++// expected-error@-26 {{unknown type name 'atomic_uintptr_t'; did you mean 'atomic_uint'?}} ++// expected-note@* {{'atomic_uint' declared here}} ++#endif + #endif + #endif + +-#ifdef CL20 ++// OpenCL v2.0 s6.13.11.8, _Atomic type specifier and _Atomic type qualifier ++// are not supported by OpenCL. ++ _Atomic int i; ++#ifdef __OPENCL_C_VERSION__ ++// expected-error@-2 {{use of undeclared identifier '_Atomic'}} ++#else ++ // expected-error@-4 {{unknown type name '_Atomic'}} ++#endif ++} ++ ++#if defined(LANG_VER_OK) ++int atomic_uint; //expected-error{{redefinition of 'atomic_uint' as different kind of symbol}} + void foo(atomic_int * ptr) {} + void atomic_ops_test() { + atomic_int i; +@@ -71,4 +83,6 @@ void atomic_ops_test() { + i += 1; // expected-error {{invalid operands to binary expression ('__private atomic_int' (aka '__private _Atomic(int)') and 'int')}} + i = i + i; // expected-error {{invalid operands to binary expression ('__private atomic_int' (aka '__private _Atomic(int)') and '__private atomic_int')}} + } ++#else ++__constant int atomic_uint = 1; + #endif +diff --git a/clang/test/SemaOpenCL/access-qualifier.cl b/clang/test/SemaOpenCL/access-qualifier.cl +index a5e1b65daf70..c538e73253ce 100644 +--- a/clang/test/SemaOpenCL/access-qualifier.cl ++++ b/clang/test/SemaOpenCL/access-qualifier.cl +@@ -1,12 +1,14 @@ +-// RUN: %clang_cc1 -verify -pedantic -fsyntax-only -cl-std=CL1.2 %s +-// RUN: %clang_cc1 -verify -pedantic -fsyntax-only -cl-std=CL2.0 %s ++// RUN: %clang_cc1 -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL1.2 %s -cl-ext=-cl_khr_3d_image_writes ++// RUN: %clang_cc1 -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL2.0 %s ++// RUN: %clang_cc1 -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL3.0 %s ++// RUN: %clang_cc1 -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL3.0 %s -cl-ext=-__opencl_c_read_write_images + + typedef image1d_t img1d_ro_default; // expected-note {{previously declared 'read_only' here}} + + typedef write_only image1d_t img1d_wo; // expected-note {{previously declared 'write_only' here}} + typedef read_only image1d_t img1d_ro; + +-#if __OPENCL_C_VERSION__ >= 200 ++#if (__OPENCL_C_VERSION__ == 200) || (__OPENCL_C_VERSION__ == 300 && defined(__opencl_c_read_write_images)) + typedef read_write image1d_t img1d_rw; + #endif + +@@ -17,10 +19,10 @@ typedef read_only int IntRO; // expected-error {{access qualifier can only be us + void myWrite(write_only image1d_t); // expected-note {{passing argument to parameter here}} expected-note {{passing argument to parameter here}} + void myRead(read_only image1d_t); // expected-note {{passing argument to parameter here}} + +-#if __OPENCL_C_VERSION__ >= 200 ++#if (__OPENCL_C_VERSION__ == 200) || (__OPENCL_C_VERSION__ == 300 && defined(__opencl_c_read_write_images)) + void myReadWrite(read_write image1d_t); + #else +-void myReadWrite(read_write image1d_t); // expected-error {{access qualifier 'read_write' can not be used for '__read_write image1d_t' prior to OpenCL version 2.0}} ++void myReadWrite(read_write image1d_t); // expected-error {{access qualifier 'read_write' can not be used for '__read_write image1d_t' prior to OpenCL C version 2.0 or in version 3.0 and without __opencl_c_read_write_images feature}} + #endif + + +@@ -36,7 +38,7 @@ kernel void k3(img1d_wo img) { + myWrite(img); + } + +-#if __OPENCL_C_VERSION__ >= 200 ++#if (__OPENCL_C_VERSION__ == 200) || (__OPENCL_C_VERSION__ == 300 && defined(__opencl_c_read_write_images)) + kernel void k4(img1d_rw img) { + myReadWrite(img); + } +@@ -62,26 +64,26 @@ kernel void k11(read_only write_only image1d_t i){} // expected-error{{multiple + + kernel void k12(read_only read_only image1d_t i){} // expected-warning {{duplicate 'read_only' declaration specifier}} + +-#if __OPENCL_C_VERSION__ >= 200 ++#if (__OPENCL_C_VERSION__ == 200) || (__OPENCL_C_VERSION__ == 300 && defined(__opencl_c_read_write_images)) + kernel void k13(read_write pipe int i){} // expected-error{{access qualifier 'read_write' can not be used for 'read_only pipe int'}} + #else +-kernel void k13(__read_write image1d_t i){} // expected-error{{access qualifier '__read_write' can not be used for '__read_write image1d_t' prior to OpenCL version 2.0}} +-#endif +- +-#if __OPENCL_C_VERSION__ >= 200 +-void myPipeWrite(write_only pipe int); // expected-note {{passing argument to parameter here}} +-kernel void k14(read_only pipe int p) { +- myPipeWrite(p); // expected-error {{passing '__private read_only pipe int' to parameter of incompatible type 'write_only pipe int'}} +-} ++kernel void k13(__read_write image1d_t i){} // expected-error{{access qualifier '__read_write' can not be used for '__read_write image1d_t' prior to OpenCL C version 2.0 or in version 3.0 and without __opencl_c_read_write_images feature}} + #endif + + #if __OPENCL_C_VERSION__ < 200 +-kernel void test_image3d_wo(write_only image3d_t img) {} // expected-error {{use of type '__write_only image3d_t' requires cl_khr_3d_image_writes extension to be enabled}} ++kernel void test_image3d_wo(write_only image3d_t img) {} // expected-error {{use of type '__write_only image3d_t' requires cl_khr_3d_image_writes support}} + #endif + +-#if __OPENCL_C_VERSION__ >= 200 ++#if (__OPENCL_C_VERSION__ == 200) || (__OPENCL_C_VERSION__ == 300 && defined(__opencl_c_read_write_images)) + kernel void read_write_twice_typedef(read_write img1d_rw i){} // expected-warning {{duplicate 'read_write' declaration specifier}} +-// expected-note@-74 {{previously declared 'read_write' here}} ++// expected-note@-67 {{previously declared 'read_write' here}} ++#endif ++ ++#if OPENCL_C_VERSION__ >= 200 ++void myPipeWrite(write_only pipe int); // expected-note {{passing argument to parameter here}} ++kernel void k14(read_only pipe int p) { ++ myPipeWrite(p); // expected-error {{passing '__private read_only pipe int' to parameter of incompatible type 'write_only pipe int'}} ++} + + kernel void pipe_ro_twice(read_only read_only pipe int i){} // expected-warning{{duplicate 'read_only' declaration specifier}} + // Conflicting access qualifiers +@@ -94,7 +96,7 @@ kernel void pipe_ro_twice_typedef(read_only ROPipeInt i){} // expected-warning{{ + + kernel void pass_ro_typedef_to_wo(ROPipeInt p) { + myPipeWrite(p); // expected-error {{passing '__private ROPipeInt' (aka '__private read_only pipe int') to parameter of incompatible type 'write_only pipe int'}} +- // expected-note@-25 {{passing argument to parameter here}} ++ // expected-note@-16 {{passing argument to parameter here}} + } + #endif + +diff --git a/clang/test/SemaOpenCL/address-spaces-conversions-cl2.0.cl b/clang/test/SemaOpenCL/address-spaces-conversions-cl2.0.cl +index a5a838241347..daedce8459aa 100644 +--- a/clang/test/SemaOpenCL/address-spaces-conversions-cl2.0.cl ++++ b/clang/test/SemaOpenCL/address-spaces-conversions-cl2.0.cl +@@ -4,6 +4,9 @@ + // RUN: %clang_cc1 %s -ffake-address-space-map -verify -pedantic -fsyntax-only -DCONSTANT -cl-std=clc++ + // RUN: %clang_cc1 %s -ffake-address-space-map -verify -pedantic -fsyntax-only -DGLOBAL -cl-std=clc++ + // RUN: %clang_cc1 %s -ffake-address-space-map -verify -pedantic -fsyntax-only -DGENERIC -cl-std=clc++ ++// RUN: %clang_cc1 %s -ffake-address-space-map -verify -pedantic -fsyntax-only -DCONSTANT -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space ++// RUN: %clang_cc1 %s -ffake-address-space-map -verify -pedantic -fsyntax-only -DGLOBAL -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space ++// RUN: %clang_cc1 %s -ffake-address-space-map -verify -pedantic -fsyntax-only -DGENERIC -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space + + /* OpenCLC v2.0 adds a set of restrictions for conversions between pointers to + * different address spaces, mainly described in Sections 6.5.5 and 6.5.6. +diff --git a/clang/test/SemaOpenCL/address-spaces.cl b/clang/test/SemaOpenCL/address-spaces.cl +index 2c4f0fdec524..98b9a39e78ea 100644 +--- a/clang/test/SemaOpenCL/address-spaces.cl ++++ b/clang/test/SemaOpenCL/address-spaces.cl +@@ -1,5 +1,6 @@ + // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only + // RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -pedantic -fsyntax-only ++// RUN: %clang_cc1 %s -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -verify -pedantic -fsyntax-only + // RUN: %clang_cc1 %s -cl-std=clc++ -verify -pedantic -fsyntax-only + + __constant int ci = 1; +diff --git a/clang/test/SemaOpenCL/arm-integer-dot-product.cl b/clang/test/SemaOpenCL/arm-integer-dot-product.cl +index d7219d7402a9..5552f7777954 100644 +--- a/clang/test/SemaOpenCL/arm-integer-dot-product.cl ++++ b/clang/test/SemaOpenCL/arm-integer-dot-product.cl +@@ -1,4 +1,4 @@ +-// RUN: %clang_cc1 %s -triple spir-unknown-unknown -finclude-default-header -verify -cl-std=CL1.2 -emit-llvm -o - -O0 ++// RUN: %clang_cc1 %s -triple spir-unknown-unknown -finclude-default-header -fdeclare-opencl-builtins -verify -cl-std=CL1.2 -emit-llvm -o - -cl-ext=-all + + void test_negative() { + uchar4 ua8, ub8; +@@ -7,37 +7,13 @@ void test_negative() { + short2 sa16, sb16; + uint ur; + int sr; +- ur = arm_dot(ua8, ub8); // expected-error{{no matching function for call to 'arm_dot'}} +- // expected-note@opencl-c.h:* {{candidate function not viable}} +- // expected-note@opencl-c.h:* {{candidate unavailable as it requires OpenCL extension 'cl_arm_integer_dot_product_int8' to be enabled}} +- sr = arm_dot(sa8, sb8); // expected-error{{no matching function for call to 'arm_dot'}} +- // expected-note@opencl-c.h:* {{candidate function not viable}} +- // expected-note@opencl-c.h:* {{candidate unavailable as it requires OpenCL extension 'cl_arm_integer_dot_product_int8' to be enabled}} +- ur = arm_dot_acc(ua8, ub8, ur); // expected-error{{no matching function for call to 'arm_dot_acc'}} +- // expected-note@opencl-c.h:* {{candidate function not viable}} +- // expected-note@opencl-c.h:* {{candidate function not viable}} +- // expected-note@opencl-c.h:* {{candidate function not viable}} +- // expected-note@opencl-c.h:* {{candidate unavailable as it requires OpenCL extension 'cl_arm_integer_dot_product_accumulate_int8' to be enabled}} +- sr = arm_dot_acc(sa8, sb8, sr); // expected-error{{no matching function for call to 'arm_dot_acc'}} +- // expected-note@opencl-c.h:* {{candidate function not viable}} +- // expected-note@opencl-c.h:* {{candidate function not viable}} +- // expected-note@opencl-c.h:* {{candidate function not viable}} +- // expected-note@opencl-c.h:* {{candidate unavailable as it requires OpenCL extension 'cl_arm_integer_dot_product_accumulate_int8' to be enabled}} +- ur = arm_dot_acc(ua16, ub16, ur); // expected-error{{no matching function for call to 'arm_dot_acc'}} +- // expected-note@opencl-c.h:* {{candidate function not viable}} +- // expected-note@opencl-c.h:* {{candidate function not viable}} +- // expected-note@opencl-c.h:* {{candidate function not viable}} +- // expected-note@opencl-c.h:* {{candidate unavailable as it requires OpenCL extension 'cl_arm_integer_dot_product_accumulate_int16' to be enabled}} +- sr = arm_dot_acc(sa16, sb16, sr); // expected-error{{no matching function for call to 'arm_dot_acc'}} +- // expected-note@opencl-c.h:* {{candidate function not viable}} +- // expected-note@opencl-c.h:* {{candidate function not viable}} +- // expected-note@opencl-c.h:* {{candidate function not viable}} +- // expected-note@opencl-c.h:* {{candidate unavailable as it requires OpenCL extension 'cl_arm_integer_dot_product_accumulate_int16' to be enabled}} +- ur = arm_dot_acc_sat(ua8, ub8, ur); // expected-error{{no matching function for call to 'arm_dot_acc_sat'}} +- // expected-note@opencl-c.h:* {{candidate function not viable}} +- // expected-note@opencl-c.h:* {{candidate unavailable as it requires OpenCL extension 'cl_arm_integer_dot_product_accumulate_saturate_int8' to be enabled}} +- sr = arm_dot_acc_sat(sa8, sb8, sr); // expected-error{{no matching function for call to 'arm_dot_acc_sat'}} +- // expected-note@opencl-c.h:* {{candidate function not viable}} +- // expected-note@opencl-c.h:* {{candidate unavailable as it requires OpenCL extension 'cl_arm_integer_dot_product_accumulate_saturate_int8' to be enabled}} ++ ur = arm_dot(ua8, ub8); // expected-error{{implicit declaration of function 'arm_dot' is invalid in OpenCL}} ++ sr = arm_dot(sa8, sb8); ++ ur = arm_dot_acc(ua8, ub8, ur); // expected-error{{implicit declaration of function 'arm_dot_acc' is invalid in OpenCL}} //expected-note{{'arm_dot_acc' declared here}} ++ sr = arm_dot_acc(sa8, sb8, sr); ++ ur = arm_dot_acc(ua16, ub16, ur); ++ sr = arm_dot_acc(sa16, sb16, sr); ++ ur = arm_dot_acc_sat(ua8, ub8, ur); // expected-error{{implicit declaration of function 'arm_dot_acc_sat' is invalid in OpenCL}} //expected-note{{did you mean 'arm_dot_acc'?}} ++ sr = arm_dot_acc_sat(sa8, sb8, sr); + } + +diff --git a/clang/test/SemaOpenCL/cl20-device-side-enqueue.cl b/clang/test/SemaOpenCL/cl20-device-side-enqueue.cl +index f63e2913c749..d25a03504c03 100644 +--- a/clang/test/SemaOpenCL/cl20-device-side-enqueue.cl ++++ b/clang/test/SemaOpenCL/cl20-device-side-enqueue.cl +@@ -235,11 +235,11 @@ kernel void bar(global unsigned int *buf) + kernel void foo1(global unsigned int *buf) + { + ndrange_t n; +- buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, ^(){}); // expected-error {{use of declaration 'get_kernel_max_sub_group_size_for_ndrange' requires cl_khr_subgroups extension to be enabled}} ++ buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, ^(){}); // expected-error {{use of declaration 'get_kernel_max_sub_group_size_for_ndrange' requires cl_khr_subgroups support}} + } + + kernel void bar1(global unsigned int *buf) + { + ndrange_t n; +- buf[0] = get_kernel_sub_group_count_for_ndrange(n, ^(){}); // expected-error {{use of declaration 'get_kernel_sub_group_count_for_ndrange' requires cl_khr_subgroups extension to be enabled}} ++ buf[0] = get_kernel_sub_group_count_for_ndrange(n, ^(){}); // expected-error {{use of declaration 'get_kernel_sub_group_count_for_ndrange' requires cl_khr_subgroups support}} + } +diff --git a/clang/test/SemaOpenCL/extension-begin.cl b/clang/test/SemaOpenCL/extension-begin.cl +index fdb481f8e092..9124ceba4e2a 100644 +--- a/clang/test/SemaOpenCL/extension-begin.cl ++++ b/clang/test/SemaOpenCL/extension-begin.cl +@@ -29,25 +29,23 @@ + #ifndef USE_PCH + // expected-warning@extension-begin.h:4 {{expected 'disable' - ignoring}} + // expected-warning@extension-begin.h:5 {{expected 'disable' - ignoring}} +-// expected-warning@extension-begin.h:21 {{OpenCL extension end directive mismatches begin directive - ignoring}} + #endif // USE_PCH + ++#if defined(IMPLICIT_INCLUDE) && defined(USE_PCH) ++//expected-no-diagnostics ++#endif ++ ++// Tests that the pragmas are accepted for backward compatibility. + #pragma OPENCL EXTENSION my_ext : enable +-void test_f1(void) { ++#pragma OPENCL EXTENSION my_ext : disable ++ ++#ifndef my_ext ++#error "Missing my_ext macro" ++#endif ++ ++// When extension is supported its functionality can be used freely. ++void test(void) { + struct A test_A1; + f(); + g(0); + } +- +-#pragma OPENCL EXTENSION my_ext : disable +-void test_f2(void) { +- struct A test_A2; // expected-error {{use of type 'struct A' requires my_ext extension to be enabled}} +- const struct A test_A_local; // expected-error {{use of type 'struct A' requires my_ext extension to be enabled}} +- TypedefOfA test_typedef_A; // expected-error {{use of type 'TypedefOfA' (aka 'struct A') requires my_ext extension to be enabled}} +- PointerOfA test_A_pointer; // expected-error {{use of type 'PointerOfA' (aka 'const __private struct A *') requires my_ext extension to be enabled}} +- f(); // expected-error {{use of declaration 'f' requires my_ext extension to be enabled}} +- g(0); // expected-error {{no matching function for call to 'g'}} +- // expected-note@extension-begin.h:18 {{candidate unavailable as it requires OpenCL extension 'my_ext' to be enabled}} +- // expected-note@extension-begin.h:23 {{candidate function not viable: requires 0 arguments, but 1 was provided}} +-} +- +diff --git a/clang/test/SemaOpenCL/extension-begin.h b/clang/test/SemaOpenCL/extension-begin.h +index d9865ba0b33a..0e262e4adb93 100644 +--- a/clang/test/SemaOpenCL/extension-begin.h ++++ b/clang/test/SemaOpenCL/extension-begin.h +@@ -5,10 +5,13 @@ + #pragma OPENCL EXTENSION all : end + + #pragma OPENCL EXTENSION my_ext : begin +- + struct A { + int a; + }; ++#pragma OPENCL EXTENSION my_ext : end ++#pragma OPENCL EXTENSION my_ext : end ++ ++#define my_ext + + typedef struct A TypedefOfA; + typedef const __private TypedefOfA* PointerOfA; +@@ -17,10 +20,8 @@ void f(void); + + __attribute__((overloadable)) void g(long x); + +-#pragma OPENCL EXTENSION my_ext : end +-#pragma OPENCL EXTENSION my_ext : end ++ + + __attribute__((overloadable)) void g(void); + + #endif // INCLUDED +- +diff --git a/clang/test/SemaOpenCL/extension-version.cl b/clang/test/SemaOpenCL/extension-version.cl +index b997a00145ef..6f26a23c4192 100644 +--- a/clang/test/SemaOpenCL/extension-version.cl ++++ b/clang/test/SemaOpenCL/extension-version.cl +@@ -3,15 +3,13 @@ + // RUN: %clang_cc1 -x cl -cl-std=CL1.2 %s -verify -triple spir-unknown-unknown + // RUN: %clang_cc1 -x cl -cl-std=CL2.0 %s -verify -triple spir-unknown-unknown + // RUN: %clang_cc1 -x cl -cl-std=clc++ %s -verify -triple spir-unknown-unknown ++// RUN: %clang_cc1 -x cl -cl-std=CL3.0 %s -verify -triple spir-unknown-unknown + // RUN: %clang_cc1 -x cl -cl-std=CL %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES + // RUN: %clang_cc1 -x cl -cl-std=CL1.1 %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES + // RUN: %clang_cc1 -x cl -cl-std=CL1.2 %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES + // RUN: %clang_cc1 -x cl -cl-std=CL2.0 %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES + // RUN: %clang_cc1 -x cl -cl-std=clc++ %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES +- +-#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200) && !defined(TEST_CORE_FEATURES) +-// expected-no-diagnostics +-#endif ++// RUN: %clang_cc1 -x cl -cl-std=CL3.0 %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES + + // Extensions in all versions + #ifndef cl_clang_storage_class_specifiers +@@ -95,12 +93,12 @@ + // expected-warning@-2{{OpenCL extension 'cl_khr_fp64' is core feature or supported optional core feature - ignoring}} + #endif + +-//Core feature in CL 2.0 ++//Core feature in CL 2.0, optional core feature in CL 3.0 + #ifndef cl_khr_3d_image_writes + #error "Missing cl_khr_3d_image_writes define" + #endif + #pragma OPENCL EXTENSION cl_khr_3d_image_writes : enable +-#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200) && defined TEST_CORE_FEATURES ++#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ == 200) && defined TEST_CORE_FEATURES + // expected-warning@-2{{OpenCL extension 'cl_khr_3d_image_writes' is core feature or supported optional core feature - ignoring}} + #endif + +@@ -215,3 +213,55 @@ + // expected-warning@+2{{unsupported OpenCL extension 'cl_intel_device_side_avc_motion_estimation' - ignoring}} + #endif + #pragma OPENCL EXTENSION cl_intel_device_side_avc_motion_estimation : enable ++ ++// Check that pragmas for the OpenCL 3.0 features are rejected. ++ ++#pragma OPENCL EXTENSION __opencl_c_int64 : disable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_int64' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_3d_image_writes : disable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_3d_image_writes' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_atomic_order_acq_rel : disable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_atomic_order_acq_rel' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_atomic_order_seq_cst : disable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_atomic_order_seq_cst' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_device_enqueue : disable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_device_enqueue' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_fp64 : disable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_fp64' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_generic_address_space : disable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_generic_address_space' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_images : disable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_images' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_pipes : disable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_pipes' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_program_scope_global_variables : disable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_program_scope_global_variables' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_read_write_images : disable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_read_write_images' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_subgroups : disable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_subgroups' - ignoring}} ++ ++#pragma OPENCL EXTENSION __opencl_c_int64 : enable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_int64' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_3d_image_writes : enable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_3d_image_writes' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_atomic_order_acq_rel : enable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_atomic_order_acq_rel' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_atomic_order_seq_cst : enable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_atomic_order_seq_cst' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_device_enqueue : enable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_device_enqueue' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_fp64 : enable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_fp64' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_generic_address_space : enable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_generic_address_space' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_images : enable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_images' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_pipes : enable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_pipes' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_program_scope_global_variables : enable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_program_scope_global_variables' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_read_write_images : enable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_read_write_images' - ignoring}} ++#pragma OPENCL EXTENSION __opencl_c_subgroups : enable ++//expected-warning@-1{{unknown OpenCL extension '__opencl_c_subgroups' - ignoring}} +diff --git a/clang/test/SemaOpenCL/extensions.cl b/clang/test/SemaOpenCL/extensions.cl +index 55dbd1d5eede..d43cdcece2e4 100644 +--- a/clang/test/SemaOpenCL/extensions.cl ++++ b/clang/test/SemaOpenCL/extensions.cl +@@ -1,26 +1,34 @@ +-// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only ++// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL1.0 + // RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL1.1 ++// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -fsyntax-only -cl-std=CL1.1 -DNOPEDANTIC + // RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL1.2 -DFP64 + + // Test with a target not supporting fp64. +-// RUN: %clang_cc1 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -DNOFP64 -DNOFP16 ++// RUN: %clang_cc1 %s -cl-std=CL1.0 -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -DNOFP64 -DNOFP16 ++// RUN: %clang_cc1 -cl-std=CL3.0 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -DNOFP64 -DNOFP16 + + // Test with some extensions enabled or disabled by cmd-line args + // + // Target does not support fp64 and fp16 - override it +-// RUN: %clang_cc1 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -cl-ext=+cl_khr_fp64,+cl_khr_fp16 ++// RUN: %clang_cc1 %s -cl-std=CL1.0 -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -cl-ext=+cl_khr_fp64,+cl_khr_fp16 + // + // Disable or enable all extensions +-// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-all -DNOFP64 -DNOFP16 +-// RUN: %clang_cc1 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -cl-ext=+all +-// RUN: %clang_cc1 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -cl-ext=+all,-cl_khr_fp64 -DNOFP64 +-// RUN: %clang_cc1 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -cl-ext=-all,+cl_khr_fp64 -DNOFP16 ++// RUN: %clang_cc1 %s -cl-std=CL1.0 -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-all -DNOFP64 -DNOFP16 ++// RUN: %clang_cc1 %s -cl-std=CL1.0 -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -cl-ext=+all ++// RUN: %clang_cc1 %s -cl-std=CL1.0 -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -cl-ext=+all,-cl_khr_fp64 -DNOFP64 ++// RUN: %clang_cc1 %s -cl-std=CL1.0 -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -cl-ext=-all,+cl_khr_fp64 -DNOFP16 ++// RUN: %clang_cc1 -cl-std=CL3.0 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-all -DNOFP64 -DNOFP16 ++// RUN: %clang_cc1 -cl-std=CL3.0 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -cl-ext=+all -DFP64 ++// RUN: %clang_cc1 -cl-std=CL3.0 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -cl-ext=+all,-__opencl_c_fp64,-cl_khr_fp64 -DNOFP64 + // + // Concatenating +-// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-cl_khr_fp64 -cl-ext=+cl_khr_fp64 +-// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-cl_khr_fp64,+cl_khr_fp64 +-// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-all -cl-ext=+cl_khr_fp64 -cl-ext=+cl_khr_fp16 -cl-ext=-cl_khr_fp64 -DNOFP64 ++// RUN: %clang_cc1 %s -cl-std=CL1.0 -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-cl_khr_fp64 -cl-ext=+cl_khr_fp64 ++// RUN: %clang_cc1 %s -cl-std=CL1.0 -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-cl_khr_fp64,+cl_khr_fp64 ++// RUN: %clang_cc1 %s -cl-std=CL1.0 -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-all -cl-ext=+cl_khr_fp64 -cl-ext=+cl_khr_fp16 -cl-ext=-cl_khr_fp64 -DNOFP64 + // RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-all -cl-ext=+cl_khr_fp64,-cl_khr_fp64,+cl_khr_fp16 -DNOFP64 ++// RUN: %clang_cc1 -cl-std=CL3.0 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-__opencl_c_fp64,-cl_khr_fp64 -cl-ext=+__opencl_c_fp64,+cl_khr_fp64 -DFP64 ++// RUN: %clang_cc1 -cl-std=CL3.0 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-__opencl_c_fp64,+__opencl_c_fp64,+cl_khr_fp64 -DFP64 ++// RUN: %clang_cc1 -cl-std=CL3.0 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-__opencl_c_fp64,-cl_khr_fp64 -DNOFP64 + + // Test with -finclude-default-header, which includes opencl-c.h. opencl-c.h + // disables all extensions by default, but supported core extensions for a +@@ -43,8 +51,20 @@ + #endif + + #if (defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ < 120) +-void f1(double da) { // expected-error {{type 'double' requires cl_khr_fp64 extension}} +- double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}} ++void f1(double da) { ++#ifdef NOFP64 ++// expected-error@-2 {{type 'double' requires cl_khr_fp64 support}} ++#elif !defined(NOPEDANTIC) ++// expected-warning@-4{{Clang permits use of type 'double' regardless pragma if 'cl_khr_fp64' is supported}} ++#endif ++ double d; ++#ifdef NOFP64 ++// expected-error@-2 {{type 'double' requires cl_khr_fp64 support}} ++#elif !defined(NOPEDANTIC) ++// expected-warning@-4{{Clang permits use of type 'double' regardless pragma if 'cl_khr_fp64' is supported}} ++#endif ++ // FIXME: this diagnostic depends on the extension pragma in the earlier versions. ++ // There is no indication that this behavior is expected. + (void) 1.0; // expected-warning {{double precision constant requires cl_khr_fp64}} + } + #endif +@@ -72,20 +92,30 @@ int isfinite(float x) { + void f2(void) { + double d; + #ifdef NOFP64 +-// expected-error@-2{{use of type 'double' requires cl_khr_fp64 extension to be enabled}} ++#if (defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ >= 300) ++// expected-error@-3{{use of type 'double' requires cl_khr_fp64 and __opencl_c_fp64 support}} ++#else ++// expected-error@-5{{use of type 'double' requires cl_khr_fp64 support}} ++#endif + #endif + + typedef double double4 __attribute__((ext_vector_type(4))); + double4 d4 = {0.0f, 2.0f, 3.0f, 1.0f}; + #ifdef NOFP64 +-// expected-error@-3 {{use of type 'double' requires cl_khr_fp64 extension to be enabled}} +-// expected-error@-3 {{use of type 'double4' (vector of 4 'double' values) requires cl_khr_fp64 extension to be enabled}} ++#if (defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ >= 300) ++// expected-error@-4 {{use of type 'double' requires cl_khr_fp64 and __opencl_c_fp64 support}} ++#else ++// expected-error@-6 {{use of type 'double' requires cl_khr_fp64 support}} ++#endif + #endif + + (void) 1.0; +- + #ifdef NOFP64 +-// expected-warning@-3{{double precision constant requires cl_khr_fp64, casting to single precision}} ++#if (defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ >= 300) ++// expected-warning@-3{{double precision constant requires cl_khr_fp64 and __opencl_c_fp64, casting to single precision}} ++#else ++// expected-warning@-5{{double precision constant requires cl_khr_fp64, casting to single precision}} ++#endif + #endif + } + +@@ -96,6 +126,11 @@ void f2(void) { + + #if (defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ < 120) + void f3(void) { +- double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}} ++ double d; ++#ifdef NOFP64 ++// expected-error@-2 {{type 'double' requires cl_khr_fp64 support}} ++#elif !defined(NOPEDANTIC) ++// expected-warning@-4 {{Clang permits use of type 'double' regardless pragma if 'cl_khr_fp64' is supported}} ++#endif + } + #endif +diff --git a/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl b/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl +index d1dcdfe8cb35..2db651836cb1 100644 +--- a/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl ++++ b/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl +@@ -39,26 +39,7 @@ kernel void test_pointers(volatile global void *global_p, global const int4 *a) + prefetch(a, 2); + + atom_add((volatile __global int *)global_p, i); +-#if !defined(__OPENCL_CPP_VERSION__) && __OPENCL_C_VERSION__ < CL_VERSION_1_1 +-// expected-error@-2{{no matching function for call to 'atom_add'}} +- +-// There are two potential definitions of the function "atom_add", both are +-// currently disabled because the associated extension is disabled. +-// expected-note@-6{{candidate function not viable: cannot pass pointer to address space '__global' as a pointer to address space '__local' in 1st argument}} +-// expected-note@-7{{candidate function not viable: no known conversion}} +-// expected-note@-8{{candidate function not viable: no known conversion}} +-// expected-note@-9{{candidate function not viable: no known conversion}} +-// expected-note@-10{{candidate unavailable as it requires OpenCL extension 'cl_khr_global_int32_base_atomics' to be enabled}} +-// expected-note@-11{{candidate unavailable as it requires OpenCL extension 'cl_khr_global_int32_base_atomics' to be enabled}} +-// expected-note@-12{{candidate unavailable as it requires OpenCL extension 'cl_khr_int64_base_atomics' to be enabled}} +-// expected-note@-13{{candidate unavailable as it requires OpenCL extension 'cl_khr_int64_base_atomics' to be enabled}} +-#endif +- +-#if __OPENCL_C_VERSION__ < CL_VERSION_1_1 +-#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable +-#endif + +- atom_add((volatile __global int *)global_p, i); + atom_cmpxchg((volatile __global unsigned int *)global_p, ui, ui); + } + +@@ -140,11 +121,9 @@ kernel void basic_image_writeonly(write_only image1d_buffer_t image_write_only_i + + kernel void basic_subgroup(global uint *out) { + out[0] = get_sub_group_size(); +-#if defined(__OPENCL_CPP_VERSION__) +- // expected-error@-2{{no matching function for call to 'get_sub_group_size'}} +- // expected-note@-3{{candidate unavailable as it requires OpenCL extension 'cl_khr_subgroups' to be enabled}} +-#else +- // expected-error@-5{{use of declaration 'get_sub_group_size' requires cl_khr_subgroups extension to be enabled}} ++#if __OPENCL_C_VERSION__ <= CL_VERSION_1_2 && !defined(__OPENCL_CPP_VERSION__) ++ // expected-error@-2{{implicit declaration of function 'get_sub_group_size' is invalid in OpenCL}} ++ // expected-error@-3{{implicit conversion changes signedness}} + #endif + } + +diff --git a/clang/test/SemaOpenCL/features.cl b/clang/test/SemaOpenCL/features.cl +new file mode 100644 +index 000000000000..57c52694b685 +--- /dev/null ++++ b/clang/test/SemaOpenCL/features.cl +@@ -0,0 +1,48 @@ ++// RUN: %clang_cc1 -triple spir-unknown-unknown %s -E -dM -o - -x cl -cl-std=CL3.0 -cl-ext=-all \ ++// RUN: | FileCheck -match-full-lines %s --check-prefix=NO-FEATURES ++// RUN: %clang_cc1 -triple spir-unknown-unknown %s -E -dM -o - -x cl -cl-std=CL3.0 -cl-ext=+all \ ++// RUN: | FileCheck -match-full-lines %s --check-prefix=FEATURES ++// RUN: %clang_cc1 -triple r600-unknown-unknown %s -E -dM -o - -x cl -cl-std=CL3.0 \ ++// RUN: | FileCheck -match-full-lines %s --check-prefix=NO-FEATURES ++// RUN: %clang_cc1 -triple r600-unknown-unknown %s -E -dM -o - -x cl -cl-std=CL3.0 -cl-ext=+all \ ++// RUN: | FileCheck -match-full-lines %s --check-prefix=FEATURES ++ ++// For OpenCL C 2.0 feature macros are defined only in header, so test that earlier OpenCL ++// versions don't define feature macros accidentally and CL2.0 don't define them without header ++// RUN: %clang_cc1 -triple spir-unknown-unknown %s -E -dM -o - -x cl -cl-std=CL1.1 \ ++// RUN: | FileCheck -match-full-lines %s --check-prefix=NO-FEATURES ++// RUN: %clang_cc1 -triple spir-unknown-unknown %s -E -dM -o - -x cl -cl-std=CL1.2 \ ++// RUN: | FileCheck -match-full-lines %s --check-prefix=NO-FEATURES ++// RUN: %clang_cc1 -triple spir-unknown-unknown %s -E -dM -o - -x cl -cl-std=CL2.0 \ ++// RUN: | FileCheck -match-full-lines %s --check-prefix=NO-FEATURES ++// RUN: %clang_cc1 -triple spir-unknown-unknown %s -E -dM -o - -x cl -cl-std=CLC++ \ ++// RUN: | FileCheck -match-full-lines %s --check-prefix=NO-FEATURES ++ ++// Note that __opencl_c_int64 is always defined assuming ++// always compiling for FULL OpenCL profile ++ ++// FEATURES: #define __opencl_c_3d_image_writes 1 ++// FEATURES: #define __opencl_c_atomic_order_acq_rel 1 ++// FEATURES: #define __opencl_c_atomic_order_seq_cst 1 ++// FEATURES: #define __opencl_c_device_enqueue 1 ++// FEATURES: #define __opencl_c_fp64 1 ++// FEATURES: #define __opencl_c_generic_address_space 1 ++// FEATURES: #define __opencl_c_images 1 ++// FEATURES: #define __opencl_c_int64 1 ++// FEATURES: #define __opencl_c_pipes 1 ++// FEATURES: #define __opencl_c_program_scope_global_variables 1 ++// FEATURES: #define __opencl_c_read_write_images 1 ++// FEATURES: #define __opencl_c_subgroups 1 ++ ++// NO-FEATURES: #define __opencl_c_int64 1 ++// NO-FEATURES-NOT: __opencl_c_3d_image_writes ++// NO-FEATURES-NOT: __opencl_c_atomic_order_acq_rel ++// NO-FEATURES-NOT: __opencl_c_atomic_order_seq_cst ++// NO-FEATURES-NOT: __opencl_c_device_enqueue ++// NO-FEATURES-NOT: __opencl_c_fp64 ++// NO-FEATURES-NOT: __opencl_c_generic_address_space ++// NO-FEATURES-NOT: __opencl_c_images ++// NO-FEATURES-NOT: __opencl_c_pipes ++// NO-FEATURES-NOT: __opencl_c_program_scope_global_variables ++// NO-FEATURES-NOT: __opencl_c_read_write_images ++// NO-FEATURES-NOT: __opencl_c_subgroups +diff --git a/clang/test/SemaOpenCL/intel-subgroup-avc-ext-types.cl b/clang/test/SemaOpenCL/intel-subgroup-avc-ext-types.cl +index e76d54763016..48ed4c0594d6 100644 +--- a/clang/test/SemaOpenCL/intel-subgroup-avc-ext-types.cl ++++ b/clang/test/SemaOpenCL/intel-subgroup-avc-ext-types.cl +@@ -1,6 +1,9 @@ +-// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL1.2 -cl-ext=+cl_intel_device_side_avc_motion_estimation -fsyntax-only -verify %s ++// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL1.2 -cl-ext=+cl_intel_device_side_avc_motion_estimation -fsyntax-only -verify -DEXT %s ++// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL1.2 -cl-ext=-cl_intel_device_side_avc_motion_estimation -fsyntax-only -verify %s + ++#ifdef cl_intel_device_side_avc_motion_estimation + #pragma OPENCL EXTENSION cl_intel_device_side_avc_motion_estimation : enable ++#endif + + // All intel_sub_group_avc_* types can only be used as argument or return value + // of built-in functions defined in the extension. +@@ -16,55 +19,77 @@ struct st{}; + // negative test cases for initializers + void foo(char c, float f, void* v, struct st ss) { + intel_sub_group_avc_mce_payload_t payload_mce = 0; // No zero initializer for mce types +- // expected-error@-1 {{initializing '__private intel_sub_group_avc_mce_payload_t' with an expression of incompatible type 'int'}} + intel_sub_group_avc_ime_payload_t payload_ime = 1; // No literal initializer for *payload_t types +- // expected-error@-1 {{initializing '__private intel_sub_group_avc_ime_payload_t' with an expression of incompatible type 'int'}} + intel_sub_group_avc_ref_payload_t payload_ref = f; +- // expected-error@-1 {{initializing '__private intel_sub_group_avc_ref_payload_t' with an expression of incompatible type '__private float'}} + intel_sub_group_avc_sic_payload_t payload_sic = ss; +- // expected-error@-1 {{initializing '__private intel_sub_group_avc_sic_payload_t' with an expression of incompatible type '__private struct st'}} +- + intel_sub_group_avc_mce_result_t result_mce = 0; // No zero initializer for mce types +- // expected-error@-1 {{initializing '__private intel_sub_group_avc_mce_result_t' with an expression of incompatible type 'int'}} + intel_sub_group_avc_ime_result_t result_ime = 1; // No literal initializer for *result_t types +- // expected-error@-1 {{initializing '__private intel_sub_group_avc_ime_result_t' with an expression of incompatible type 'int'}} + intel_sub_group_avc_ref_result_t result_ref = f; +- // expected-error@-1 {{initializing '__private intel_sub_group_avc_ref_result_t' with an expression of incompatible type '__private float'}} + intel_sub_group_avc_sic_result_t result_sic = ss; +- // expected-error@-1 {{initializing '__private intel_sub_group_avc_sic_result_t' with an expression of incompatible type '__private struct st'}} +- + intel_sub_group_avc_ime_result_single_reference_streamout_t sstreamout = v; +- // expected-error@-1 {{initializing '__private intel_sub_group_avc_ime_result_single_reference_streamout_t' with an expression of incompatible type '__private void *__private'}} +- + intel_sub_group_avc_ime_result_dual_reference_streamout_t dstreamin_list = {0x0, 0x1}; +- // expected-warning@-1 {{excess elements in struct initializer}} + intel_sub_group_avc_ime_dual_reference_streamin_t dstreamin_list2 = {}; +- // expected-error@-1 {{scalar initializer cannot be empty}} + intel_sub_group_avc_ime_single_reference_streamin_t dstreamin_list3 = {c}; +- // expected-error@-1 {{initializing '__private intel_sub_group_avc_ime_single_reference_streamin_t' with an expression of incompatible type '__private char'}} + intel_sub_group_avc_ime_dual_reference_streamin_t dstreamin_list4 = {1}; +- // expected-error@-1 {{initializing '__private intel_sub_group_avc_ime_dual_reference_streamin_t' with an expression of incompatible type 'int'}} ++#ifdef EXT ++// expected-error@-14 {{initializing '__private intel_sub_group_avc_mce_payload_t' with an expression of incompatible type 'int'}} ++// expected-error@-14 {{initializing '__private intel_sub_group_avc_ime_payload_t' with an expression of incompatible type 'int'}} ++// expected-error@-14 {{initializing '__private intel_sub_group_avc_ref_payload_t' with an expression of incompatible type '__private float'}} ++// expected-error@-14 {{initializing '__private intel_sub_group_avc_sic_payload_t' with an expression of incompatible type '__private struct st'}} ++// expected-error@-14 {{initializing '__private intel_sub_group_avc_mce_result_t' with an expression of incompatible type 'int'}} ++// expected-error@-14 {{initializing '__private intel_sub_group_avc_ime_result_t' with an expression of incompatible type 'int'}} ++// expected-error@-14 {{initializing '__private intel_sub_group_avc_ref_result_t' with an expression of incompatible type '__private float'}} ++// expected-error@-14 {{initializing '__private intel_sub_group_avc_sic_result_t' with an expression of incompatible type '__private struct st'}} ++// expected-error@-14 {{initializing '__private intel_sub_group_avc_ime_result_single_reference_streamout_t' with an expression of incompatible type '__private void *__private'}} ++// expected-warning@-14 {{excess elements in struct initializer}} ++// expected-error@-14 {{scalar initializer cannot be empty}} ++// expected-error@-14 {{initializing '__private intel_sub_group_avc_ime_single_reference_streamin_t' with an expression of incompatible type '__private char'}} ++// expected-error@-14 {{initializing '__private intel_sub_group_avc_ime_dual_reference_streamin_t' with an expression of incompatible type 'int'}} ++#else ++// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_mce_payload_t'}} ++// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_payload_t'}} ++// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ref_payload_t'}} ++// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_sic_payload_t'}} ++// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_mce_result_t'}} ++// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_result_t'}} ++// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ref_result_t'}} ++// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_sic_result_t'}} ++// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_result_single_reference_streamout_t'}} ++// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_result_dual_reference_streamout_t'}} ++// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_dual_reference_streamin_t'}} ++// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_single_reference_streamin_t'}} ++// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_dual_reference_streamin_t'}} ++#endif + } + + // negative tests for initializers and assignment + void far() { + intel_sub_group_avc_mce_payload_t payload_mce; + intel_sub_group_avc_mce_payload_t payload_mce2 = payload_mce; +- + intel_sub_group_avc_ime_payload_t payload_ime; + intel_sub_group_avc_ref_payload_t payload_ref = payload_ime; +- // expected-error@-1 {{initializing '__private intel_sub_group_avc_ref_payload_t' with an expression of incompatible type '__private intel_sub_group_avc_ime_payload_t'}} +- + intel_sub_group_avc_sic_result_t result_sic; + intel_sub_group_avc_ime_result_t result_ime; + result_sic = result_ime; +- // expected-error@-1 {{assigning to '__private intel_sub_group_avc_sic_result_t' from incompatible type '__private intel_sub_group_avc_ime_result_t'}} ++#ifdef EXT ++// expected-error@-5 {{initializing '__private intel_sub_group_avc_ref_payload_t' with an expression of incompatible type '__private intel_sub_group_avc_ime_payload_t'}} ++// expected-error@-3 {{assigning to '__private intel_sub_group_avc_sic_result_t' from incompatible type '__private intel_sub_group_avc_ime_result_t'}} ++#else ++// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_mce_payload_t'}} ++// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_mce_payload_t'}} ++// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_ime_payload_t'}} ++// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_ref_payload_t'}} ++// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_sic_result_t'}} ++// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_ime_result_t'}} ++// expected-error@-11 {{use of undeclared identifier 'result_sic'}} expected-error@-11 {{use of undeclared identifier 'result_ime'}} ++#endif + } + + // Using 0x0 directly allows us not to include opencl-c.h header and not to + // redefine all of these CLK_AVC_*_INTITIALIZE_INTEL macro. '0x0' value must + // be in sync with ones defined in opencl-c.h + ++#ifdef EXT + // positive test cases + void bar() { + const sampler_t vme_sampler = 0x0; +@@ -102,4 +127,4 @@ void bar() { + intel_sub_group_avc_ime_single_reference_streamin_t sstreamin_list = {0}; + intel_sub_group_avc_ime_dual_reference_streamin_t dstreamin_list = {0}; + } +- ++#endif //EXT +diff --git a/clang/test/SemaOpenCL/storageclass.cl b/clang/test/SemaOpenCL/storageclass.cl +index f35ab9c2e08c..060aff2354d1 100644 +--- a/clang/test/SemaOpenCL/storageclass.cl ++++ b/clang/test/SemaOpenCL/storageclass.cl +@@ -1,28 +1,118 @@ + // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL1.2 +- ++// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL3.0 -cl-ext=-__opencl_c_program_scope_global_variables,-__opencl_c_generic_address_space ++// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL3.0 -cl-ext=+__opencl_c_program_scope_global_variables,-__opencl_c_generic_address_space ++// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL3.0 -cl-ext=-__opencl_c_program_scope_global_variables,+__opencl_c_generic_address_space ++// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL3.0 -cl-ext=+__opencl_c_program_scope_global_variables,+__opencl_c_generic_address_space + static constant int G1 = 0; + constant int G2 = 0; +-int G3 = 0; // expected-error{{program scope variable must reside in constant address space}} +-global int G4 = 0; // expected-error{{program scope variable must reside in constant address space}} + +-static float g_implicit_static_var = 0; // expected-error {{program scope variable must reside in constant address space}} ++int G3 = 0; ++#ifndef __opencl_c_program_scope_global_variables ++// expected-error@-2 {{program scope variable must reside in constant address space}} ++#endif ++ ++global int G4 = 0; ++#ifndef __opencl_c_program_scope_global_variables ++// expected-error@-2 {{program scope variable must reside in constant address space}} ++#endif ++ ++static float g_implicit_static_var = 0; ++#ifndef __opencl_c_program_scope_global_variables ++// expected-error@-2 {{program scope variable must reside in constant address space}} ++#endif ++ + static constant float g_constant_static_var = 0; +-static global float g_global_static_var = 0; // expected-error {{program scope variable must reside in constant address space}} +-static local float g_local_static_var = 0; // expected-error {{program scope variable must reside in constant address space}} +-static private float g_private_static_var = 0; // expected-error {{program scope variable must reside in constant address space}} +-static generic float g_generic_static_var = 0; // expected-error{{OpenCL C version 1.2 does not support the 'generic' type qualifier}} // expected-error {{program scope variable must reside in constant address space}} + +-extern float g_implicit_extern_var; // expected-error {{extern variable must reside in constant address space}} ++static global float g_global_static_var = 0; ++#ifndef __opencl_c_program_scope_global_variables ++// expected-error@-2 {{program scope variable must reside in constant address space}} ++#endif ++ ++static local float g_local_static_var = 0; ++#ifndef __opencl_c_program_scope_global_variables ++// expected-error@-2 {{program scope variable must reside in constant address space}} ++#else ++// expected-error@-4 {{program scope variable must reside in global or constant address space}} ++#endif ++ ++static private float g_private_static_var = 0; ++#ifndef __opencl_c_program_scope_global_variables ++// expected-error@-2 {{program scope variable must reside in constant address space}} ++#else ++// expected-error@-4 {{program scope variable must reside in global or constant address space}} ++#endif ++ ++static generic float g_generic_static_var = 0; ++#if (__OPENCL_C_VERSION__ < 300) ++// expected-error@-2 {{OpenCL C version 1.2 does not support the 'generic' type qualifier}} ++// expected-error@-3 {{program scope variable must reside in constant address space}} ++#elif (__OPENCL_C_VERSION__ == 300) ++ #if !defined(__opencl_c_generic_address_space) ++// expected-error@-6 {{OpenCL C version 3.0 does not support the 'generic' type qualifier}} ++ #endif ++ #if !defined(__opencl_c_program_scope_global_variables) ++// expected-error@-9 {{program scope variable must reside in constant address space}} ++ #endif ++ #if defined(__opencl_c_generic_address_space) && defined(__opencl_c_program_scope_global_variables) ++// expected-error@-12 {{program scope variable must reside in global or constant address space}} ++ #endif ++#endif ++ ++extern float g_implicit_extern_var; ++#ifndef __opencl_c_program_scope_global_variables ++// expected-error@-2 {{extern variable must reside in constant address space}} ++#endif ++ + extern constant float g_constant_extern_var; +-extern global float g_global_extern_var; // expected-error {{extern variable must reside in constant address space}} +-extern local float g_local_extern_var; // expected-error {{extern variable must reside in constant address space}} +-extern private float g_private_extern_var; // expected-error {{extern variable must reside in constant address space}} +-extern generic float g_generic_extern_var; // expected-error{{OpenCL C version 1.2 does not support the 'generic' type qualifier}} // expected-error {{extern variable must reside in constant address space}} ++ ++extern global float g_global_extern_var; ++#ifndef __opencl_c_program_scope_global_variables ++// expected-error@-2 {{extern variable must reside in constant address space}} ++#endif ++ ++extern local float g_local_extern_var; ++#ifndef __opencl_c_program_scope_global_variables ++// expected-error@-2 {{extern variable must reside in constant address space}} ++#else ++// expected-error@-4 {{extern variable must reside in global or constant address space}} ++#endif ++ ++extern private float g_private_extern_var; ++#ifndef __opencl_c_program_scope_global_variables ++// expected-error@-2 {{extern variable must reside in constant address space}} ++#else ++// expected-error@-4 {{extern variable must reside in global or constant address space}} ++#endif ++ ++extern generic float g_generic_extern_var; ++#if (__OPENCL_C_VERSION__ < 300) ++// expected-error@-2 {{OpenCL C version 1.2 does not support the 'generic' type qualifier}} ++// expected-error@-3 {{extern variable must reside in constant address space}} ++#elif (__OPENCL_C_VERSION__ == 300) ++ #if !defined(__opencl_c_generic_address_space) ++// expected-error@-6 {{OpenCL C version 3.0 does not support the 'generic' type qualifier}} ++ #endif ++ #if !defined(__opencl_c_program_scope_global_variables) ++// expected-error@-9 {{extern variable must reside in constant address space}} ++ #endif ++ #if defined(__opencl_c_generic_address_space) && defined(__opencl_c_program_scope_global_variables) ++// expected-error@-12 {{extern variable must reside in global or constant address space}} ++ #endif ++#endif + + void kernel foo(int x) { + // static is not allowed at local scope before CL2.0 +- static int S1 = 5; // expected-error{{variables in function scope cannot be declared static}} +- static constant int S2 = 5; // expected-error{{variables in function scope cannot be declared static}} ++ static int S1 = 5; ++#if __OPENCL_C_VERSION__ < 300 ++// expected-error@-2 {{variables in function scope cannot be declared static}} ++#elif !defined(__opencl_c_program_scope_global_variables) ++// expected-error@-4 {{static local variable must reside in constant address space}} ++#endif ++ ++ static constant int S2 = 5; ++#if __OPENCL_C_VERSION__ < 300 ++// expected-error@-2 {{variables in function scope cannot be declared static}} ++#endif + + constant int L1 = 0; + local int L2; +@@ -32,12 +122,13 @@ void kernel foo(int x) { + constant int L1 = 42; // expected-error {{variables in the constant address space can only be declared in the outermost scope of a kernel function}} + } + +- auto int L3 = 7; // expected-error{{OpenCL C version 1.2 does not support the 'auto' storage class specifier}} ++ auto int L3 = 7; // expected-error-re{{OpenCL C version {{1.2|3.0}} does not support the 'auto' storage class specifier}} + global int L4; // expected-error{{function scope variable cannot be declared in global address space}} + __attribute__((address_space(100))) int L5; // expected-error{{automatic variable qualified with an invalid address space}} + + constant int L6 = x; // expected-error {{initializer element is not a compile-time constant}} + global int *constant L7 = &G4; ++ + private int *constant L8 = &x; // expected-error {{initializer element is not a compile-time constant}} + constant int *constant L9 = &L1; + local int *constant L10 = &L2; // expected-error {{initializer element is not a compile-time constant}} +@@ -59,17 +150,106 @@ void f() { + __attribute__((address_space(100))) int L4; // expected-error{{automatic variable qualified with an invalid address space}} + } + +- static float l_implicit_static_var = 0; // expected-error {{variables in function scope cannot be declared static}} +- static constant float l_constant_static_var = 0; // expected-error {{variables in function scope cannot be declared static}} +- static global float l_global_static_var = 0; // expected-error {{variables in function scope cannot be declared static}} +- static local float l_local_static_var = 0; // expected-error {{variables in function scope cannot be declared static}} +- static private float l_private_static_var = 0; // expected-error {{variables in function scope cannot be declared static}} +- static generic float l_generic_static_var = 0; // expected-error{{OpenCL C version 1.2 does not support the 'generic' type qualifier}} // expected-error {{variables in function scope cannot be declared static}} ++ static float l_implicit_static_var = 0; ++#if __OPENCL_C_VERSION__ < 300 ++// expected-error@-2 {{variables in function scope cannot be declared static}} ++#elif !defined(__opencl_c_program_scope_global_variables) ++// expected-error@-4 {{static local variable must reside in constant address space}} ++#endif ++ ++ static constant float l_constant_static_var = 0; ++#if __OPENCL_C_VERSION__ < 300 ++// expected-error@-2 {{variables in function scope cannot be declared static}} ++#endif ++ ++ static global float l_global_static_var = 0; ++#if __OPENCL_C_VERSION__ < 300 ++// expected-error@-2 {{variables in function scope cannot be declared static}} ++#elif !defined(__opencl_c_program_scope_global_variables) ++// expected-error@-4 {{static local variable must reside in constant address space}} ++#endif ++ ++ static local float l_local_static_var = 0; ++#if __OPENCL_C_VERSION__ < 300 ++// expected-error@-2 {{variables in function scope cannot be declared static}} ++#elif !defined(__opencl_c_program_scope_global_variables) ++// expected-error@-4 {{static local variable must reside in constant address space}} ++#elif defined(__opencl_c_program_scope_global_variables) ++// expected-error@-6 {{static local variable must reside in global or constant address space}} ++#endif ++ ++ static private float l_private_static_var = 0; ++#if __OPENCL_C_VERSION__ < 300 ++// expected-error@-2 {{variables in function scope cannot be declared static}} ++#elif !defined(__opencl_c_program_scope_global_variables) ++// expected-error@-4 {{static local variable must reside in constant address space}} ++#elif defined(__opencl_c_program_scope_global_variables) ++// expected-error@-6 {{static local variable must reside in global or constant address space}} ++#endif ++ ++ static generic float l_generic_static_var = 0; ++#if (__OPENCL_C_VERSION__ < 300) ++// expected-error@-2 {{OpenCL C version 1.2 does not support the 'generic' type qualifier}} ++// expected-error@-3 {{variables in function scope cannot be declared static}} ++#elif (__OPENCL_C_VERSION__ == 300) ++ #if !defined(__opencl_c_generic_address_space) ++// expected-error@-6 {{OpenCL C version 3.0 does not support the 'generic' type qualifier}} ++ #endif ++ #if !defined(__opencl_c_program_scope_global_variables) ++// expected-error@-9 {{static local variable must reside in constant address space}} ++ #endif ++ #if defined(__opencl_c_generic_address_space) && defined(__opencl_c_program_scope_global_variables) ++// expected-error@-12 {{static local variable must reside in global or constant address space}} ++ #endif ++#endif ++ ++ extern float l_implicit_extern_var; ++#if __OPENCL_C_VERSION__ < 300 ++// expected-error@-2 {{extern variable must reside in constant address space}} ++#elif !defined(__opencl_c_program_scope_global_variables) ++// expected-error@-4 {{extern variable must reside in constant address space}} ++#endif + +- extern float l_implicit_extern_var; // expected-error {{extern variable must reside in constant address space}} + extern constant float l_constant_extern_var; +- extern global float l_global_extern_var; // expected-error {{extern variable must reside in constant address space}} +- extern local float l_local_extern_var; // expected-error {{extern variable must reside in constant address space}} +- extern private float l_private_extern_var; // expected-error {{extern variable must reside in constant address space}} +- extern generic float l_generic_extern_var; // expected-error{{OpenCL C version 1.2 does not support the 'generic' type qualifier}} // expected-error {{extern variable must reside in constant address space}} ++ ++ extern global float l_global_extern_var; ++#if __OPENCL_C_VERSION__ < 300 ++// expected-error@-2 {{extern variable must reside in constant address space}} ++#elif !defined(__opencl_c_program_scope_global_variables) ++// expected-error@-4 {{extern variable must reside in constant address space}} ++#endif ++ ++ extern local float l_local_extern_var; ++#if __OPENCL_C_VERSION__ < 300 ++// expected-error@-2 {{extern variable must reside in constant address space}} ++#elif !defined(__opencl_c_program_scope_global_variables) ++// expected-error@-4 {{extern variable must reside in constant address space}} ++#elif defined(__opencl_c_program_scope_global_variables) ++// expected-error@-6 {{extern variable must reside in global or constant address space}} ++#endif ++ ++ extern private float l_private_extern_var; ++#if __OPENCL_C_VERSION__ < 300 ++// expected-error@-2 {{extern variable must reside in constant address space}} ++#elif !defined(__opencl_c_program_scope_global_variables) ++// expected-error@-4 {{extern variable must reside in constant address space}} ++#elif defined(__opencl_c_program_scope_global_variables) ++// expected-error@-6 {{extern variable must reside in global or constant address space}} ++#endif ++ ++ extern generic float l_generic_extern_var; ++#if (__OPENCL_C_VERSION__ < 300) ++// expected-error@-2 {{OpenCL C version 1.2 does not support the 'generic' type qualifier}} ++// expected-error@-3 {{extern variable must reside in constant address space}} ++#elif (__OPENCL_C_VERSION__ == 300) ++ #if !defined(__opencl_c_generic_address_space) ++// expected-error@-6 {{OpenCL C version 3.0 does not support the 'generic' type qualifier}} ++ #endif ++ #if !defined(__opencl_c_program_scope_global_variables) ++// expected-error@-9 {{extern variable must reside in constant address space}} ++ #endif ++ #if defined(__opencl_c_generic_address_space) && defined(__opencl_c_program_scope_global_variables) ++// expected-error@-12 {{extern variable must reside in global or constant address space}} ++ #endif ++#endif + } +diff --git a/clang/test/SemaOpenCL/unsupported-image.cl b/clang/test/SemaOpenCL/unsupported-image.cl +new file mode 100644 +index 000000000000..40772460e54d +--- /dev/null ++++ b/clang/test/SemaOpenCL/unsupported-image.cl +@@ -0,0 +1,69 @@ ++// RUN: %clang_cc1 -triple spir-unknown-unknown -verify -cl-std=CL3.0 -cl-ext=-__opencl_c_images,-__opencl_c_read_write_images,-cl_khr_3d_image_writes,-__opencl_c_3d_image_writes %s ++// RUN: %clang_cc1 -triple spir-unknown-unknown -verify -cl-std=CL3.0 -cl-ext=+__opencl_c_images,+__opencl_c_read_write_images,+cl_khr_3d_image_writes,+__opencl_c_3d_image_writes %s ++// RUN: %clang_cc1 -triple spir-unknown-unknown -verify -cl-std=CL3.0 -cl-ext=+__opencl_c_images,+__opencl_c_read_write_images,-cl_khr_3d_image_writes,-__opencl_c_3d_image_writes %s ++ ++#if defined(__opencl_c_images) && defined(__opencl_c_3d_image_writes) ++//expected-no-diagnostics ++#endif ++ ++void test1(image1d_t i) {} ++#if !defined(__opencl_c_images) ++// expected-error@-2{{use of type '__read_only image1d_t' requires __opencl_c_images support}} ++#endif ++ ++void test2(image2d_t i) {} ++#if !defined(__opencl_c_images) ++// expected-error@-2{{use of type '__read_only image2d_t' requires __opencl_c_images support}} ++#endif ++ ++void test3(image1d_array_t i) {} ++#if !defined(__opencl_c_images) ++// expected-error@-2{{use of type '__read_only image1d_array_t' requires __opencl_c_images support}} ++#endif ++ ++void test4(image2d_array_t i) {} ++#if !defined(__opencl_c_images) ++// expected-error@-2{{use of type '__read_only image2d_array_t' requires __opencl_c_images support}} ++#endif ++ ++void test5(image2d_depth_t i) {} ++#if !defined(__opencl_c_images) ++// expected-error@-2{{use of type '__read_only image2d_depth_t' requires __opencl_c_images support}} ++#endif ++ ++void test6(image1d_buffer_t i) {} ++#if !defined(__opencl_c_images) ++// expected-error@-2{{use of type '__read_only image1d_buffer_t' requires __opencl_c_images support}} ++#endif ++ ++void test7(image2d_msaa_t i) {} ++#if !defined(__opencl_c_images) ++// expected-error@-2{{use of type '__read_only image2d_msaa_t' requires __opencl_c_images support}} ++#endif ++ ++void test8(image2d_array_msaa_t i) {} ++#if !defined(__opencl_c_images) ++// expected-error@-2{{use of type '__read_only image2d_array_msaa_t' requires __opencl_c_images support}} ++#endif ++ ++void test9(image2d_msaa_depth_t i) {} ++#if !defined(__opencl_c_images) ++// expected-error@-2{{use of type '__read_only image2d_msaa_depth_t' requires __opencl_c_images support}} ++#endif ++ ++void test10(image2d_array_msaa_depth_t i) {} ++#if !defined(__opencl_c_images) ++// expected-error@-2{{use of type '__read_only image2d_array_msaa_depth_t' requires __opencl_c_images support}} ++#endif ++ ++void test11(sampler_t s) {} ++#if !defined(__opencl_c_images) ++// expected-error@-2{{use of type 'sampler_t' requires __opencl_c_images support}} ++#endif ++ ++void test12(write_only image3d_t i) {} ++#if !defined(__opencl_c_images) ++// expected-error@-2{{use of type '__write_only image3d_t' requires __opencl_c_images support}} ++#elif !defined(__opencl_c_3d_image_writes) ++// expected-error@-4{{use of type '__write_only image3d_t' requires cl_khr_3d_image_writes and __opencl_c_3d_image_writes support}} ++#endif +-- +2.18.1 + diff --git a/dynamic-layers/clang-layer/recipes-devtools/clang/llvm-project-source.bbappend b/dynamic-layers/clang-layer/recipes-devtools/clang/llvm-project-source.bbappend index 42ccb1dd..e3fd054b 100644 --- a/dynamic-layers/clang-layer/recipes-devtools/clang/llvm-project-source.bbappend +++ b/dynamic-layers/clang-layer/recipes-devtools/clang/llvm-project-source.bbappend @@ -6,6 +6,8 @@ SRC_URI_LLVM12_PATCHES = " \ file://llvm12-0003-Support-cl_ext_float_atomics.patch \ file://llvm12-0004-ispc-12_0_disable-A-B-A-B-and-BSWAP-in-InstCombine.patch \ file://llvm12-0005-ispc-12_0_fix_for_2111.patch \ + file://llvm12-0006-OpenCL-Add-cl_khr_integer_dot_product.patch \ + file://llvm12-0007-OpenCL-3.0-support.patch \ " SRC_URI:append:intel-x86-common = "${@bb.utils.contains('LLVMVERSION', '12.0.0', ' ${SRC_URI_LLVM12_PATCHES} ', '', d)}" -- cgit v1.2.3-54-g00ecf