Author: Sven van Haastregt Date: 2022-02-17T10:58:52Z New Revision: 9798b33d1dc14f5334e2cc117e3896510fa57b82
URL: https://github.com/llvm/llvm-project/commit/9798b33d1dc14f5334e2cc117e3896510fa57b82 DIFF: https://github.com/llvm/llvm-project/commit/9798b33d1dc14f5334e2cc117e3896510fa57b82.diff LOG: [OpenCL] Guard 64-bit atomic types Until now, overloads with a 64-bit atomic type argument were always made available with `-fdeclare-opencl-builtins`. Ensure these overloads are only available when both the `cl_khr_int64_base_atomics` and `cl_khr_int64_extended_atomics` extensions have been enabled, as required by the OpenCL specification. Differential Revision: https://reviews.llvm.org/D119858 Added: Modified: clang/lib/Sema/OpenCLBuiltins.td clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/OpenCLBuiltins.td b/clang/lib/Sema/OpenCLBuiltins.td index 556d1778625e7..e6da5e34f7091 100644 --- a/clang/lib/Sema/OpenCLBuiltins.td +++ b/clang/lib/Sema/OpenCLBuiltins.td @@ -78,6 +78,8 @@ class concatExtension<FunctionExtension Base, string NewExts> { def NoTypeExt : TypeExtension<"">; def Fp16TypeExt : TypeExtension<"cl_khr_fp16">; def Fp64TypeExt : TypeExtension<"cl_khr_fp64">; +def Atomic64TypeExt : TypeExtension<"cl_khr_int64_base_atomics cl_khr_int64_extended_atomics">; +def AtomicFp64TypeExt : TypeExtension<"cl_khr_int64_base_atomics cl_khr_int64_extended_atomics cl_khr_fp64">; // FunctionExtension definitions. def FuncExtNone : FunctionExtension<"">; @@ -389,10 +391,14 @@ def NDRange : TypedefType<"ndrange_t">; // OpenCL v2.0 s6.13.11: Atomic integer and floating-point types. def AtomicInt : Type<"atomic_int", QualType<"Context.getAtomicType(Context.IntTy)">>; def AtomicUInt : Type<"atomic_uint", QualType<"Context.getAtomicType(Context.UnsignedIntTy)">>; -def AtomicLong : Type<"atomic_long", QualType<"Context.getAtomicType(Context.LongTy)">>; -def AtomicULong : Type<"atomic_ulong", QualType<"Context.getAtomicType(Context.UnsignedLongTy)">>; +let Extension = Atomic64TypeExt in { + def AtomicLong : Type<"atomic_long", QualType<"Context.getAtomicType(Context.LongTy)">>; + def AtomicULong : Type<"atomic_ulong", QualType<"Context.getAtomicType(Context.UnsignedLongTy)">>; +} def AtomicFloat : Type<"atomic_float", QualType<"Context.getAtomicType(Context.FloatTy)">>; -def AtomicDouble : Type<"atomic_double", QualType<"Context.getAtomicType(Context.DoubleTy)">>; +let Extension = AtomicFp64TypeExt in { + def AtomicDouble : Type<"atomic_double", QualType<"Context.getAtomicType(Context.DoubleTy)">>; +} def AtomicHalf : Type<"atomic_half", QualType<"Context.getAtomicType(Context.HalfTy)">>; def AtomicIntPtr : Type<"atomic_intptr_t", QualType<"Context.getAtomicType(Context.getIntPtrType())">>; def AtomicUIntPtr : Type<"atomic_uintptr_t", QualType<"Context.getAtomicType(Context.getUIntPtrType())">>; diff --git a/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl b/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl index d526c32d65a92..d2d7fff02efaa 100644 --- a/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl +++ b/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl @@ -163,6 +163,25 @@ void test_atomic_fetch_with_address_space(volatile __generic atomic_float *a_flo } #endif // !defined(NO_HEADER) && __OPENCL_C_VERSION__ >= 200 +#if !defined(NO_HEADER) && __OPENCL_C_VERSION__ == 200 && defined(__opencl_c_generic_address_space) + +// Test that overloads that use atomic_double are not available when the fp64 +// extension is disabled. Test this by counting the number of notes about +// candidate functions. +void test_atomic_double_reporting(volatile __generic atomic_int *a) { + atomic_init(a); + // expected-error@-1{{no matching function for call to 'atomic_init'}} +#if defined(NO_FP64) + // Expecting 5 candidates: int, uint, long, ulong, float + // expected-note@-4 5 {{candidate function not viable: requires 2 arguments, but 1 was provided}} +#else + // Expecting 6 candidates: int, uint, long, ulong, float, double + // expected-note@-7 6 {{candidate function not viable: requires 2 arguments, but 1 was provided}} +#endif +} + +#endif + #if defined(NO_ATOMSCOPE) && __OPENCL_C_VERSION__ >= 300 // Disable the feature by undefining the feature macro. #undef __opencl_c_atomic_scope_device diff --git a/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp b/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp index 4795b008dda3c..34ca6cb36738c 100644 --- a/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp +++ b/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp @@ -733,6 +733,20 @@ static std::pair<unsigned, unsigned> isOpenCLBuiltin(llvm::StringRef Name) { OS << "} // isOpenCLBuiltin\n"; } +// Emit an if-statement with an isMacroDefined call for each extension in +// the space-separated list of extensions. +static void EmitMacroChecks(raw_ostream &OS, StringRef Extensions) { + SmallVector<StringRef, 2> ExtVec; + Extensions.split(ExtVec, " "); + OS << " if ("; + for (StringRef Ext : ExtVec) { + if (Ext != ExtVec.front()) + OS << " && "; + OS << "S.getPreprocessor().isMacroDefined(\"" << Ext << "\")"; + } + OS << ") {\n "; +} + void BuiltinNameEmitter::EmitQualTypeFinder() { OS << R"( @@ -825,15 +839,14 @@ static void OCL2Qual(Sema &S, const OpenCLTypeStruct &Ty, // Collect all QualTypes for a single vector size into TypeList. OS << " SmallVector<QualType, " << BaseTypes.size() << "> TypeList;\n"; for (const auto *T : BaseTypes) { - StringRef Ext = + StringRef Exts = T->getValueAsDef("Extension")->getValueAsString("ExtName"); - if (!Ext.empty()) { - OS << " if (S.getPreprocessor().isMacroDefined(\"" << Ext - << "\")) {\n "; + if (!Exts.empty()) { + EmitMacroChecks(OS, Exts); } OS << " TypeList.push_back(" << T->getValueAsDef("QTExpr")->getValueAsString("TypeExpr") << ");\n"; - if (!Ext.empty()) { + if (!Exts.empty()) { OS << " }\n"; } } @@ -877,15 +890,14 @@ static void OCL2Qual(Sema &S, const OpenCLTypeStruct &Ty, // Emit the cases for non generic, non image types. OS << " case OCLT_" << T->getValueAsString("Name") << ":\n"; - StringRef Ext = T->getValueAsDef("Extension")->getValueAsString("ExtName"); - // If this type depends on an extension, ensure the extension macro is + StringRef Exts = T->getValueAsDef("Extension")->getValueAsString("ExtName"); + // If this type depends on an extension, ensure the extension macros are // defined. - if (!Ext.empty()) { - OS << " if (S.getPreprocessor().isMacroDefined(\"" << Ext - << "\")) {\n "; + if (!Exts.empty()) { + EmitMacroChecks(OS, Exts); } OS << " QT.push_back(" << QT->getValueAsString("TypeExpr") << ");\n"; - if (!Ext.empty()) { + if (!Exts.empty()) { OS << " }\n"; } OS << " break;\n"; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits