Index: clang/include/clang/Basic/OpenCLExtensions.def =================================================================== --- clang/include/clang/Basic/OpenCLExtensions.def +++ clang/include/clang/Basic/OpenCLExtensions.def @@ -42,6 +42,10 @@ #endif // OPENCLEXT #endif // OPENCLEXT_INTERNAL +#ifndef OPENCLFEAT_INTERNAL +#define OPENCLFEAT_INTERNAL OPENCLEXT_INTERNAL +#endif // OPENCLFEAT_INTERNAL + // OpenCL 1.0. OPENCLEXT_INTERNAL(cl_khr_3d_image_writes, 100, 200) OPENCLEXT_INTERNAL(cl_khr_byte_addressable_store, 100, 110) @@ -92,7 +96,22 @@ OPENCLEXT_INTERNAL(cl_intel_subgroups_short, 120, ~0U) OPENCLEXT_INTERNAL(cl_intel_device_side_avc_motion_estimation, 120, ~0U) +// OpenCL features +OPENCLFEAT_INTERNAL(__opencl_c_pipes, 200, ~0U) +OPENCLFEAT_INTERNAL(__opencl_c_generic_address_space, 200, ~0U) +OPENCLFEAT_INTERNAL(__opencl_c_atomic_order_acq_rel, 200, ~0U) +OPENCLFEAT_INTERNAL(__opencl_c_atomic_order_seq_cst, 200, ~0U) +OPENCLFEAT_INTERNAL(__opencl_c_subgroups, 300, ~0U) +OPENCLFEAT_INTERNAL(__opencl_c_3d_image_writes, 100, ~0U) +OPENCLFEAT_INTERNAL(__opencl_c_device_enqueue, 200, ~0U) +OPENCLFEAT_INTERNAL(__opencl_c_read_write_images, 200, ~0U) +OPENCLFEAT_INTERNAL(__opencl_c_program_scope_global_variables, 200, ~0U) +OPENCLFEAT_INTERNAL(__opencl_c_fp64, 120, ~0U) +OPENCLFEAT_INTERNAL(__opencl_c_images, 100, ~0U) +OPENCLFEAT_INTERNAL(__opencl_c_int64, 100, ~0) + #undef OPENCLEXT_INTERNAL +#undef OPENCLFEAT_INTERNAL #ifdef OPENCLEXT #undef OPENCLEXT Index: clang/include/clang/Basic/OpenCLOptions.h =================================================================== --- clang/include/clang/Basic/OpenCLOptions.h +++ clang/include/clang/Basic/OpenCLOptions.h @@ -24,14 +24,45 @@ struct Info { bool Supported; // Is this option supported bool Enabled; // Is this option enabled + bool IsFeature; // Is this OpenCL feature unsigned Avail; // Option starts to be available in this OpenCL version unsigned Core; // Option becomes (optional) core feature in this OpenCL // version - Info(bool S = false, bool E = false, unsigned A = 100, unsigned C = ~0U) - :Supported(S), Enabled(E), Avail(A), Core(C){} + Info(bool S = false, bool E = false, bool F = false, unsigned A = 100, + unsigned C = ~0U) + : Supported(S), Enabled(E), IsFeature(F), Avail(A), Core(C) {} }; + + // OpenCL Version + unsigned CLVer = 120; + bool IsOpenCLCPlusPlus = false; + llvm::StringMap OptMap; + + // Note that __opencl_c_subgroups and cl_khr_subgroups are not equivalent + // because extension requires sub-group independent forward progress + const llvm::StringMap EquivalentFeaturesExtensions{ + {"__opencl_c_3d_image_writes", "cl_khr_3d_image_writes"}, + {"__opencl_c_fp64", "cl_khr_fp64"}}; + + // For pre-OpenCL C 3.0 features are supported simultaneously + // with corresponding extensions (if there is such extension, otherwise + // check specific version of feature) + void supportFeatureForPreOCL30(StringRef Feat, bool On = true) { + assert(CLVer < 300 && "Can'be called for OpenCL C higher 3.0"); + auto It = EquivalentFeaturesExtensions.find(Feat); + if (It != EquivalentFeaturesExtensions.end()) + OptMap[Feat].Supported = OptMap[It->getValue()].Supported; + else if (OptMap[Feat].Avail <= CLVer) + OptMap[Feat].Supported = On; + } + public: + void setOpenCLVersion(const LangOptions &LO) { + IsOpenCLCPlusPlus = LO.OpenCLCPlusPlus; + CLVer = IsOpenCLCPlusPlus ? 200 : LO.OpenCLVersion; + } + bool isKnown(llvm::StringRef Ext) const { return OptMap.find(Ext) != OptMap.end(); } @@ -42,27 +73,24 @@ // Is supported as either an extension or an (optional) core feature for // OpenCL version \p CLVer. - bool isSupported(llvm::StringRef Ext, const LangOptions &LO) const { + bool isSupported(llvm::StringRef Ext) const { // In C++ mode all extensions should work at least as in v2.0. - auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion; auto I = OptMap.find(Ext)->getValue(); return I.Supported && I.Avail <= CLVer; } // Is supported (optional) OpenCL core features for OpenCL version \p CLVer. // For supported extension, return false. - bool isSupportedCore(llvm::StringRef Ext, const LangOptions &LO) const { + bool isSupportedCore(llvm::StringRef Ext) const { // In C++ mode all extensions should work at least as in v2.0. - auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion; auto I = OptMap.find(Ext)->getValue(); return I.Supported && I.Avail <= CLVer && I.Core != ~0U && CLVer >= I.Core; } // Is supported OpenCL extension for OpenCL version \p CLVer. // For supported (optional) core feature, return false. - bool isSupportedExtension(llvm::StringRef Ext, const LangOptions &LO) const { + bool isSupportedExtension(llvm::StringRef Ext) const { // In C++ mode all extensions should work at least as in v2.0. - auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion; auto I = OptMap.find(Ext)->getValue(); return I.Supported && I.Avail <= CLVer && (I.Core == ~0U || CLVer < I.Core); } @@ -77,7 +105,6 @@ /// \param V used when \p Ext is not prefixed by '+' or '-' void support(llvm::StringRef Ext, bool V = true) { assert(!Ext.empty() && "Extension is empty."); - switch (Ext[0]) { case '+': V = true; @@ -93,23 +120,60 @@ supportAll(V); return; } - OptMap[Ext].Supported = V; + + auto &Info = OptMap[Ext]; + if (Info.IsFeature && CLVer < 300) + supportFeatureForPreOCL30(Ext, V); + else + OptMap[Ext].Supported = V; } OpenCLOptions(){ #define OPENCLEXT_INTERNAL(Ext, AvailVer, CoreVer) \ OptMap[#Ext].Avail = AvailVer; \ OptMap[#Ext].Core = CoreVer; +#define OPENCLFEAT_INTERNAL(Feat, AvailVer, CoreVer) \ + OptMap[#Feat].Avail = AvailVer; \ + OptMap[#Feat].Core = CoreVer; \ + OptMap[#Feat].IsFeature = true; #include "clang/Basic/OpenCLExtensions.def" } + // Support features whose support is directly related to the + // specific OpenCL version. For example, OpenCL 2.0 supports + // all features that are optional in 3.0 + void adjustFeatures() { + // Assume compiling for FULL profile + OptMap["__opencl_c_int64"].Supported = true; + + if (CLVer >= 300) { + // Simultaneously support feature and equivalent extension. + for (auto &FeatExt : EquivalentFeaturesExtensions) + OptMap[FeatExt.getValue()].Supported = + OptMap[FeatExt.getKey()].Supported; + + // For OpenCL C 3.0 all features are supported + // explicitly via option or target settings. + return; + } + + for (auto &Opt : OptMap) { + auto &Info = Opt.getValue(); + if (!Info.IsFeature) + continue; + supportFeatureForPreOCL30(Opt.getKey()); + } + } + void addSupport(const OpenCLOptions &Opts) { for (auto &I:Opts.OptMap) if (I.second.Supported) - OptMap[I.getKey()].Supported = true; + support(I.getKey(), true); } void copy(const OpenCLOptions &Opts) { + CLVer = Opts.CLVer; + IsOpenCLCPlusPlus = Opts.IsOpenCLCPlusPlus; OptMap = Opts.OptMap; } @@ -117,19 +181,19 @@ void supportAll(bool On = true) { for (llvm::StringMap::iterator I = OptMap.begin(), E = OptMap.end(); I != E; ++I) - I->second.Supported = On; + support(I->getKey(), On); } - void disableAll() { + void disableAllExtensions() { for (llvm::StringMap::iterator I = OptMap.begin(), E = OptMap.end(); I != E; ++I) I->second.Enabled = false; } - void enableSupportedCore(LangOptions LO) { + void enableSupportedCore() { for (llvm::StringMap::iterator I = OptMap.begin(), E = OptMap.end(); I != E; ++I) - if (isSupportedCore(I->getKey(), LO)) + if (isSupportedCore(I->getKey())) I->second.Enabled = true; } Index: clang/lib/Basic/TargetInfo.cpp =================================================================== --- clang/lib/Basic/TargetInfo.cpp +++ clang/lib/Basic/TargetInfo.cpp @@ -387,6 +387,10 @@ HalfFormat = &llvm::APFloat::IEEEhalf(); FloatFormat = &llvm::APFloat::IEEEsingle(); LongDoubleFormat = &llvm::APFloat::IEEEquad(); + + auto &SupportedOCLOpts = getTargetOpts().SupportedOpenCLOptions; + + SupportedOCLOpts.adjustFeatures(); } if (Opts.DoubleSize) { Index: clang/lib/Basic/Targets.cpp =================================================================== --- clang/lib/Basic/Targets.cpp +++ clang/lib/Basic/Targets.cpp @@ -694,8 +694,6 @@ if (!Target->handleTargetFeatures(Opts->Features, Diags)) return nullptr; - Target->setSupportedOpenCLOpts(); - Target->setOpenCLExtensionOpts(); Target->setMaxAtomicWidth(); if (!Target->validateTarget(Diags)) Index: clang/lib/Frontend/CompilerInstance.cpp =================================================================== --- clang/lib/Frontend/CompilerInstance.cpp +++ clang/lib/Frontend/CompilerInstance.cpp @@ -951,6 +951,12 @@ // FIXME: can we disable FEnvAccess? } + if (getLangOpts().OpenCL) { + getTarget().getSupportedOpenCLOpts().setOpenCLVersion((getLangOpts())); + getTarget().setSupportedOpenCLOpts(); + getTarget().setOpenCLExtensionOpts(); + } + // Inform the target of the language options. // // FIXME: We shouldn't need to do this, the target should be immutable once Index: clang/lib/Frontend/InitPreprocessor.cpp =================================================================== --- clang/lib/Frontend/InitPreprocessor.cpp +++ clang/lib/Frontend/InitPreprocessor.cpp @@ -1112,7 +1112,7 @@ // OpenCL definitions. if (LangOpts.OpenCL) { #define OPENCLEXT(Ext) \ - if (TI.getSupportedOpenCLOpts().isSupported(#Ext, LangOpts)) \ + if (TI.getSupportedOpenCLOpts().isSupported(#Ext)) \ Builder.defineMacro(#Ext); #include "clang/Basic/OpenCLExtensions.def" Index: clang/lib/Headers/opencl-c-base.h =================================================================== --- clang/lib/Headers/opencl-c-base.h +++ clang/lib/Headers/opencl-c-base.h @@ -9,6 +9,13 @@ #ifndef _OPENCL_BASE_H_ #define _OPENCL_BASE_H_ +// Define OpenCL header-only features for pre-OpenCL C 3.0 +#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ == CL_VERSION_2_0) +#define __opencl_c_atomic_scope_device 1 +#define __opencl_c_atomic_scope_all_devices 1 +#define __opencl_c_work_group_collective_functions 1 +#endif + // built-in scalar data types: /** Index: clang/lib/Parse/ParsePragma.cpp =================================================================== --- clang/lib/Parse/ParsePragma.cpp +++ clang/lib/Parse/ParsePragma.cpp @@ -772,13 +772,13 @@ // behavior is set to disable." if (Name == "all") { if (State == Disable) { - Opt.disableAll(); - Opt.enableSupportedCore(getLangOpts()); + Opt.disableAllExtensions(); + Opt.enableSupportedCore(); } else { PP.Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1; } } else if (State == Begin) { - if (!Opt.isKnown(Name) || !Opt.isSupported(Name, getLangOpts())) { + if (!Opt.isKnown(Name) || !Opt.isSupported(Name)) { Opt.support(Name); } Actions.setCurrentOpenCLExtension(Name); @@ -788,9 +788,9 @@ Actions.setCurrentOpenCLExtension(""); } else if (!Opt.isKnown(Name)) PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident; - else if (Opt.isSupportedExtension(Name, getLangOpts())) + else if (Opt.isSupportedExtension(Name)) Opt.enable(Name, State == Enable); - else if (Opt.isSupportedCore(Name, getLangOpts())) + else if (Opt.isSupportedCore(Name)) PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident; else PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident; Index: clang/lib/Sema/Sema.cpp =================================================================== --- clang/lib/Sema/Sema.cpp +++ clang/lib/Sema/Sema.cpp @@ -292,9 +292,10 @@ // Initialize predefined OpenCL types and supported extensions and (optional) // core features. if (getLangOpts().OpenCL) { + getOpenCLOptions().setOpenCLVersion(getLangOpts()); getOpenCLOptions().addSupport( Context.getTargetInfo().getSupportedOpenCLOpts()); - getOpenCLOptions().enableSupportedCore(getLangOpts()); + getOpenCLOptions().enableSupportedCore(); addImplicitTypedef("sampler_t", Context.OCLSamplerTy); addImplicitTypedef("event_t", Context.OCLEventTy); if (getLangOpts().OpenCLCPlusPlus || getLangOpts().OpenCLVersion >= 200) { Index: clang/lib/Serialization/ASTReader.cpp =================================================================== --- clang/lib/Serialization/ASTReader.cpp +++ clang/lib/Serialization/ASTReader.cpp @@ -3602,6 +3602,7 @@ auto &Opt = OpenCLExtensions.OptMap[Name]; Opt.Supported = Record[I++] != 0; Opt.Enabled = Record[I++] != 0; + Opt.IsFeature = Record[I++] != 0; Opt.Avail = Record[I++]; Opt.Core = Record[I++]; } Index: clang/lib/Serialization/ASTWriter.cpp =================================================================== --- clang/lib/Serialization/ASTWriter.cpp +++ clang/lib/Serialization/ASTWriter.cpp @@ -3976,6 +3976,7 @@ auto V = I.getValue(); Record.push_back(V.Supported ? 1 : 0); Record.push_back(V.Enabled ? 1 : 0); + Record.push_back(V.IsFeature ? 1 : 0); Record.push_back(V.Avail); Record.push_back(V.Core); } Index: clang/test/SemaOpenCL/opencl-feature-extension-simult.cl =================================================================== --- /dev/null +++ clang/test/SemaOpenCL/opencl-feature-extension-simult.cl @@ -0,0 +1,33 @@ +// Testing with target which doesn't support 3d image writes and fp64 + +// RUN: %clang_cc1 %s -triple r600-unknown-unknown -E -cl-std=CL1.2 -cl-ext=-cl_khr_fp64 +// RUN: %clang_cc1 %s -triple r600-unknown-unknown -E -cl-std=CL1.2 -cl-ext=+cl_khr_fp64 +// RUN: %clang_cc1 %s -triple r600-unknown-unknown -E -cl-std=CL1.2 -cl-ext=-cl_khr_3d_image_writes +// RUN: %clang_cc1 %s -triple r600-unknown-unknown -E -cl-std=CL1.2 -cl-ext=+cl_khr_3d_image_writes + +// RUN: %clang_cc1 %s -triple r600-unknown-unknown -E -cl-std=CL2.0 -cl-ext=-cl_khr_fp64 +// RUN: %clang_cc1 %s -triple r600-unknown-unknown -E -cl-std=CL2.0 -cl-ext=+cl_khr_fp64 +// RUN: %clang_cc1 %s -triple r600-unknown-unknown -E -cl-std=CL2.0 -cl-ext=-cl_khr_3d_image_writes +// RUN: %clang_cc1 %s -triple r600-unknown-unknown -E -cl-std=CL2.0 -cl-ext=+cl_khr_3d_image_writes + +// RUN: %clang_cc1 %s -triple r600-unknown-unknown -E -cl-std=CL3.0 -cl-ext=-all,__opencl_c_fp64 +// RUN: %clang_cc1 %s -triple r600-unknown-unknown -E -cl-std=CL3.0 -cl-ext=+__opencl_c_fp64 +// RUN: %clang_cc1 %s -triple r600-unknown-unknown -E -cl-std=CL3.0 -cl-ext=+__opencl_c_3d_image_writes +// RUN: %clang_cc1 %s -triple r600-unknown-unknown -E -cl-std=CL3.0 -cl-ext=+__opencl_c_pipes +// RUN: %clang_cc1 %s -triple r600-unknown-unknown -E -cl-std=CL3.0 -cl-ext=+__opencl_c_device_enqueue +// RUN: %clang_cc1 %s -triple r600-unknown-unknown -E -cl-std=CL3.0 -cl-ext=+__opencl_c_read_write_images +// RUN: %clang_cc1 %s -triple r600-unknown-unknown -E -cl-std=CL3.0 -cl-ext=+__opencl_c_fp64,-cl_khr_fp64 +// RUN: %clang_cc1 %s -triple r600-unknown-unknown -E -cl-std=CL3.0 -cl-ext=+__opencl_c_3d_image_writes,-cl_khr_3d_image_writes + +// expected-no-diagnostics + +#if (defined(cl_khr_fp64) && !defined(__opencl_c_fp64)) || \ + (defined(__opencl_c_fp64) && !defined(cl_khr_fp64)) + #error macros were not properly set up +#endif + +#if (defined(cl_khr_3d_image_writes) && \ + !defined(__opencl_c_3d_image_writes)) || \ + (defined(__opencl_c_3d_image_writes) && !defined(cl_khr_3d_image_writes)) + #error macros were not properly set up +#endif Index: clang/test/SemaOpenCL/opencl-features.cl =================================================================== --- /dev/null +++ clang/test/SemaOpenCL/opencl-features.cl @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -finclude-default-header %s -E -dM -o - -x cl -cl-std=CL2.0 \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CL20 +// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -finclude-default-header %s -E -dM -o - -x cl -cl-std=CL2.0 -cl-ext=-all \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CL20 +// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -finclude-default-header %s -E -dM -o - -x cl -cl-std=CLC++ \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CL20 +// RUN: %clang_cc1 -triple r600-unknown-unknown -finclude-default-header %s -E -dM -o - -x cl -cl-std=CL2.0 \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CL20 +// RUN: %clang_cc1 -triple r600-unknown-unknown -finclude-default-header %s -E -dM -o - -x cl -cl-std=CL2.0 -cl-ext=-all \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CL20 +// RUN: %clang_cc1 -triple r600-unknown-unknown -finclude-default-header %s -E -dM -o - -x cl -cl-std=CLC++ \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CL20 +// RUN: %clang_cc1 -triple nvptx-unknown-unknown -finclude-default-header %s -E -dM -o - -x cl -cl-std=CL2.0 \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CL20 +// RUN: %clang_cc1 -triple nvptx-unknown-unknown -finclude-default-header %s -E -dM -o - -x cl -cl-std=CL2.0 -cl-ext=-all \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CL20 +// RUN: %clang_cc1 -triple nvptx-unknown-unknown -finclude-default-header %s -E -dM -o - -x cl -cl-std=CLC++ \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CL20 +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -finclude-default-header %s -E -dM -o - -x cl -cl-std=CL2.0 \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CL20 +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -finclude-default-header %s -E -dM -o - -x cl -cl-std=CL2.0 -cl-ext=-all \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CL20 +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -finclude-default-header %s -E -dM -o - -x cl -cl-std=CLC++ \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CL20 +// RUN: %clang_cc1 -triple spir-unknown-unknown -finclude-default-header %s -E -dM -o - -x cl -cl-std=CL2.0 \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CL20 +// RUN: %clang_cc1 -triple r600-unknown-unknown -finclude-default-header %s -E -dM -o - -x cl -cl-std=CL2.0 -cl-ext=-all \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CL20 +// RUN: %clang_cc1 -triple spir-unknown-unknown -finclude-default-header %s -E -dM -o - -x cl -cl-std=CLC++ \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CL20 + +// x86_64 and spir support all features by default + +// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -finclude-default-header %s -E -dM -o - -x cl -cl-std=CL3.0 \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CL30 +// RUN: %clang_cc1 -triple r600-unknown-unknown -finclude-default-header %s -E -dM -o - -x cl -cl-std=CL3.0 \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CL30 +// RUN: %clang_cc1 -triple nvptx-unknown-unknown -finclude-default-header %s -E -dM -o - -x cl -cl-std=CL3.0 \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CL30 +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -finclude-default-header %s -E -dM -o - -x cl -cl-std=CL3.0 -cl-ext=-all \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CL30 +// RUN: %clang_cc1 -triple spir-unknown-unknown -finclude-default-header %s -E -dM -o - -x cl -cl-std=CL3.0 -cl-ext=-all \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=CL30 + +// CL20: #define __opencl_c_atomic_order_acq_rel 1 +// CL20: #define __opencl_c_atomic_order_seq_cst 1 +// CL20: #define __opencl_c_atomic_scope_all_devices 1 +// CL20: #define __opencl_c_atomic_scope_device 1 +// CL20: #define __opencl_c_device_enqueue 1 +// CL20: #define __opencl_c_generic_address_space 1 +// CL20: #define __opencl_c_images 1 +// CL20: #define __opencl_c_int64 1 +// CL20: #define __opencl_c_pipes 1 +// CL20: #define __opencl_c_program_scope_global_variables 1 +// CL20: #define __opencl_c_read_write_images 1 +// CL20: #define __opencl_c_work_group_collective_functions 1 + +// CL30: #define __opencl_c_int64 1 +// CL30-NOT: __opencl_c_atomic_order_acq_rel +// CL30-NOT: __opencl_c_atomic_order_seq_cst +// CL30-NOT: __opencl_c_atomic_scope_all_devices +// CL30-NOT: __opencl_c_atomic_scope_device +// CL30-NOT: __opencl_c_device_enqueue +// CL30-NOT: __opencl_c_generic_address_space +// CL30-NOT: __opencl_c_images +// CL30-NOT: __opencl_c_pipes +// CL30-NOT: __opencl_c_program_scope_global_variables +// CL30-NOT: __opencl_c_read_write_images +// CL30-NOT: __opencl_c_work_group_collective_functions