svenvh created this revision.
svenvh added a reviewer: Anastasia.
svenvh added a project: clang.
Herald added subscribers: jfb, yaxunl.
svenvh requested review of this revision.
Herald added a subscriber: cfe-commits.

Add enum and typedef argument support to `-fdeclare-opencl-builtins`,
which was the last major missing feature.

Adding the remaining missing builtins is left as future work.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D96051

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/OpenCLBuiltins.td
  clang/lib/Sema/SemaLookup.cpp
  clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl
  clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp

Index: clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp
===================================================================
--- clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp
+++ clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp
@@ -715,6 +715,30 @@
 void BuiltinNameEmitter::EmitQualTypeFinder() {
   OS << R"(
 
+// Lookup an OpenCL enum type.
+static QualType getOpenCLEnumType(Sema &S, llvm::StringRef Name) {
+  LookupResult Result(S, &S.Context.Idents.get(Name), SourceLocation(),
+                      Sema::LookupTagName);
+  S.LookupName(Result, S.TUScope);
+  if (Result.empty()) {
+    S.Diag(SourceLocation(), diag::err_opencl_type_not_found) << Name;
+    return S.Context.VoidTy;
+  }
+  return S.Context.getEnumType(Result.getAsSingle<EnumDecl>());
+}
+
+// Lookup an OpenCL typedef type.
+static QualType getOpenCLTypedefType(Sema &S, llvm::StringRef Name) {
+  LookupResult Result(S, &S.Context.Idents.get(Name), SourceLocation(),
+                      Sema::LookupOrdinaryName);
+  S.LookupName(Result, S.TUScope);
+  if (Result.empty()) {
+    S.Diag(SourceLocation(), diag::err_opencl_type_not_found) << Name;
+    return S.Context.VoidTy;
+  }
+  return S.Context.getTypedefType(Result.getAsSingle<TypedefNameDecl>());
+}
+
 // Convert an OpenCLTypeStruct type to a list of QualTypes.
 // Generic types represent multiple types and vector sizes, thus a vector
 // is returned. The conversion is done in two steps:
@@ -723,8 +747,9 @@
 //         or a single scalar type for non generic types.
 // Step 2: Qualifiers and other type properties such as vector size are
 //         applied.
-static void OCL2Qual(ASTContext &Context, const OpenCLTypeStruct &Ty,
+static void OCL2Qual(Sema &S, const OpenCLTypeStruct &Ty,
                      llvm::SmallVectorImpl<QualType> &QT) {
+  ASTContext &Context = S.Context;
   // Number of scalar types in the GenType.
   unsigned GenTypeNumTypes;
   // Pointer to the list of vector sizes for the GenType.
Index: clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl
===================================================================
--- clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl
+++ clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl
@@ -34,6 +34,9 @@
 typedef uint uint4 __attribute__((ext_vector_type(4)));
 typedef long long2 __attribute__((ext_vector_type(2)));
 
+typedef uint cl_mem_fence_flags;
+#define CLK_GLOBAL_MEM_FENCE   0x02
+
 // Enable extensions that are enabled in opencl-c-base.h.
 #if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200)
 #define cl_khr_subgroup_ballot 1
@@ -52,6 +55,18 @@
   atom_cmpxchg((volatile __global unsigned int *)global_p, ui, ui);
 }
 
+// Only test enum arguments when the base header is included, because we need
+// the enum declarations.
+#if !defined(NO_HEADER) && (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200)
+kernel void test_enum_args(volatile global atomic_int *global_p, global int* expected) {
+  int desired;
+  atomic_compare_exchange_strong_explicit(global_p, expected, desired,
+                                          memory_order_acq_rel,
+                                          memory_order_relaxed,
+                                          memory_scope_work_group);
+}
+#endif
+
 kernel void basic_conversion() {
   double d;
   float f;
@@ -180,6 +195,8 @@
 kernel void basic_work_item() {
   uint ui;
 
+  barrier(CLK_GLOBAL_MEM_FENCE);
+
   get_enqueued_local_size(ui);
 #if !defined(__OPENCL_CPP_VERSION__) && __OPENCL_C_VERSION__ < CL_VERSION_2_0
 // expected-error@-2{{implicit declaration of function 'get_enqueued_local_size' is invalid in OpenCL}}
Index: clang/lib/Sema/SemaLookup.cpp
===================================================================
--- clang/lib/Sema/SemaLookup.cpp
+++ clang/lib/Sema/SemaLookup.cpp
@@ -679,7 +679,7 @@
 
 /// Get the QualType instances of the return type and arguments for an OpenCL
 /// builtin function signature.
-/// \param Context (in) The Context instance.
+/// \param S (in) The Sema instance.
 /// \param OpenCLBuiltin (in) The signature currently handled.
 /// \param GenTypeMaxCnt (out) Maximum number of types contained in a generic
 ///        type used as return type or as argument.
@@ -689,20 +689,20 @@
 ///        argument, ArgTypes contains QualTypes for the Cartesian product
 ///        of (vector sizes) x (types) .
 static void GetQualTypesForOpenCLBuiltin(
-    ASTContext &Context, const OpenCLBuiltinStruct &OpenCLBuiltin,
-    unsigned &GenTypeMaxCnt, SmallVector<QualType, 1> &RetTypes,
+    Sema &S, const OpenCLBuiltinStruct &OpenCLBuiltin, unsigned &GenTypeMaxCnt,
+    SmallVector<QualType, 1> &RetTypes,
     SmallVector<SmallVector<QualType, 1>, 5> &ArgTypes) {
   // Get the QualType instances of the return types.
   unsigned Sig = SignatureTable[OpenCLBuiltin.SigTableIndex];
-  OCL2Qual(Context, TypeTable[Sig], RetTypes);
+  OCL2Qual(S, TypeTable[Sig], RetTypes);
   GenTypeMaxCnt = RetTypes.size();
 
   // Get the QualType instances of the arguments.
   // First type is the return type, skip it.
   for (unsigned Index = 1; Index < OpenCLBuiltin.NumTypes; Index++) {
     SmallVector<QualType, 1> Ty;
-    OCL2Qual(Context,
-        TypeTable[SignatureTable[OpenCLBuiltin.SigTableIndex + Index]], Ty);
+    OCL2Qual(S, TypeTable[SignatureTable[OpenCLBuiltin.SigTableIndex + Index]],
+             Ty);
     GenTypeMaxCnt = (Ty.size() > GenTypeMaxCnt) ? Ty.size() : GenTypeMaxCnt;
     ArgTypes.push_back(std::move(Ty));
   }
@@ -789,8 +789,8 @@
     SmallVector<SmallVector<QualType, 1>, 5> ArgTypes;
 
     // Obtain QualType lists for the function signature.
-    GetQualTypesForOpenCLBuiltin(Context, OpenCLBuiltin, GenTypeMaxCnt,
-                                 RetTypes, ArgTypes);
+    GetQualTypesForOpenCLBuiltin(S, OpenCLBuiltin, GenTypeMaxCnt, RetTypes,
+                                 ArgTypes);
     if (GenTypeMaxCnt > 1) {
       HasGenType = true;
     }
Index: clang/lib/Sema/OpenCLBuiltins.td
===================================================================
--- clang/lib/Sema/OpenCLBuiltins.td
+++ clang/lib/Sema/OpenCLBuiltins.td
@@ -177,6 +177,16 @@
   let AddrSpace = _Ty.AddrSpace;
 }
 
+// OpenCL enum type (e.g. memory_scope).
+class EnumType<string _Name> :
+    Type<_Name, QualType<"getOpenCLEnumType(S, \"" # _Name # "\")", 0>> {
+}
+
+// OpenCL typedef type (e.g. cl_mem_fence_flags).
+class TypedefType<string _Name> :
+    Type<_Name, QualType<"getOpenCLTypedefType(S, \"" # _Name # "\")", 0>> {
+}
+
 // List of Types.
 class TypeList<list<Type> _Type> {
   list<Type> List = _Type;
@@ -298,6 +308,7 @@
 def Event                 : Type<"event_t", QualType<"Context.OCLEventTy">>;
 def Queue                 : Type<"queue_t", QualType<"Context.OCLQueueTy">>;
 def ReserveId             : Type<"reserve_id_t", QualType<"Context.OCLReserveIDTy">>;
+def MemFenceFlags         : TypedefType<"cl_mem_fence_flags">;
 
 // OpenCL v2.0 s6.13.11: Atomic integer and floating-point types.
 def AtomicInt             : Type<"atomic_int", QualType<"Context.getAtomicType(Context.IntTy)">>;
@@ -311,6 +322,9 @@
 def AtomicSize            : Type<"atomic_size_t", QualType<"Context.getAtomicType(Context.getSizeType())">>;
 def AtomicPtrDiff         : Type<"atomic_ptrdiff_t", QualType<"Context.getAtomicType(Context.getPointerDiffType())">>;
 
+def MemoryOrder           : EnumType<"memory_order">;
+def MemoryScope           : EnumType<"memory_scope">;
+
 //===----------------------------------------------------------------------===//
 //                 Definitions of OpenCL gentype variants
 //===----------------------------------------------------------------------===//
@@ -893,6 +907,9 @@
   }
 }
 
+// OpenCL v3.0 s6.15.8 - Synchronization Functions.
+def : Builtin<"barrier", [Void, MemFenceFlags], Attr.Convergent>;
+
 //--------------------------------------------------------------------
 // OpenCL v1.1 s6.11.10, v1.2 s6.12.10, v2.0 s6.13.10: Async Copies from Global to Local Memory, Local to Global Memory, and Prefetch
 // OpenCL Extension v2.0 s5.1.7 and s6.1.7: Async Copies from Global to Local Memory, Local to Global Memory, and Prefetch
@@ -1024,6 +1041,12 @@
       def : Builtin<"atomic_compare_exchange_" # Variant,
           [Bool, PointerType<VolatileType<TypePair[0]>, GenericAS>,
            PointerType<TypePair[1], GenericAS>, TypePair[1]]>;
+      def : Builtin<"atomic_compare_exchange_" # Variant # "_explicit",
+          [Bool, PointerType<VolatileType<TypePair[0]>, GenericAS>,
+           PointerType<TypePair[1], GenericAS>, TypePair[1], MemoryOrder, MemoryOrder]>;
+      def : Builtin<"atomic_compare_exchange_" # Variant # "_explicit",
+          [Bool, PointerType<VolatileType<TypePair[0]>, GenericAS>,
+           PointerType<TypePair[1], GenericAS>, TypePair[1], MemoryOrder, MemoryOrder, MemoryScope]>;
     }
   }
 
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9886,6 +9886,8 @@
   "pointer to type %0 is invalid in OpenCL">;
 def err_opencl_type_can_only_be_used_as_function_parameter : Error <
   "type %0 can only be used as a function parameter in OpenCL">;
+def err_opencl_type_not_found : Error<
+  "type %0 not found; include the base header with -finclude-default-header">;
 def warn_opencl_attr_deprecated_ignored : Warning <
   "%0 attribute is deprecated and ignored in OpenCL version %1">,
   InGroup<IgnoredAttributes>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to