meta-intel/dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm12-0007-OpenCL-3.0-support.patch
Anuj Mittal b9da851fa5 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 <anuj.mittal@intel.com>
2022-04-19 20:56:14 +08:00

4629 lines
254 KiB
Diff

From cc23dafd55bfe102e490c719f8b088e6b2a52561 Mon Sep 17 00:00:00 2001
From: Haonan Yang <haonan.yang@intel.com>
Date: Fri, 15 Apr 2022 15:52:37 +0800
Subject: [PATCH] OpenCL 3.0 support
Signed-off-by: Haonan Yang <haonan.yang@intel.com>
Upstream-Status: Submitted
Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
---
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 <https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_C.html#features>`_).
+Command-line flag :ref:`-cl-ext <opencl_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<DiagGroup<"poison-system-directories">>, 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<OpenCLCoreFeaturesDiagGroup>, 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<IgnoredPragmas>;
def warn_pragma_expected_predicate : Warning<
"expected %select{'enable', 'disable', 'begin' or 'end'|'disable'}0 - ignoring">, InGroup<IgnoredPragmas>;
-def warn_pragma_begin_end_mismatch : Warning<
- "OpenCL extension end directive mismatches begin directive - ignoring">, InGroup<IgnoredPragmas>;
def warn_pragma_unknown_extension : Warning<
"unknown OpenCL extension %0 - ignoring">, InGroup<IgnoredPragmas>;
def warn_pragma_unsupported_extension : Warning<
"unsupported OpenCL extension %0 - ignoring">, InGroup<IgnoredPragmas>;
def warn_pragma_extension_is_core : Warning<
- "OpenCL extension %0 is core feature or supported optional core feature - ignoring">, InGroup<DiagGroup<"pedantic-core-features">>, DefaultIgnore;
+ "OpenCL extension %0 is core feature or supported optional core feature - ignoring">,
+ InGroup<OpenCLCoreFeaturesDiagGroup>, 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<LiteralRange>;
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<UserDefinedWarnings>,
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<OpenCLOptionInfo>;
+ template <typename... Args>
+ static bool isOpenCLOptionCoreIn(const LangOptions &LO, Args &&... args) {
+ return OpenCLOptionInfo(std::forward<Args>(args)...).isCoreIn(LO);
+ }
+
+ template <typename... Args>
+ static bool isOpenCLOptionAvailableIn(const LangOptions &LO,
+ Args &&... args) {
+ return OpenCLOptionInfo(std::forward<Args>(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<bool> &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<bool> &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<bool> &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<const Type*, std::set<std::string>> OpenCLTypeExtMap;
- /// Extensions required by an OpenCL declaration.
- llvm::DenseMap<const Decl*, std::set<std::string>> 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<typename T, typename MapT>
- 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 <typename T, typename DiagLocT, typename DiagInfoT, typename MapT>
- 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<bool> &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<llvm::StringRef> 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<llvm::StringRef> 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<bool> &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<bool> &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<bool> &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<bool> &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<QualType> 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<QualType> 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<FieldDecl *, Sema::DeleteLocs> &
Sema::getMismatchingDeleteExpressions() const {
return DeleteExprs;
}
-
-void Sema::setOpenCLExtensionForType(QualType T, llvm::StringRef ExtStr) {
- if (ExtStr.empty())
- return;
- llvm::SmallVector<StringRef, 1> 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<StringRef, 1> 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 <typename T, typename MapT>
-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 <typename T, typename DiagLocT, typename DiagInfoT, typename MapT>
-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<TypedefType>(QT.getTypePtr()))
- Decl = TypedefT->getDecl();
- if (auto TagT = dyn_cast<TagType>(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<ExtVectorType>()->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<ParmVarDecl>(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<BuiltinType>()->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 <Index, Len> 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<QualType, 1> RetTypes;
SmallVector<SmallVector<QualType, 1>, 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<CXXConstructorDecl>(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<unsigned>(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<unsigned>(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<const Type *, std::set<std::string>> &OpenCLTypeExtMap =
- SemaRef.OpenCLTypeExtMap;
- using ElementTy = std::pair<TypeID, const std::set<std::string> *>;
- llvm::SmallVector<ElementTy, 8> 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<std::string> *ExtSet = E.second;
- Record.push_back(static_cast<unsigned>(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<const Decl *, std::set<std::string>> &OpenCLDeclExtMap =
- SemaRef.OpenCLDeclExtMap;
- using ElementTy = std::pair<DeclID, const std::set<std::string> *>;
- llvm::SmallVector<ElementTy, 8> 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<std::string> *ExtSet = E.second;
- Record.push_back(static_cast<unsigned>(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