From dd1268ce8e9b56ded8322583e04bbb4d9b0f1eef Mon Sep 17 00:00:00 2001 From: Anastasia Stulova Date: Wed, 18 Mar 2015 12:55:29 +0000 Subject: [PATCH] OpenCL: CL2.0 atomic types OpenCL C Spec v2.0 Section 6.13.11 - Made c11 _Atomic being not accepted for OpenCL - Implemented CL2.0 atomics by aliasing them to the corresponding c11 atomic types using implicit typedef - Added diagnostics for atomics Khronos extension enabling git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@232631 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 4 +- include/clang/Basic/TokenKinds.def | 3 +- lib/Basic/IdentifierTable.cpp | 15 ++++-- lib/Sema/Sema.cpp | 23 +++++++++ lib/Sema/SemaType.cpp | 27 ++++++++++- test/Parser/opencl-atomics-cl20.cl | 56 ++++++++++++++++++++++ 6 files changed, 120 insertions(+), 8 deletions(-) create mode 100644 test/Parser/opencl-atomics-cl20.cl diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 085cafff78..b7ab489117 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -7124,8 +7124,8 @@ def ext_c99_array_usage : Extension< def err_c99_array_usage_cxx : Error< "%select{qualifier in |static |}0array size %select{||'[*] '}0is a C99 " "feature, not permitted in C++">; -def err_double_requires_fp64 : Error< - "use of type 'double' requires cl_khr_fp64 extension to be enabled">; + def err_type_requires_extension : Error< + "use of type %0 requires %1 extension to be enabled">; def err_int128_unsupported : Error< "__int128 is not supported on this target">; def err_nsconsumed_attribute_mismatch : Error< diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def index 2382dbf048..f33561ba42 100644 --- a/include/clang/Basic/TokenKinds.def +++ b/include/clang/Basic/TokenKinds.def @@ -228,6 +228,7 @@ PUNCTUATOR(greatergreatergreater, ">>>") // KEYNOMS18 - This is a keyword that must never be enabled under // MSVC <= v18. // KEYOPENCL - This is a keyword in OpenCL +// KEYNOOPENCL - This is a keyword that is not supported in OpenCL // KEYALTIVEC - This is a keyword in AltiVec // KEYBORLAND - This is a keyword if Borland extensions are enabled // BOOLSUPPORT - This is a keyword if 'bool' is a built-in type @@ -270,7 +271,7 @@ KEYWORD(volatile , KEYALL) KEYWORD(while , KEYALL) KEYWORD(_Alignas , KEYALL) KEYWORD(_Alignof , KEYALL) -KEYWORD(_Atomic , KEYALL|KEYNOMS18) +KEYWORD(_Atomic , KEYALL|KEYNOMS18|KEYNOOPENCL) KEYWORD(_Bool , KEYNOCXX) KEYWORD(_Complex , KEYALL) KEYWORD(_Generic , KEYALL) diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp index db148f493f..bd2840db4c 100644 --- a/lib/Basic/IdentifierTable.cpp +++ b/lib/Basic/IdentifierTable.cpp @@ -106,9 +106,11 @@ namespace { KEYC11 = 0x400, KEYARC = 0x800, KEYNOMS18 = 0x01000, - WCHARSUPPORT = 0x02000, - HALFSUPPORT = 0x04000, - KEYALL = (0xffff & ~KEYNOMS18) // Because KEYNOMS18 is used to exclude. + KEYNOOPENCL = 0x02000, + WCHARSUPPORT = 0x04000, + HALFSUPPORT = 0x08000, + KEYALL = (0xffff & ~KEYNOMS18 & + ~KEYNOOPENCL) // KEYNOMS18 and KEYNOOPENCL are used to exclude. }; /// \brief How a keyword is treated in the selected standard. @@ -156,7 +158,12 @@ static void AddKeyword(StringRef Keyword, // Don't add this keyword under MSVCCompat. if (LangOpts.MSVCCompat && (Flags & KEYNOMS18) && !LangOpts.isCompatibleWithMSVC(19)) - return; + return; + + // Don't add this keyword under OpenCL. + if (LangOpts.OpenCL && (Flags & KEYNOOPENCL)) + return; + // Don't add this keyword if disabled in this language. if (AddResult == KS_Disabled) return; diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index a851ce1455..a1a9b9d0b8 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -212,6 +212,29 @@ void Sema::Initialize() { addImplicitTypedef("image3d_t", Context.OCLImage3dTy); addImplicitTypedef("sampler_t", Context.OCLSamplerTy); addImplicitTypedef("event_t", Context.OCLEventTy); + if (getLangOpts().OpenCLVersion >= 200) { + addImplicitTypedef("atomic_int", Context.getAtomicType(Context.IntTy)); + addImplicitTypedef("atomic_uint", + Context.getAtomicType(Context.UnsignedIntTy)); + addImplicitTypedef("atomic_long", Context.getAtomicType(Context.LongTy)); + addImplicitTypedef("atomic_ulong", + Context.getAtomicType(Context.UnsignedLongTy)); + addImplicitTypedef("atomic_float", + Context.getAtomicType(Context.FloatTy)); + addImplicitTypedef("atomic_double", + Context.getAtomicType(Context.DoubleTy)); + // OpenCLC v2.0, s6.13.11.6 requires that atomic_flag is implemented as + // 32-bit integer and OpenCLC v2.0, s6.1.1 int is always 32-bit wide. + addImplicitTypedef("atomic_flag", Context.getAtomicType(Context.IntTy)); + addImplicitTypedef("atomic_intptr_t", + Context.getAtomicType(Context.getIntPtrType())); + addImplicitTypedef("atomic_uintptr_t", + Context.getAtomicType(Context.getUIntPtrType())); + addImplicitTypedef("atomic_size_t", + Context.getAtomicType(Context.getSizeType())); + addImplicitTypedef("atomic_ptrdiff_t", + Context.getAtomicType(Context.getPointerDiffType())); + } } DeclarationName BuiltinVaList = &Context.Idents.get("__builtin_va_list"); diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 56142253a0..669cb9a977 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -871,7 +871,8 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { if (S.getLangOpts().OpenCL && !((S.getLangOpts().OpenCLVersion >= 120) || S.getOpenCLOptions().cl_khr_fp64)) { - S.Diag(DS.getTypeSpecTypeLoc(), diag::err_double_requires_fp64); + S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension) + << Result << "cl_khr_fp64"; declarator.setInvalidType(true); } break; @@ -947,6 +948,30 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { << DS.getSourceRange(); declarator.setInvalidType(true); } + } else if (S.getLangOpts().OpenCL) { + if (const AtomicType *AT = Result->getAs()) { + const BuiltinType *BT = AT->getValueType()->getAs(); + bool NoExtTypes = BT && (BT->getKind() == BuiltinType::Int || + BT->getKind() == BuiltinType::UInt || + BT->getKind() == BuiltinType::Float); + if (!S.getOpenCLOptions().cl_khr_int64_base_atomics && !NoExtTypes) { + S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension) + << Result << "cl_khr_int64_base_atomics"; + declarator.setInvalidType(true); + } + if (!S.getOpenCLOptions().cl_khr_int64_extended_atomics && + !NoExtTypes) { + S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension) + << Result << "cl_khr_int64_extended_atomics"; + declarator.setInvalidType(true); + } + if (!S.getOpenCLOptions().cl_khr_fp64 && BT && + BT->getKind() == BuiltinType::Double) { + S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension) + << Result << "cl_khr_fp64"; + declarator.setInvalidType(true); + } + } } // TypeQuals handled by caller. diff --git a/test/Parser/opencl-atomics-cl20.cl b/test/Parser/opencl-atomics-cl20.cl new file mode 100644 index 0000000000..c62142b2aa --- /dev/null +++ b/test/Parser/opencl-atomics-cl20.cl @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only +// RUN: %clang_cc1 %s -verify -fsyntax-only -cl-std=CL2.0 -DCL20 +// RUN: %clang_cc1 %s -verify -fsyntax-only -cl-std=CL2.0 -DCL20 -DEXT + +#ifdef EXT +#pragma OPENCL EXTENSION cl_khr_int64_base_atomics:enable +#pragma OPENCL EXTENSION cl_khr_int64_extended_atomics:enable +#pragma OPENCL EXTENSION cl_khr_fp64:enable +#endif + +void atomic_types_test() { +// OpenCL v2.0 s6.13.11.6 defines supported atomic types. + atomic_int i; + atomic_uint ui; + atomic_long l; + atomic_ulong ul; + atomic_float f; + atomic_double d; + atomic_flag fl; + atomic_intptr_t ip; + atomic_uintptr_t uip; + atomic_size_t s; + atomic_ptrdiff_t pd; +// OpenCL v2.0 s6.13.11.8, _Atomic type specifier and _Atomic type qualifier +// are not supported by OpenCL. + _Atomic int i; // expected-error {{use of undeclared identifier '_Atomic'}} +} +#ifndef CL20 +// expected-error@-16 {{use of undeclared identifier 'atomic_int'}} +// expected-error@-16 {{use of undeclared identifier 'atomic_uint'}} +// expected-error@-16 {{use of undeclared identifier 'atomic_long'}} +// expected-error@-16 {{use of undeclared identifier 'atomic_ulong'}} +// expected-error@-16 {{use of undeclared identifier 'atomic_float'}} +// expected-error@-16 {{use of undeclared identifier 'atomic_double'}} +// expected-error@-16 {{use of undeclared identifier 'atomic_flag'}} +// expected-error@-16 {{use of undeclared identifier 'atomic_intptr_t'}} +// expected-error@-16 {{use of undeclared identifier 'atomic_uintptr_t'}} +// expected-error@-16 {{use of undeclared identifier 'atomic_size_t'}} +// expected-error@-16 {{use of undeclared identifier 'atomic_ptrdiff_t'}} +#elif !EXT +// expected-error@-26 {{use of type 'atomic_long' (aka '_Atomic(long)') requires cl_khr_int64_base_atomics extension to be enabled}} +// expected-error@-27 {{use of type 'atomic_long' (aka '_Atomic(long)') requires cl_khr_int64_extended_atomics extension to be enabled}} +// expected-error@-27 {{use of type 'atomic_ulong' (aka '_Atomic(unsigned long)') requires cl_khr_int64_base_atomics extension to be enabled}} +// expected-error@-28 {{use of type 'atomic_ulong' (aka '_Atomic(unsigned long)') requires cl_khr_int64_extended_atomics extension to be enabled}} +// expected-error@-27 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_base_atomics extension to be enabled}} +// expected-error@-28 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_extended_atomics extension to be enabled}} +// expected-error@-29 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_fp64 extension to be enabled}} +// expected-error-re@-28 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} +// expected-error-re@-29 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} +// expected-error-re@-29 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} +// expected-error-re@-30 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} +// expected-error-re@-30 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} +// expected-error-re@-31 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} +// expected-error-re@-31 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} +// expected-error-re@-32 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} +#endif -- 2.40.0