This revision was automatically updated to reflect the committed changes.
Closed by commit rG308b8b76ceee: [OpenCL] Add builtin function extension 
handling (authored by svenvh).
Herald added a project: clang.

Changed prior to commit:
  https://reviews.llvm.org/D71476?vs=233826&id=234491#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D71476/new/

https://reviews.llvm.org/D71476

Files:
  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
@@ -26,6 +26,11 @@
 //
 //  * Structs and enums to represent types and function signatures.
 //
+//  * const char *FunctionExtensionTable[]
+//    List of space-separated OpenCL extensions.  A builtin references an
+//    entry in this table when the builtin requires a particular (set of)
+//    extension(s) to be enabled.
+//
 //  * OpenCLTypeStruct TypeTable[]
 //    Type information for return types and arguments.
 //
@@ -133,6 +138,9 @@
   // function names.
   void GroupBySignature();
 
+  // Emit the FunctionExtensionTable that lists all function extensions.
+  void EmitExtensionTable();
+
   // Emit the TypeTable containing all types used by OpenCL builtins.
   void EmitTypeTable();
 
@@ -150,12 +158,13 @@
   // each function, and is a struct OpenCLBuiltinDecl.
   // E.g.:
   // // 891 convert_float2_rtn
-  //   { 58, 2, 100, 0 },
+  //   { 58, 2, 3, 100, 0 },
   // This means that the signature of this convert_float2_rtn overload has
   // 1 argument (+1 for the return type), stored at index 58 in
-  // the SignatureTable.  The last two values represent the minimum (1.0) and
-  // maximum (0, meaning no max version) OpenCL version in which this overload
-  // is supported.
+  // the SignatureTable.  This prototype requires extension "3" in the
+  // FunctionExtensionTable.  The last two values represent the minimum (1.0)
+  // and maximum (0, meaning no max version) OpenCL version in which this
+  // overload is supported.
   void EmitBuiltinTable();
 
   // Emit a StringMatcher function to check whether a function name is an
@@ -191,6 +200,10 @@
   // Contains the map of OpenCL types to their index in the TypeTable.
   MapVector<const Record *, unsigned> TypeMap;
 
+  // List of OpenCL function extensions mapping extension strings to
+  // an index into the FunctionExtensionTable.
+  StringMap<unsigned> FunctionExtensionIndex;
+
   // List of OpenCL type names in the same order as in enum OpenCLTypeID.
   // This list does not contain generic types.
   std::vector<const Record *> TypeList;
@@ -227,16 +240,18 @@
   // Emit enums and structs.
   EmitDeclarations();
 
+  // Parse the Records to populate the internal lists.
   GetOverloads();
   GroupBySignature();
 
   // Emit tables.
+  EmitExtensionTable();
   EmitTypeTable();
   EmitSignatureTable();
   EmitBuiltinTable();
 
+  // Emit functions.
   EmitStringMatcher();
-
   EmitQualTypeFinder();
 }
 
@@ -323,6 +338,8 @@
   const bool IsConst;
   // Function attribute __attribute__((convergent))
   const bool IsConv;
+  // OpenCL extension(s) required for this overload.
+  const unsigned short Extension;
   // First OpenCL version in which this overload was introduced (e.g. CL20).
   const unsigned short MinVersion;
   // First OpenCL version in which this overload was removed (e.g. CL20).
@@ -413,6 +430,23 @@
   }
 }
 
