[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
This commit is contained in:
parent
4709d9d5be
commit
ab76101f40
|
@ -367,4 +367,6 @@ def warn_opencl_unsupported_core_feature : Warning<
|
|||
|
||||
def err_opencl_extension_and_feature_differs : Error<
|
||||
"options %0 and %1 are set to different values">;
|
||||
def err_opencl_feature_requires : Error<
|
||||
"feature %0 requires support of %1 feature">;
|
||||
}
|
||||
|
|
|
@ -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<
|
||||
|
|
|
@ -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 @@ public:
|
|||
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;
|
||||
|
|
|
@ -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_differs)
|
||||
<< ExtAndFeat.getKey() << ExtAndFeat.getValue();
|
||||
}
|
||||
return IsValid;
|
||||
}
|
||||
|
||||
} // end namespace clang
|
||||
|
|
|
@ -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_differs)
|
||||
<< ExtAndFeat.first << ExtAndFeat.second;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return OpenCLOptions::diagnoseUnsupportedFeatureDependencies(*this, Diags) &&
|
||||
OpenCLOptions::diagnoseFeatureExtensionDifferences(*this, Diags);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 different values
|
||||
// CHECK-FP64: error: options cl_khr_fp64 and __opencl_c_fp64 are set to different values
|
||||
// CHECK-READ-WRITE-IMAGES: error: feature __opencl_c_read_write_images requires support of __opencl_c_images feature
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue