Anastasia created this revision. Anastasia added reviewers: azabaznov, svenvh, mantognini. Herald added subscribers: ebevhan, jfb, yaxunl. Anastasia requested review of this revision.
Currently, extension pragma is always added when new OpenCL option (extension or feature) is added to the frontend. This change adds a new field for the options that allows specifying the need for the pragmas. For backward compatibility, the pragmas are added for all extensions prior to OpenCL 3.0. For OpenCL 3.0 features and future extensions (those that are documented in the unified spec only), the pragmas is not to be added unless they are explicitly requested and their behavior is sufficiently well explained. https://reviews.llvm.org/D97052 Files: clang/include/clang/Basic/OpenCLExtensions.def clang/include/clang/Basic/OpenCLOptions.h clang/lib/Basic/OpenCLOptions.cpp clang/lib/Basic/Targets.cpp clang/lib/Parse/ParsePragma.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/test/SemaOpenCL/extension-version.cl
Index: clang/test/SemaOpenCL/extension-version.cl =================================================================== --- clang/test/SemaOpenCL/extension-version.cl +++ 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 @@ -100,7 +98,7 @@ #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}} Index: clang/lib/Serialization/ASTWriter.cpp =================================================================== --- clang/lib/Serialization/ASTWriter.cpp +++ clang/lib/Serialization/ASTWriter.cpp @@ -3958,6 +3958,7 @@ 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); Index: clang/lib/Serialization/ASTReader.cpp =================================================================== --- clang/lib/Serialization/ASTReader.cpp +++ clang/lib/Serialization/ASTReader.cpp @@ -3629,6 +3629,7 @@ 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++]; Index: clang/lib/Parse/ParsePragma.cpp =================================================================== --- clang/lib/Parse/ParsePragma.cpp +++ clang/lib/Parse/ParsePragma.cpp @@ -780,13 +780,16 @@ } 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)) + } 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); Index: clang/lib/Basic/Targets.cpp =================================================================== --- clang/lib/Basic/Targets.cpp +++ clang/lib/Basic/Targets.cpp @@ -735,7 +735,7 @@ .isAvailableIn(Opts)) Builder.defineMacro(Name); }; -#define OPENCL_GENERIC_EXTENSION(Ext, Avail, Core, Opt) \ +#define OPENCL_GENERIC_EXTENSION(Ext, WithPragma, Avail, Core, Opt) \ defineOpenCLExtMacro(#Ext, Avail, Core, Opt); #include "clang/Basic/OpenCLExtensions.def" Index: clang/lib/Basic/OpenCLOptions.cpp =================================================================== --- clang/lib/Basic/OpenCLOptions.cpp +++ clang/lib/Basic/OpenCLOptions.cpp @@ -19,6 +19,11 @@ return E != OptMap.end() && E->second.Enabled; } +bool OpenCLOptions::isWithPragma(llvm::StringRef Ext) const { + auto E = OptMap.find(Ext); + return E != OptMap.end() && E->second.WithPragma; +} + bool OpenCLOptions::isSupported(llvm::StringRef Ext, const LangOptions &LO) const { auto E = OptMap.find(Ext); @@ -69,6 +74,10 @@ 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,10 +85,10 @@ } OpenCLOptions::OpenCLOptions() { -#define OPENCL_GENERIC_EXTENSION(Ext, AvailVer, CoreVer, OptVer) \ - OptMap[#Ext].Avail = AvailVer; \ - OptMap[#Ext].Core = CoreVer; \ - OptMap[#Ext].Opt = OptVer; +#define OPENCL_GENERIC_EXTENSION(Ext, Pragma, AvailVer, CoreVer, OptVer) \ + OptMap.insert( \ + std::make_pair(llvm::StringRef{#Ext}, \ + OpenCLOptionInfo{AvailVer, CoreVer, OptVer, Pragma})); #include "clang/Basic/OpenCLExtensions.def" } Index: clang/include/clang/Basic/OpenCLOptions.h =================================================================== --- clang/include/clang/Basic/OpenCLOptions.h +++ clang/include/clang/Basic/OpenCLOptions.h @@ -74,14 +74,18 @@ // Option becomes optional core feature in this OpenCL versions unsigned Opt; + // Does this option have pragma. + bool WithPragma = false; + // Is this option supported bool Supported = false; // Is this option enabled bool Enabled = false; - OpenCLOptionInfo(unsigned A = 100, unsigned C = 0U, unsigned O = 0U) - : Avail(A), Core(C), Opt(O) {} + OpenCLOptionInfo(unsigned A = 100, unsigned C = 0U, unsigned O = 0U, + bool Pragma = false) + : Avail(A), Core(C), Opt(O), WithPragma(Pragma) {} bool isCore() const { return Core != 0U; } @@ -109,6 +113,8 @@ bool isEnabled(llvm::StringRef Ext) const; + bool isWithPragma(llvm::StringRef Ext) const; + // Is supported as either an extension or an (optional) core feature for // OpenCL version \p LO. bool isSupported(llvm::StringRef Ext, const LangOptions &LO) const; @@ -131,6 +137,11 @@ // 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 Index: clang/include/clang/Basic/OpenCLExtensions.def =================================================================== --- clang/include/clang/Basic/OpenCLExtensions.def +++ 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 if false. // avail - minimum OpenCL version supporting it. // core - OpenCL versions mask when the extension becomes core feature. // 0U indicates not a core feature. @@ -50,67 +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_COREFEATURE(cl_khr_3d_image_writes, 100, OCL_C_20) +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, 300, OCL_C_30) -OPENCL_OPTIONALCOREFEATURE(__opencl_c_generic_address_space, 300, OCL_C_30) -OPENCL_OPTIONALCOREFEATURE(__opencl_c_atomic_order_acq_rel, 300, OCL_C_30) -OPENCL_OPTIONALCOREFEATURE(__opencl_c_atomic_order_seq_cst, 300, OCL_C_30) -OPENCL_OPTIONALCOREFEATURE(__opencl_c_subgroups, 300, OCL_C_30) -OPENCL_OPTIONALCOREFEATURE(__opencl_c_3d_image_writes, 300, OCL_C_30) -OPENCL_OPTIONALCOREFEATURE(__opencl_c_device_enqueue, 300, OCL_C_30) -OPENCL_OPTIONALCOREFEATURE(__opencl_c_read_write_images, 300, OCL_C_30) -OPENCL_OPTIONALCOREFEATURE(__opencl_c_program_scope_global_variables, 300, OCL_C_30) -OPENCL_OPTIONALCOREFEATURE(__opencl_c_fp64, 300, OCL_C_30) -OPENCL_OPTIONALCOREFEATURE(__opencl_c_images, 300, OCL_C_30) +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
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits