Author: Justas Janickas
Date: 2021-09-17T14:14:31+01:00
New Revision: b7e9d203c6793873f72dd3ffaf7c9365ce03007e

URL: 
https://github.com/llvm/llvm-project/commit/b7e9d203c6793873f72dd3ffaf7c9365ce03007e
DIFF: 
https://github.com/llvm/llvm-project/commit/b7e9d203c6793873f72dd3ffaf7c9365ce03007e.diff

LOG: [OpenCL] Supports optional same image reads and writes in C++ for OpenCL 
2021

Adds support for a feature macro `__opencl_c_read_write_images` in
C++ for OpenCL 2021 enabling a respective optional core feature
from OpenCL 3.0.

This change aims to achieve compatibility between C++ for OpenCL
2021 and OpenCL 3.0.

Differential Revision: https://reviews.llvm.org/D109307

Added: 
    

Modified: 
    clang/lib/Sema/SemaDeclAttr.cpp
    clang/test/Misc/opencl-c-3.0.incorrect_options.cl
    clang/test/SemaOpenCL/access-qualifier.cl

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 35c32043e377..8092aeb21ada 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -7552,18 +7552,17 @@ static void handleOpenCLAccessAttr(Sema &S, Decl *D, 
const ParsedAttr &AL) {
   // 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.
-  // C++ for OpenCL inherits rule from OpenCL C v2.0.
+  // C++ for OpenCL 1.0 inherits rule from OpenCL C v2.0.
+  // C++ for OpenCL 2021 inherits rule from OpenCL C v3.0.
   if (const auto *PDecl = dyn_cast<ParmVarDecl>(D)) {
     const Type *DeclTy = PDecl->getType().getCanonicalType().getTypePtr();
     if (AL.getAttrName()->getName().find("read_write") != StringRef::npos) {
-      bool ReadWriteImagesUnsupportedForOCLC =
-          (S.getLangOpts().OpenCLVersion < 200) ||
-          (S.getLangOpts().OpenCLVersion == 300 &&
+      bool ReadWriteImagesUnsupported =
+          (S.getLangOpts().getOpenCLCompatibleVersion() < 200) ||
+          (S.getLangOpts().getOpenCLCompatibleVersion() == 300 &&
            !S.getOpenCLOptions().isSupported("__opencl_c_read_write_images",
                                              S.getLangOpts()));
-      if ((!S.getLangOpts().OpenCLCPlusPlus &&
-           ReadWriteImagesUnsupportedForOCLC) ||
-          DeclTy->isPipeType()) {
+      if (ReadWriteImagesUnsupported || DeclTy->isPipeType()) {
         S.Diag(AL.getLoc(), diag::err_opencl_invalid_read_write)
             << AL << PDecl->getType() << DeclTy->isImageType();
         D->setInvalidDecl(true);

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 3ce0f325ce91..6232806c5c6d 100644
--- a/clang/test/Misc/opencl-c-3.0.incorrect_options.cl
+++ b/clang/test/Misc/opencl-c-3.0.incorrect_options.cl
@@ -3,6 +3,7 @@
 // RUN: not %clang_cc1 -cl-std=clc++2021 -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=clc++2021 -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
+// RUN: not %clang_cc1 -cl-std=clc++2021 -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
 // RUN: not %clang_cc1 -cl-std=CL3.0 -triple spir-unknown-unknown 
-cl-ext=+__opencl_c_pipes,-__opencl_c_generic_address_space %s 2>&1 | FileCheck 
-check-prefix=CHECK-PIPES %s
 // RUN: not %clang_cc1 -cl-std=clc++2021 -triple spir-unknown-unknown 
-cl-ext=+__opencl_c_pipes,-__opencl_c_generic_address_space %s 2>&1 | FileCheck 
-check-prefix=CHECK-PIPES %s
 // RUN: not %clang_cc1 -cl-std=CL3.0 -triple spir-unknown-unknown 
-cl-ext=+__opencl_c_3d_image_writes,+__opencl_c_images,-cl_khr_3d_image_writes 
%s 2>&1 | FileCheck -check-prefix=CHECK-3D-WRITE-IMAGES-DIFF %s

diff  --git a/clang/test/SemaOpenCL/access-qualifier.cl 
b/clang/test/SemaOpenCL/access-qualifier.cl
index fc6ad750e717..726253c0b1a2 100644
--- a/clang/test/SemaOpenCL/access-qualifier.cl
+++ b/clang/test/SemaOpenCL/access-qualifier.cl
@@ -2,24 +2,38 @@
 // 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
+// RUN: %clang_cc1 -triple spir-unknown-unknown -verify -pedantic 
-fsyntax-only -cl-std=clc++2021 %s
+// RUN: %clang_cc1 -triple spir-unknown-unknown -verify -pedantic 
-fsyntax-only -cl-std=clc++2021 %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) || (__OPENCL_C_VERSION__ == 300 && 
defined(__opencl_c_read_write_images))
+#if (__OPENCL_C_VERSION__ == 200) || ((__OPENCL_CPP_VERSION__ == 202100 || 
__OPENCL_C_VERSION__ == 300) && defined(__opencl_c_read_write_images))
 typedef read_write image1d_t img1d_rw;
 #endif
 
 typedef int Int;
 typedef read_only int IntRO; // expected-error {{access qualifier can only be 
used for pipe and image type}}
 
+void myWrite(write_only image1d_t);
+#if !defined(__OPENCL_CPP_VERSION__)
+// expected-note@-2 {{passing argument to parameter here}}
+// expected-note@-3 {{passing argument to parameter here}}
+#else
+// expected-note@-5 {{candidate function not viable: no known conversion from 
'__private img1d_ro' (aka '__private __read_only image1d_t') to '__private 
__write_only image1d_t' for 1st argument}}
+// expected-note@-6 {{candidate function not viable: no known conversion from 
'__private img1d_ro_default' (aka '__private __read_only image1d_t') to 
'__private __write_only image1d_t' for 1st argument}}
+#endif
 
