[clang] ab76101 - [OpenCL] Add support of __opencl_c_read_write_images feature macro
Anton Zabaznov via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 13 05:38:30 PDT 2021
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 at -74 {{previously declared 'read_write' here}}
+// expected-note at -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 at -25 {{passing argument to parameter here}}
+ // expected-note at -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
More information about the cfe-commits
mailing list