azabaznov updated this revision to Diff 340053.
azabaznov added a comment.

Use `LangOptions::getOpenCLVersionTuple()` to provide diagnostics of OpenCL 
version


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D101087

Files:
  clang/include/clang/Basic/DiagnosticCommonKinds.td
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/OpenCLOptions.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/Basic/OpenCLOptions.cpp
  clang/lib/Basic/Targets.cpp
  clang/lib/Basic/Targets/X86.cpp
  clang/lib/Frontend/CompilerInstance.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/test/Misc/nvptx.unsupported_core.cl
  clang/test/Misc/r600.unsupported_core.cl

Index: clang/test/Misc/r600.unsupported_core.cl
===================================================================
--- /dev/null
+++ clang/test/Misc/r600.unsupported_core.cl
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -cl-std=CL2.0 -triple r600-unknown-unknown -Wpedantic-core-features %s 2> %t
+// RUN: FileCheck < %t %s
+
+// CHECK: cl_khr_byte_addressable_store is a core feature in OpenCL C version 2.0 but not supported on this target
+// CHECK: cl_khr_global_int32_base_atomics is a core feature in OpenCL C version 2.0 but not supported on this target
+// CHECK: cl_khr_global_int32_extended_atomics is a core feature in OpenCL C version 2.0 but not supported on this target
+// CHECK: cl_khr_local_int32_base_atomics is a core feature in OpenCL C version 2.0 but not supported on this target
+// CHECK: cl_khr_local_int32_extended_atomics is a core feature in OpenCL C version 2.0 but not supported on this target
+// CHECK: cl_khr_3d_image_writes is a core feature in OpenCL C version 2.0 but not supported on this target
Index: clang/test/Misc/nvptx.unsupported_core.cl
===================================================================
--- /dev/null
+++ clang/test/Misc/nvptx.unsupported_core.cl
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -cl-std=CL2.0 -triple nvptx-unknown-unknown -Wpedantic-core-features %s 2> %t
+// RUN: FileCheck < %t %s
+
+// CHECK: cl_khr_3d_image_writes is a core feature in OpenCL C version 2.0 but not supported on this target
Index: clang/lib/Frontend/InitPreprocessor.cpp
===================================================================
--- clang/lib/Frontend/InitPreprocessor.cpp
+++ clang/lib/Frontend/InitPreprocessor.cpp
@@ -601,6 +601,29 @@
     Builder.defineMacro("__cpp_coroutines", "201703L");
 }
 