+void BuiltinNameEmitter::EmitExtensionTable() {
+  OS << "static const char *FunctionExtensionTable[] = {\n";
+  unsigned Index = 0;
+  std::vector<Record *> FuncExtensions =
+      Records.getAllDerivedDefinitions("FunctionExtension");
+
+  for (const auto &FE : FuncExtensions) {
+    // Emit OpenCL extension table entry.
+    OS << "  // " << Index << ": " << FE->getName() << "\n"
+       << "  \"" << FE->getValueAsString("ExtName") << "\",\n";
+
+    // Record index of this extension.
+    FunctionExtensionIndex[FE->getName()] = Index++;
+  }
+  OS << "};\n\n";
+}
+
 void BuiltinNameEmitter::EmitTypeTable() {
   OS << "static const OpenCLTypeStruct TypeTable[] = {\n";
   for (const auto &T : TypeMap) {
@@ -463,11 +497,13 @@
     OS << "\n";
 
     for (const auto &Overload : SLM.second.Signatures) {
+      StringRef ExtName = Overload.first->getValueAsDef("Extension")->getName();
       OS << "  { " << Overload.second << ", "
          << Overload.first->getValueAsListOfDefs("Signature").size() << ", "
          << (Overload.first->getValueAsBit("IsPure")) << ", "
          << (Overload.first->getValueAsBit("IsConst")) << ", "
          << (Overload.first->getValueAsBit("IsConv")) << ", "
+         << FunctionExtensionIndex[ExtName] << ", "
          << Overload.first->getValueAsDef("MinVersion")->getValueAsInt("ID")
          << ", "
          << Overload.first->getValueAsDef("MaxVersion")->getValueAsInt("ID")
@@ -496,8 +532,8 @@
             Rec2->getValueAsDef("MinVersion")->getValueAsInt("ID") &&
         Rec->getValueAsDef("MaxVersion")->getValueAsInt("ID") ==
             Rec2->getValueAsDef("MaxVersion")->getValueAsInt("ID") &&
-        Rec->getValueAsString("Extension") ==
-            Rec2->getValueAsString("Extension")) {
+        Rec->getValueAsDef("Extension")->getName() ==
+            Rec2->getValueAsDef("Extension")->getName()) {
       return true;
     }
   }
Index: clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl
===================================================================
--- clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl
+++ clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl
@@ -7,10 +7,6 @@
 // RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CLC++ -fdeclare-opencl-builtins -DNO_HEADER
 // RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CLC++ -fdeclare-opencl-builtins -finclude-default-header
 
-#if defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= CL_VERSION_2_0
-// expected-no-diagnostics
-#endif
-
 // Test the -fdeclare-opencl-builtins option.
 
 #pragma OPENCL EXTENSION cl_khr_fp16 : enable
@@ -43,6 +39,20 @@
   prefetch(a, 2);
 
   atom_add((volatile __global int *)global_p, i);
+#if !defined(__OPENCL_CPP_VERSION__) && __OPENCL_C_VERSION__ < CL_VERSION_1_1
+// expected-error@-2{{no matching function for call to 'atom_add'}}
+
+// There are two potential definitions of the function "atom_add", both are
+// currently disabled because the associated extension is disabled.
+// expected-note@-6{{candidate unavailable as it requires OpenCL extension 'cl_khr_global_int32_base_atomics' to be enabled}}
+// expected-note@-7{{candidate unavailable as it requires OpenCL extension 'cl_khr_global_int32_base_atomics' to be enabled}}
+#endif
+
+#if __OPENCL_C_VERSION__ < CL_VERSION_1_1
+#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable
+#endif
+
+  atom_add((volatile __global int *)global_p, i);
   atom_cmpxchg((volatile __global unsigned int *)global_p, ui, ui);
 }
 
@@ -113,6 +123,11 @@
 #if !defined(__OPENCL_CPP_VERSION__) && __OPENCL_C_VERSION__ < CL_VERSION_2_0
 // expected-error@-2{{implicit declaration of function 'get_sub_group_size' is invalid in OpenCL}}
 // expected-error@-3{{implicit conversion changes signedness: 'int' to 'uint' (aka 'unsigned int')}}
+#elif defined(__OPENCL_CPP_VERSION__)
+// expected-error@-5{{no matching function for call to 'get_sub_group_size'}}
+// expected-note@-6{{candidate unavailable as it requires OpenCL extension 'cl_khr_subgroups' to be enabled}}
+#else
+// expected-error@-8{{use of declaration 'get_sub_group_size' requires cl_khr_subgroups extension to be enabled}}
 #endif
 }
 
Index: clang/lib/Sema/SemaLookup.cpp
===================================================================
--- clang/lib/Sema/SemaLookup.cpp
+++ clang/lib/Sema/SemaLookup.cpp
@@ -739,6 +739,18 @@
   }
 }
 
+/// Add extensions to the function declaration.
+/// \param S (in/out) The Sema instance.
+/// \param BIDecl (in) Description of the builtin.
+/// \param FDecl (in/out) FunctionDecl instance.
+static void AddOpenCLExtensions(Sema &S, const OpenCLBuiltinStruct &BIDecl,
+                                FunctionDecl *FDecl) {
+  // Fetch extension associated with a function prototype.
+  StringRef E = FunctionExtensionTable[BIDecl.Extension];
+  if (E != "")
+    S.setOpenCLExtensionForDecl(FDecl, E);
+}
+
 /// When trying to resolve a function name, if isOpenCLBuiltin() returns a
 /// non-null <Index, Len> pair, then the name is referencing an OpenCL
 /// builtin function.  Add all candidate signatures to the LookUpResult.
@@ -827,6 +839,8 @@
       if (!S.getLangOpts().OpenCLCPlusPlus)
         NewOpenCLBuiltin->addAttr(OverloadableAttr::CreateImplicit(Context));
 
