Author: Anton Zabaznov Date: 2021-07-13T15:38:23+03:00 New Revision: ab76101f40f80bbec82073fc5bfddd7203e63a52
URL: https://github.com/llvm/llvm-project/commit/ab76101f40f80bbec82073fc5bfddd7203e63a52 DIFF: https://github.com/llvm/llvm-project/commit/ab76101f40f80bbec82073fc5bfddd7203e63a52.diff LOG: [OpenCL] Add support of __opencl_c_read_write_images feature macro This feature requires support of __opencl_c_images, so diagnostics for that is provided as well Reviewed By: Anastasia Differential Revision: https://reviews.llvm.org/D104915 Added: Modified: clang/include/clang/Basic/DiagnosticCommonKinds.td clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Basic/OpenCLOptions.h clang/lib/Basic/OpenCLOptions.cpp clang/lib/Basic/Targets.cpp clang/lib/Sema/SemaDeclAttr.cpp clang/test/Misc/opencl-c-3.0.incorrect_options.cl clang/test/SemaOpenCL/access-qualifier.cl clang/test/SemaOpenCL/unsupported-image.cl Removed: ################################################################################ diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index 4dab3a3b39ac3..eea5d8eaa10a1 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -367,4 +367,6 @@ def warn_opencl_unsupported_core_feature : Warning< def err_opencl_extension_and_feature_ diff ers : Error< "options %0 and %1 are set to diff erent values">; +def err_opencl_feature_requires : Error< + "feature %0 requires support of %1 feature">; } diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 21b9ce2d9ff2a..2d62163e3dcc0 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10111,7 +10111,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/OpenCLOptions.h b/clang/include/clang/Basic/OpenCLOptions.h index 44fda029411f1..41db6b712a631 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 @@ -179,6 +182,16 @@ class OpenCLOptions { return OpenCLOptionInfo(std::forward<Args>(args)...).isAvailableIn(LO); } + // Diagnose feature dependencies for OpenCL C 3.0. Return false if target + // doesn't follow these requirements. + static bool diagnoseUnsupportedFeatureDependencies(const TargetInfo &TI, + DiagnosticsEngine &Diags); + + // Diagnose that features and equivalent extension are set to same values. + // Return false if target doesn't follow these requirements. + static bool diagnoseFeatureExtensionDifferences(const TargetInfo &TI, + DiagnosticsEngine &Diags); + private: // Option is enabled via pragma bool isEnabled(llvm::StringRef Ext) const; diff --git a/clang/lib/Basic/OpenCLOptions.cpp b/clang/lib/Basic/OpenCLOptions.cpp index 7a647f02b1bd0..2e215b185f662 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 { @@ -104,4 +106,43 @@ void OpenCLOptions::disableAll() { Opt.getValue().Enabled = false; } +bool OpenCLOptions::diagnoseUnsupportedFeatureDependencies( + const TargetInfo &TI, DiagnosticsEngine &Diags) { + // Feature pairs. First feature in a pair requires the second one to be + // supported. + static const llvm::StringMap<llvm::StringRef> DependentFeaturesMap = { + {"__opencl_c_read_write_images", "__opencl_c_images"}}; + + auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts(); + + bool IsValid = true; + for (auto &FeaturePair : DependentFeaturesMap) + if (TI.hasFeatureEnabled(OpenCLFeaturesMap, FeaturePair.getKey()) && + !TI.hasFeatureEnabled(OpenCLFeaturesMap, FeaturePair.getValue())) { + IsValid = false; + Diags.Report(diag::err_opencl_feature_requires) + << FeaturePair.getKey() << FeaturePair.getValue(); + } + return IsValid; +} + +bool OpenCLOptions::diagnoseFeatureExtensionDifferences( + const TargetInfo &TI, DiagnosticsEngine &Diags) { + // Extensions and equivalent feature pairs. + static const llvm::StringMap<llvm::StringRef> FeatureExtensionMap = { + {"cl_khr_fp64", "__opencl_c_fp64"}}; + + 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_ diff ers) + << ExtAndFeat.getKey() << ExtAndFeat.getValue(); + } + return IsValid; +} + } // end namespace clang diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 0755a946921e8..ba91d0439968c 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -748,15 +748,6 @@ bool TargetInfo::validateOpenCLTarget(const LangOptions &Opts, if (Opts.OpenCLCPlusPlus || Opts.OpenCLVersion < 300) return true; - // Feature and corresponding equivalent extension must be set - // simultaneously to the same value. - for (auto &ExtAndFeat : {std::make_pair("cl_khr_fp64", "__opencl_c_fp64")}) - if (hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.first) != - hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.second)) { - Diags.Report(diag::err_opencl_extension_and_feature_ diff ers) - << ExtAndFeat.first << ExtAndFeat.second; - return false; - } - - return true; + return OpenCLOptions::diagnoseUnsupportedFeatureDependencies(*this, Diags) && + OpenCLOptions::diagnoseFeatureExtensionDifferences(*this, Diags); } diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 5db74630de799..87e5531a77056 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -7395,16 +7395,21 @@ static void handleOpenCLAccessAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } } - // OpenCL v2.0 s6.6 - read_write can be used for image types to specify that an - // image object can be read and written. - // OpenCL v2.0 s6.13.6 - A kernel cannot read from and write to the same pipe - // object. Using the read_write (or __read_write) qualifier with the pipe - // qualifier is a compilation error. + // OpenCL v2.0 s6.6 - read_write can be used for image types to specify that + // an image object can be read and written. OpenCL v2.0 s6.13.6 - A kernel + // cannot read from and write to the same pipe object. Using the read_write + // (or __read_write) qualifier with the pipe qualifier is a compilation error. + // OpenCL v3.0 s6.8 - For OpenCL C 2.0, or with the + // __opencl_c_read_write_images feature, image objects specified as arguments + // to a kernel can additionally be declared to be read-write. if (const auto *PDecl = dyn_cast<ParmVarDecl>(D)) { const Type *DeclTy = PDecl->getType().getCanonicalType().getTypePtr(); if (AL.getAttrName()->getName().find("read_write") != StringRef::npos) { if ((!S.getLangOpts().OpenCLCPlusPlus && - S.getLangOpts().OpenCLVersion < 200) || + (S.getLangOpts().OpenCLVersion < 200) || + (S.getLangOpts().OpenCLVersion == 300 && + !S.getOpenCLOptions().isSupported("__opencl_c_read_write_images", + S.getLangOpts()))) || DeclTy->isPipeType()) { S.Diag(AL.getLoc(), diag::err_opencl_invalid_read_write) << AL << PDecl->getType() << DeclTy->isImageType(); diff --git a/clang/test/Misc/opencl-c-3.0.incorrect_options.cl b/clang/test/Misc/opencl-c-3.0.incorrect_options.cl index 493c5fde10541..07151d9a08c81 100644 --- a/clang/test/Misc/opencl-c-3.0.incorrect_options.cl +++ b/clang/test/Misc/opencl-c-3.0.incorrect_options.cl @@ -1,4 +1,6 @@ -// RUN: not %clang_cc1 -cl-std=CL3.0 -triple spir-unknown-unknown -cl-ext=-__opencl_c_fp64,+cl_khr_fp64 %s 2>&1 | FileCheck %s -// RUN: not %clang_cc1 -cl-std=CL3.0 -triple spir-unknown-unknown -cl-ext=+__opencl_c_fp64,-cl_khr_fp64 %s 2>&1 | FileCheck %s +// RUN: not %clang_cc1 -cl-std=CL3.0 -triple spir-unknown-unknown -cl-ext=-__opencl_c_fp64,+cl_khr_fp64 %s 2>&1 | FileCheck -check-prefix=CHECK-FP64 %s +// RUN: not %clang_cc1 -cl-std=CL3.0 -triple spir-unknown-unknown -cl-ext=+__opencl_c_fp64,-cl_khr_fp64 %s 2>&1 | FileCheck -check-prefix=CHECK-FP64 %s +// RUN: not %clang_cc1 -cl-std=CL3.0 -triple spir-unknown-unknown -cl-ext=+__opencl_c_read_write_images,-__opencl_c_images %s 2>&1 | FileCheck -check-prefix=CHECK-READ-WRITE-IMAGES %s -// CHECK: error: options cl_khr_fp64 and __opencl_c_fp64 are set to diff erent values +// CHECK-FP64: error: options cl_khr_fp64 and __opencl_c_fp64 are set to diff erent values +// CHECK-READ-WRITE-IMAGES: error: feature __opencl_c_read_write_images requires support of __opencl_c_images feature diff --git a/clang/test/SemaOpenCL/access-qualifier.cl b/clang/test/SemaOpenCL/access-qualifier.cl index 115944c9f3e79..c538e73253ce0 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 -cl-ext=-cl_khr_3d_image_writes -// 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 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/unsupported-image.cl b/clang/test/SemaOpenCL/unsupported-image.cl index 3aed9c1f13199..9ffbb1aef0c46 100644 --- a/clang/test/SemaOpenCL/unsupported-image.cl +++ b/clang/test/SemaOpenCL/unsupported-image.cl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple spir-unknown-unknown -verify -cl-std=CL3.0 -cl-ext=-__opencl_c_images %s +// RUN: %clang_cc1 -triple spir-unknown-unknown -verify -cl-std=CL3.0 -cl-ext=-__opencl_c_images,-__opencl_c_read_write_images %s // RUN: %clang_cc1 -triple spir-unknown-unknown -verify -cl-std=CL3.0 -cl-ext=+__opencl_c_images %s #ifdef __opencl_c_images _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits