[clang] 9798b33 - [OpenCL] Guard 64-bit atomic types
Sven van Haastregt via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 17 02:59:04 PST 2022
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 at -1{{no matching function for call to 'atomic_init'}}
+#if defined(NO_FP64)
+ // Expecting 5 candidates: int, uint, long, ulong, float
+ // expected-note at -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 at -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";
More information about the cfe-commits
mailing list