+      AddOpenCLExtensions(S, OpenCLBuiltin, NewOpenCLBuiltin);
+
       LR.addDecl(NewOpenCLBuiltin);
     }
   }
Index: clang/lib/Sema/OpenCLBuiltins.td
===================================================================
--- clang/lib/Sema/OpenCLBuiltins.td
+++ clang/lib/Sema/OpenCLBuiltins.td
@@ -40,6 +40,21 @@
 def LocalAS      : AddressSpace<"clang::LangAS::opencl_local">;
 def GenericAS    : AddressSpace<"clang::LangAS::opencl_generic">;
 
+// OpenCL language extension.
+class AbstractExtension<string _Ext> {
+  // One or more OpenCL extensions, space separated.  Each extension must be
+  // a valid extension name for the opencl extension pragma.
+  string ExtName = _Ext;
+}
+
+// Extension associated to a builtin function.
+class FunctionExtension<string _Ext> : AbstractExtension<_Ext>;
+
+// FunctionExtension definitions.
+def FuncExtNone                          : FunctionExtension<"">;
+def FuncExtKhrSubgroups                  : FunctionExtension<"cl_khr_subgroups">;
+def FuncExtKhrGlobalInt32BaseAtomics     : FunctionExtension<"cl_khr_global_int32_base_atomics">;
+def FuncExtKhrGlobalInt32ExtendedAtomics : FunctionExtension<"cl_khr_global_int32_extended_atomics">;
 
 // Qualified Type.  These map to ASTContext::QualType.
 class QualType<string _Name, bit _IsAbstract=0> {
@@ -198,14 +213,14 @@
   // the following are the arguments. The list must have at least one element
   // (the return type).
   list<Type> Signature = _Signature;
-  // OpenCL Extension to which the function belongs (cl_khr_subgroups, ...)
-  string Extension = "";
   // Function attribute __attribute__((pure))
   bit IsPure = _Attributes[0];
   // Function attribute __attribute__((const))
   bit IsConst = _Attributes[1];
   // Function attribute __attribute__((convergent))
   bit IsConv = _Attributes[2];
+  // OpenCL extensions to which the function belongs.
+  FunctionExtension Extension = FuncExtNone;
   // Version of OpenCL from which the function is available (e.g.: CL10).
   // MinVersion is inclusive.
   Version MinVersion = CL10;
@@ -862,17 +877,19 @@
 // Functions that use memory_order and cl_mem_fence_flags enums are not
 // declared here as the TableGen backend does not handle enums.
 
-// OpenCL v1.0 s9.5, s9.6, s9.7 - Atomic Functions for 32-bit integers.
+// OpenCL v1.0 s9.5, s9.6, s9.7 - Atomic Functions for 32-bit integers
 // --- Table 9.1 ---
-foreach Type = [Int, UInt] in {
-  foreach name = ["atom_add", "atom_sub", "atom_xchg"] in {
-    def : Builtin<name, [Type, PointerType<VolatileType<Type>, GlobalAS>, Type]>;
-  }
-  foreach name = ["atom_inc", "atom_dec"] in {
-    def : Builtin<name, [Type, PointerType<VolatileType<Type>, GlobalAS>]>;
-  }
-  foreach name = ["atom_cmpxchg"] in {
-    def : Builtin<name, [Type, PointerType<VolatileType<Type>, GlobalAS>, Type, Type]>;
+let Extension = FuncExtKhrGlobalInt32BaseAtomics in {
+  foreach Type = [Int, UInt] in {
+    foreach name = ["atom_add", "atom_sub", "atom_xchg"] in {
+      def : Builtin<name, [Type, PointerType<VolatileType<Type>, GlobalAS>, Type]>;
+    }
+    foreach name = ["atom_inc", "atom_dec"] in {
+      def : Builtin<name, [Type, PointerType<VolatileType<Type>, GlobalAS>]>;
+    }
+    foreach name = ["atom_cmpxchg"] in {
+      def : Builtin<name, [Type, PointerType<VolatileType<Type>, GlobalAS>, Type, Type]>;
+    }
   }
 }
 
@@ -1077,7 +1094,7 @@
 
 // OpenCL v2.0 s9.17.3: Additions to section 6.13.1: Work-Item Functions
 let MinVersion = CL20 in {
-  let Extension = "cl_khr_subgroups" in {
+  let Extension = FuncExtKhrSubgroups in {
     def get_sub_group_size : Builtin<"get_sub_group_size", [UInt]>;
     def get_max_sub_group_size : Builtin<"get_max_sub_group_size", [UInt]>;
     def get_num_sub_groups : Builtin<"get_num_sub_groups", [UInt]>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to