diff --git a/clang/include/clang/Basic/OpenCLExtensions.def b/clang/include/clang/Basic/OpenCLExtensions.def --- a/clang/include/clang/Basic/OpenCLExtensions.def +++ b/clang/include/clang/Basic/OpenCLExtensions.def @@ -64,7 +64,7 @@ OPENCL_EXTENSION(cl_khr_fp16, 100) OPENCL_EXTENSION(cl_khr_int64_base_atomics, 100) OPENCL_EXTENSION(cl_khr_int64_extended_atomics, 100) -OPENCL_GENERIC_EXTENSION(cl_khr_3d_image_writes, 100, OCL_C_20, OCL_C_30) +OPENCL_COREFEATURE(cl_khr_3d_image_writes, 100, OCL_C_20) // EMBEDDED_PROFILE OPENCL_EXTENSION(cles_khr_int64, 110) @@ -99,6 +99,18 @@ OPENCL_EXTENSION(cl_intel_subgroups_short, 120) OPENCL_EXTENSION(cl_intel_device_side_avc_motion_estimation, 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) #undef OPENCL_OPTIONALCOREFEATURE #undef OPENCL_COREFEATURE diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -720,7 +720,9 @@ /// and language version void TargetInfo::getOpenCLFeatureDefines(const LangOptions &Opts, MacroBuilder &Builder) const { - + // FIXME: OpenCL options which affect language semantics/syntax + // should be moved into LangOptions, thus macro definitions of + // such options is better to be done in clang::InitializePreprocessor auto defineOpenCLExtMacro = [&](llvm::StringRef Name, unsigned AvailVer, unsigned CoreVersions, unsigned OptionalVersions) { @@ -737,7 +739,6 @@ defineOpenCLExtMacro(#Ext, Avail, Core, Opt); #include "clang/Basic/OpenCLExtensions.def" - // FIXME: OpenCL options which affect language semantics/syntax - // should be moved into LangOptions, thus macro definitions of - // such options is better to be done in clang::InitializePreprocessor + // Assume compiling for FULL profile + Builder.defineMacro("__opencl_c_int64"); } diff --git a/clang/lib/Headers/opencl-c-base.h b/clang/lib/Headers/opencl-c-base.h --- a/clang/lib/Headers/opencl-c-base.h +++ b/clang/lib/Headers/opencl-c-base.h @@ -24,6 +24,21 @@ #endif // defined(__SPIR__) #endif // (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200) +// Define feature macros for OpenCL C 2.0 +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ == 200) +#define __opencl_c_pipes 1 +#define __opencl_c_generic_address_space 1 +#define __opencl_c_work_group_collective_functions 1 +#define __opencl_c_atomic_order_acq_rel 1 +#define __opencl_c_atomic_order_seq_cst 1 +#define __opencl_c_atomic_scope_device 1 +#define __opencl_c_atomic_scope_all_devices 1 +#define __opencl_c_device_enqueue 1 +#define __opencl_c_read_write_images 1 +#define __opencl_c_program_scope_global_variables 1 +#define __opencl_c_images 1 +#endif + // built-in scalar data types: /** diff --git a/clang/test/Headers/opencl-c-header.cl b/clang/test/Headers/opencl-c-header.cl --- a/clang/test/Headers/opencl-c-header.cl +++ b/clang/test/Headers/opencl-c-header.cl @@ -151,4 +151,88 @@ #endif //(defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200) +// OpenCL C features. +#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ == 200) + +#ifndef __opencl_c_pipes +#error "Feature macro __opencl_c_pipes should be defined" +#endif +#ifndef __opencl_c_generic_address_space +#error "Feature macro __opencl_c_generic_address_space should be defined" +#endif +#ifndef __opencl_c_work_group_collective_functions +#error "Feature macro __opencl_c_work_group_collective_functions should be defined" +#endif +#ifndef __opencl_c_atomic_order_acq_rel +#error "Feature macro __opencl_c_atomic_order_acq_rel should be defined" +#endif +#ifndef __opencl_c_atomic_order_seq_cst +#error "Feature macro __opencl_c_atomic_order_seq_cst should be defined" +#endif +#ifndef __opencl_c_atomic_scope_device +#error "Feature macro __opencl_c_atomic_scope_device should be defined" +#endif +#ifndef __opencl_c_atomic_scope_all_devices +#error "Feature macro __opencl_c_atomic_scope_all_devices should be defined" +#endif +#ifndef __opencl_c_device_enqueue +#error "Feature macro __opencl_c_device_enqueue should be defined" +#endif +#ifndef __opencl_c_read_write_images +#error "Feature macro __opencl_c_read_write_images should be defined" +#endif +#ifndef __opencl_c_program_scope_global_variables +#error "Feature macro __opencl_c_program_scope_global_variables should be defined" +#endif +#ifndef __opencl_c_images +#error "Feature macro __opencl_c_images should be defined" +#endif + +#elif (__OPENCL_C_VERSION__ < 200) + +#ifdef __opencl_c_pipes +#error "Incorret feature macro __opencl_c_pipes define" +#endif +#ifdef __opencl_c_generic_address_space +#error "Incorret feature macro __opencl_c_generic_address_space define" +#endif +#ifdef __opencl_c_work_group_collective_functions +#error "Incorret feature macro __opencl_c_work_group_collective_functions define" +#endif +#ifdef __opencl_c_atomic_order_acq_rel +#error "Incorret feature macro __opencl_c_atomic_order_acq_rel define" +#endif +#ifdef __opencl_c_atomic_order_seq_cst +#error "Incorret feature macro __opencl_c_atomic_order_seq_cst define" +#endif +#ifdef __opencl_c_atomic_scope_device +#error "Incorret feature macro __opencl_c_atomic_scope_device define" +#endif +#ifdef __opencl_c_atomic_scope_all_devices +#error "Incorret feature macro __opencl_c_atomic_scope_all_devices define" +#endif +#ifdef __opencl_c_device_enqueue +#error "Incorret feature macro __opencl_c_device_enqueue define" +#endif +#ifdef __opencl_c_read_write_images +#error "Incorret feature macro __opencl_c_read_write_images define" +#endif +#ifdef __opencl_c_program_scope_global_variables +#error "Incorret feature macro __opencl_c_program_scope_global_variables define" +#endif +#ifdef __opencl_c_images +#error "Incorret feature macro __opencl_c_images define" +#endif +#ifdef __opencl_c_3d_image_writes +#error "Incorret feature macro __opencl_c_3d_image_writes define" +#endif +#ifdef __opencl_c_fp64 +#error "Incorret feature macro __opencl_c_fp64 define" +#endif +#ifdef __opencl_c_subgroups +#error "Incorret feature macro __opencl_c_subgroups define" +#endif + +#endif //(defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ == 200) + #endif // defined(__SPIR__) diff --git a/clang/test/SemaOpenCL/features.cl b/clang/test/SemaOpenCL/features.cl new file mode 100644 --- /dev/null +++ b/clang/test/SemaOpenCL/features.cl @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -triple spir-unknown-unknown %s -E -dM -o - -x cl -cl-std=CL3.0 -cl-ext=-all \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=NO-FEATURES +// RUN: %clang_cc1 -triple spir-unknown-unknown %s -E -dM -o - -x cl -cl-std=CL3.0 -cl-ext=+all \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=FEATURES +// RUN: %clang_cc1 -triple r600-unknown-unknown %s -E -dM -o - -x cl -cl-std=CL3.0 \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=NO-FEATURES +// RUN: %clang_cc1 -triple r600-unknown-unknown %s -E -dM -o - -x cl -cl-std=CL3.0 -cl-ext=+all \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=FEATURES + +// For OpenCL C 2.0 feature macros are defined only in header, so test that earlier OpenCL +// versions don't define feature macros accidentally and CL2.0 don't define them without header +// RUN: %clang_cc1 -triple spir-unknown-unknown %s -E -dM -o - -x cl -cl-std=CL1.1 \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=NO-FEATURES +// RUN: %clang_cc1 -triple spir-unknown-unknown %s -E -dM -o - -x cl -cl-std=CL1.2 \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=NO-FEATURES +// RUN: %clang_cc1 -triple spir-unknown-unknown %s -E -dM -o - -x cl -cl-std=CL2.0 \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=NO-FEATURES +// RUN: %clang_cc1 -triple spir-unknown-unknown %s -E -dM -o - -x cl -cl-std=CLC++ \ +// RUN: | FileCheck -match-full-lines %s --check-prefix=NO-FEATURES + +// Note that __opencl_c_int64 is always defined assuming +// always compiling for FULL OpenCL profile + +// FEATURES: #define __opencl_c_3d_image_writes 1 +// FEATURES: #define __opencl_c_atomic_order_acq_rel 1 +// FEATURES: #define __opencl_c_atomic_order_seq_cst 1 +// FEATURES: #define __opencl_c_device_enqueue 1 +// FEATURES: #define __opencl_c_fp64 1 +// FEATURES: #define __opencl_c_generic_address_space 1 +// FEATURES: #define __opencl_c_images 1 +// FEATURES: #define __opencl_c_int64 1 +// FEATURES: #define __opencl_c_pipes 1 +// FEATURES: #define __opencl_c_program_scope_global_variables 1 +// FEATURES: #define __opencl_c_read_write_images 1 +// FEATURES: #define __opencl_c_subgroups 1 + +// NO-FEATURES: #define __opencl_c_int64 1 +// NO-FEATURES-NOT: __opencl_c_3d_image_writes +// NO-FEATURES-NOT: __opencl_c_atomic_order_acq_rel +// NO-FEATURES-NOT: __opencl_c_atomic_order_seq_cst +// NO-FEATURES-NOT: __opencl_c_device_enqueue +// NO-FEATURES-NOT: __opencl_c_fp64 +// NO-FEATURES-NOT: __opencl_c_generic_address_space +// NO-FEATURES-NOT: __opencl_c_images +// NO-FEATURES-NOT: __opencl_c_pipes +// NO-FEATURES-NOT: __opencl_c_program_scope_global_variables +// NO-FEATURES-NOT: __opencl_c_read_write_images +// NO-FEATURES-NOT: __opencl_c_subgroups