+/// InitializeOpenCLFeatureTestMacros - Define OpenCL macros based on target
+/// settings and language version
+void InitializeOpenCLFeatureTestMacros(const TargetInfo &TI,
+                                       const LangOptions &Opts,
+                                       MacroBuilder &Builder) {
+  const llvm::StringMap<bool> &OpenCLFeaturesMap = TI.getSupportedOpenCLOpts();
+  // FIXME: OpenCL options which affect language semantics/syntax
+  // should be moved into LangOptions.
+  auto defineOpenCLExtMacro = [&](llvm::StringRef Name, auto... OptArgs) {
+    // Check if extension is supported by target and is available in this
+    // OpenCL version
+    if (TI.hasFeatureEnabled(OpenCLFeaturesMap, Name) &&
+        OpenCLOptions::isOpenCLOptionAvailableIn(Opts, OptArgs...))
+      Builder.defineMacro(Name);
+  };
+#define OPENCL_GENERIC_EXTENSION(Ext, ...)                                     \
+  defineOpenCLExtMacro(#Ext, __VA_ARGS__);
+#include "clang/Basic/OpenCLExtensions.def"
+
+  // Assume compiling for FULL profile
+  Builder.defineMacro("__opencl_c_int64");
+}
+
 static void InitializePredefinedMacros(const TargetInfo &TI,
                                        const LangOptions &LangOpts,
                                        const FrontendOptions &FEOpts,
@@ -1138,7 +1161,7 @@
 
   // OpenCL definitions.
   if (LangOpts.OpenCL) {
-    TI.getOpenCLFeatureDefines(LangOpts, Builder);
+    InitializeOpenCLFeatureTestMacros(TI, LangOpts, Builder);
 
     if (TI.getTriple().isSPIR())
       Builder.defineMacro("__IMAGE_SUPPORT__");
Index: clang/lib/Frontend/CompilerInstance.cpp
===================================================================
--- clang/lib/Frontend/CompilerInstance.cpp
+++ clang/lib/Frontend/CompilerInstance.cpp
@@ -133,6 +133,11 @@
     // FIXME: can we disable FEnvAccess?
   }
 
+  // We should do it here because target knows nothing about
+  // language options when it's being created.
+  if (getLangOpts().OpenCL)
+    getTarget().validateOpenCLTarget(getLangOpts(), getDiagnostics());
+
   // Inform the target of the language options.
   // FIXME: We shouldn't need to do this, the target should be immutable once
   // created. This complexity should be lifted elsewhere.
Index: clang/lib/Basic/Targets/X86.cpp
===================================================================
--- clang/lib/Basic/Targets/X86.cpp
+++ clang/lib/Basic/Targets/X86.cpp
@@ -1398,13 +1398,13 @@
       return Size <= 64;
     case 'z':
       // XMM0/YMM/ZMM0
-      if (FeatureMap.lookup("avx512f"))
+      if (hasFeatureEnabled(FeatureMap, "avx512f"))
         // ZMM0 can be used if target supports AVX512F.
         return Size <= 512U;
-      else if (FeatureMap.lookup("avx"))
+      else if (hasFeatureEnabled(FeatureMap, "avx"))
         // YMM0 can be used if target supports AVX.
         return Size <= 256U;
-      else if (FeatureMap.lookup("sse"))
+      else if (hasFeatureEnabled(FeatureMap, "sse"))
         return Size <= 128U;
       return false;
     case 'i':
@@ -1418,10 +1418,10 @@
     break;
   case 'v':
   case 'x':
-    if (FeatureMap.lookup("avx512f"))
+    if (hasFeatureEnabled(FeatureMap, "avx512f"))
       // 512-bit zmm registers can be used if target supports AVX512F.
       return Size <= 512U;
-    else if (FeatureMap.lookup("avx"))
+    else if (hasFeatureEnabled(FeatureMap, "avx"))
       // 256-bit ymm registers can be used if target supports AVX.
       return Size <= 256U;
     return Size <= 128U;
Index: clang/lib/Basic/Targets.cpp
===================================================================
--- clang/lib/Basic/Targets.cpp
+++ clang/lib/Basic/Targets.cpp
@@ -726,30 +726,24 @@
 
   return Target.release();
 }
-
-/// getOpenCLFeatureDefines - Define OpenCL macros based on target settings
-/// and language version
-void TargetInfo::getOpenCLFeatureDefines(const LangOptions &Opts,
-                                         MacroBuilder &Builder) const {
-  // FIXME: OpenCL options which affect language semantics/syntax
-  // should be moved into LangOptions, thus macro definitions of
-  // such options is better to be done in clang::InitializePreprocessor.
-  auto defineOpenCLExtMacro = [&](llvm::StringRef Name, unsigned AvailVer,
-                                  unsigned CoreVersions,
-                                  unsigned OptionalVersions) {
-    // Check if extension is supported by target and is available in this
-    // OpenCL version
-    auto It = getTargetOpts().OpenCLFeaturesMap.find(Name);
-    if ((It != getTargetOpts().OpenCLFeaturesMap.end()) && It->getValue() &&
-        OpenCLOptions::OpenCLOptionInfo(false, AvailVer, CoreVersions,
-                                        OptionalVersions)
-            .isAvailableIn(Opts))
-      Builder.defineMacro(Name);
+/// validateOpenCLTarget  - Check that OpenCL target has valid
+/// options setting based on OpenCL version.
+bool TargetInfo::validateOpenCLTarget(const LangOptions &Opts,
+                                      DiagnosticsEngine &Diags) const {
+  const llvm::StringMap<bool> &OpenCLFeaturesMap = getSupportedOpenCLOpts();
+
+  auto diagnoseNotSupportedCore = [&](llvm::StringRef Name, auto... OptArgs) {
+    if (OpenCLOptions::isOpenCLOptionCoreIn(Opts, OptArgs...) &&
+        !hasFeatureEnabled(OpenCLFeaturesMap, Name))
+      Diags.Report(diag::warn_opencl_unsupported_core_feature)
+          << Name << Opts.OpenCLCPlusPlus
+          << Opts.getOpenCLVersionTuple().getAsString();
   };
-#define OPENCL_GENERIC_EXTENSION(Ext, WithPragma, Avail, Core, Opt)            \
-  defineOpenCLExtMacro(#Ext, Avail, Core, Opt);
+#define OPENCL_GENERIC_EXTENSION(Ext, ...)                                     \
+  diagnoseNotSupportedCore(#Ext, __VA_ARGS__);
 #include "clang/Basic/OpenCLExtensions.def"
 
-  // Assume compiling for FULL profile
-  Builder.defineMacro("__opencl_c_int64");
+  // For now assume that OpenCL target is always
+  // valid and just provide necessary diagnostics
+  return true;
 }
Index: clang/lib/Basic/OpenCLOptions.cpp
===================================================================
--- clang/lib/Basic/OpenCLOptions.cpp
+++ clang/lib/Basic/OpenCLOptions.cpp
@@ -85,9 +85,8 @@
 }
 
 OpenCLOptions::OpenCLOptions() {
-#define OPENCL_GENERIC_EXTENSION(Ext, WithPragma, AvailVer, CoreVer, OptVer)   \
-  OptMap.insert_or_assign(                                                     \
-      #Ext, OpenCLOptionInfo{WithPragma, AvailVer, CoreVer, OptVer});
+#define OPENCL_GENERIC_EXTENSION(Ext, ...)                                     \
+  OptMap.insert_or_assign(#Ext, OpenCLOptionInfo{__VA_ARGS__});
 #include "clang/Basic/OpenCLExtensions.def"
 }
 
Index: clang/include/clang/Basic/TargetInfo.h
===================================================================
--- clang/include/clang/Basic/TargetInfo.h
+++ clang/include/clang/Basic/TargetInfo.h
@@ -1226,6 +1226,12 @@
     return false;
   }
 
+  /// Check if target has a given feature enabled
+  virtual bool hasFeatureEnabled(const llvm::StringMap<bool> &Features,
+                                 StringRef Name) const {
+    return Features.lookup(Name);
+  }
+
   /// Enable or disable a specific target feature;
   /// the feature name must be valid.
   virtual void setFeatureEnabled(llvm::StringMap<bool> &Features,
@@ -1473,7 +1479,8 @@
   virtual void setSupportedOpenCLOpts() {}
 
   virtual void supportAllOpenCLOpts(bool V = true) {
-#define OPENCLEXTNAME(Ext) getTargetOpts().OpenCLFeaturesMap[#Ext] = V;
+#define OPENCLEXTNAME(Ext)                                                     \
+  setFeatureEnabled(getTargetOpts().OpenCLFeaturesMap, #Ext, V);
 #include "clang/Basic/OpenCLExtensions.def"
   }
 
@@ -1493,10 +1500,6 @@
     }
   }
 
-  /// Define OpenCL macros based on target settings and language version
-  void getOpenCLFeatureDefines(const LangOptions &Opts,
-                               MacroBuilder &Builder) const;
-
   /// Get supported OpenCL extensions and optional core features.
   llvm::StringMap<bool> &getSupportedOpenCLOpts() {
     return getTargetOpts().OpenCLFeaturesMap;
@@ -1536,6 +1539,11 @@
     return true;
   }
 
+  /// Check that OpenCL target has valid options setting based on OpenCL
+  /// version.
+  virtual bool validateOpenCLTarget(const LangOptions &Opts,
+                                    DiagnosticsEngine &Diags) const;
+
   virtual void setAuxTarget(const TargetInfo *Aux) {}
 
   /// Whether target allows debuginfo types for decl only variables.
Index: clang/include/clang/Basic/OpenCLOptions.h
===================================================================
--- clang/include/clang/Basic/OpenCLOptions.h
+++ clang/include/clang/Basic/OpenCLOptions.h
@@ -59,6 +59,7 @@
   OpenCLVersionID Code = encodeOpenCLVersion(CLVer);
   return Mask & Code;
 }
+
 } // end anonymous namespace
 
 /// OpenCL supported extensions and optional core features
@@ -168,6 +169,17 @@
 
   using OpenCLOptionInfoMap = llvm::StringMap<OpenCLOptionInfo>;
 
+  template <typename... Args>
+  static bool isOpenCLOptionCoreIn(const LangOptions &LO, Args &&... args) {
+    return OpenCLOptionInfo(std::forward<Args>(args)...).isCoreIn(LO);
+  }
+
+  template <typename... Args>
+  static bool isOpenCLOptionAvailableIn(const LangOptions &LO,
+                                        Args &&... args) {
+    return OpenCLOptionInfo(std::forward<Args>(args)...).isAvailableIn(LO);
+  }
+
 private:
   // Option is enabled via pragma
   bool isEnabled(llvm::StringRef Ext) const;
Index: clang/include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticParseKinds.td
+++ clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1246,7 +1246,8 @@
 def warn_pragma_unsupported_extension : Warning<
   "unsupported OpenCL extension %0 - ignoring">, InGroup<IgnoredPragmas>;
 def warn_pragma_extension_is_core : Warning<
-  "OpenCL extension %0 is core feature or supported optional core feature - ignoring">, InGroup<DiagGroup<"pedantic-core-features">>, DefaultIgnore;
+  "OpenCL extension %0 is core feature or supported optional core feature - ignoring">,
+  InGroup<OpenCLCoreFeaturesDiagGroup>, DefaultIgnore;
 
 // OpenCL errors.
 def err_opencl_taking_function_address_parser : Error<
Index: clang/include/clang/Basic/DiagnosticGroups.td
===================================================================
--- clang/include/clang/Basic/DiagnosticGroups.td
+++ clang/include/clang/Basic/DiagnosticGroups.td
@@ -1278,3 +1278,5 @@
 def WebAssemblyExceptionSpec : DiagGroup<"wasm-exception-spec">;
 
 def RTTI : DiagGroup<"rtti">;
+
+def OpenCLCoreFeaturesDiagGroup : DiagGroup<"pedantic-core-features">;
Index: clang/include/clang/Basic/DiagnosticCommonKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -360,4 +360,8 @@
 def warn_poison_system_directories : Warning <
   "include location '%0' is unsafe for cross-compilation">,
   InGroup<DiagGroup<"poison-system-directories">>, DefaultIgnore;
+
+def warn_opencl_unsupported_core_feature : Warning<
+  "%0 is a core feature in %select{OpenCL C|C++ for OpenCL}1 version %2 but not supported on this target">,
+  InGroup<OpenCLCoreFeaturesDiagGroup>, DefaultIgnore;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to