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