-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}}
+void myRead(read_only image1d_t);
+#if !defined(__OPENCL_CPP_VERSION__)
+// expected-note@-2 {{passing argument to parameter here}}
+#else
+// expected-note@-4 {{candidate function not viable: no known conversion from 
'__private img1d_wo' (aka '__private __write_only image1d_t') to '__private 
__read_only image1d_t' for 1st argument}}
+#endif
 
-#if (__OPENCL_C_VERSION__ == 200) || (__OPENCL_C_VERSION__ == 300 && 
defined(__opencl_c_read_write_images))
+#if (__OPENCL_C_VERSION__ == 200) || ((__OPENCL_CPP_VERSION__ == 202100 || 
__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 C 
version 2.0 or in version 3.0 and without __opencl_c_read_write_images feature}}
@@ -27,25 +41,40 @@ void myReadWrite(read_write image1d_t); // expected-error 
{{access qualifier 're
 
 
 kernel void k1(img1d_wo img) {
-  myRead(img); // expected-error {{passing '__private img1d_wo' (aka 
'__private __write_only image1d_t') to parameter of incompatible type 
'__read_only image1d_t'}}
+  myRead(img);
+#if !defined(__OPENCL_CPP_VERSION__)
+// expected-error@-2 {{passing '__private img1d_wo' (aka '__private 
__write_only image1d_t') to parameter of incompatible type '__read_only 
image1d_t'}}
+#else
+// expected-error@-4 {{no matching function for call to 'myRead'}}
+#endif
 }
 
 kernel void k2(img1d_ro img) {
-  myWrite(img); // expected-error {{passing '__private img1d_ro' (aka 
'__private __read_only image1d_t') to parameter of incompatible type 
'__write_only image1d_t'}}
+  myWrite(img);
+#if !defined(__OPENCL_CPP_VERSION__)
+// expected-error@-2 {{passing '__private img1d_ro' (aka '__private 
__read_only image1d_t') to parameter of incompatible type '__write_only 
image1d_t'}}
+#else
+// expected-error@-4 {{no matching function for call to 'myWrite'}}
+#endif
 }
 
 kernel void k3(img1d_wo img) {
   myWrite(img);
 }
 
-#if (__OPENCL_C_VERSION__ == 200) || (__OPENCL_C_VERSION__ == 300 && 
defined(__opencl_c_read_write_images))
+#if (__OPENCL_C_VERSION__ == 200) || ((__OPENCL_CPP_VERSION__ == 202100 || 
__OPENCL_C_VERSION__ == 300) && defined(__opencl_c_read_write_images))
 kernel void k4(img1d_rw img) {
   myReadWrite(img);
 }
 #endif
 
 kernel void k5(img1d_ro_default img) {
-  myWrite(img); // expected-error {{passing '__private img1d_ro_default' (aka 
'__private __read_only image1d_t') to parameter of incompatible type 
'__write_only image1d_t'}}
+  myWrite(img);
+#if !defined(__OPENCL_CPP_VERSION__)
+// expected-error@-2 {{passing '__private img1d_ro_default' (aka '__private 
__read_only image1d_t') to parameter of incompatible type '__write_only 
image1d_t'}}
+#else
+// expected-error@-4 {{no matching function for call to 'myWrite'}}
+#endif
 }
 
 kernel void k6(img1d_ro img) {
@@ -64,19 +93,19 @@ 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) || (__OPENCL_C_VERSION__ == 300 && 
defined(__opencl_c_read_write_images))
+#if (__OPENCL_C_VERSION__ == 200) || ((__OPENCL_CPP_VERSION__ == 202100 || 
__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 C version 2.0 or in version 3.0 and without __opencl_c_read_write_images 
feature}}
 #endif
 
-#if __OPENCL_C_VERSION__ < 200
+#if defined(__OPENCL_C_VERSION__) && __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) || (__OPENCL_C_VERSION__ == 300 && 
defined(__opencl_c_read_write_images))
+#if (__OPENCL_C_VERSION__ == 200) || ((__OPENCL_CPP_VERSION__ == 202100 || 
__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@-67 {{previously declared 'read_write' here}}
+// expected-note@-94 {{previously declared 'read_write' here}}
 #endif
 
 #if __OPENCL_C_VERSION__ >= 200
@@ -101,12 +130,11 @@ kernel void pass_ro_typedef_to_wo(ROPipeInt p) {
 #endif
 
 kernel void read_only_twice_typedef(__read_only img1d_ro i){} // 
expected-warning {{duplicate '__read_only' declaration specifier}}
-// expected-note@-95 {{previously declared 'read_only' here}}
+// expected-note@-122 {{previously declared 'read_only' here}}
 
 kernel void read_only_twice_default(read_only img1d_ro_default img){} // 
expected-warning {{duplicate 'read_only' declaration specifier}}
-// expected-note@-101 {{previously declared 'read_only' here}}
+// expected-note@-128 {{previously declared 'read_only' here}}
 
 kernel void image_wo_twice(write_only __write_only image1d_t i){} // 
expected-warning {{duplicate '__write_only' declaration specifier}}
 kernel void image_wo_twice_typedef(write_only img1d_wo i){} // 
expected-warning {{duplicate 'write_only' declaration specifier}}
-// expected-note@-103 {{previously declared 'write_only' here}}
-
+// expected-note@-130 {{previously declared 'write_only' here}}


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to