[clang] f0efc00 - [OpenCL] Introduce new method for validating OpenCL target

Anton Zabaznov via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 28 06:00:12 PDT 2021


Author: Anton Zabaznov
Date: 2021-04-28T16:00:02+03:00
New Revision: f0efc00751313779671746492ded4014b715df6a

URL: https://github.com/llvm/llvm-project/commit/f0efc00751313779671746492ded4014b715df6a
DIFF: https://github.com/llvm/llvm-project/commit/f0efc00751313779671746492ded4014b715df6a.diff

LOG: [OpenCL] Introduce new method for validating OpenCL target

Language options are not available when a target is being created,
thus, a new method is introduced. Also, some refactoring is done,
such as removing OpenCL feature macros setting from TargetInfo.

Reviewed By: Anastasia

Differential Revision: https://reviews.llvm.org/D101087

Added: 
    clang/test/Misc/nvptx.unsupported_core.cl
    clang/test/Misc/r600.unsupported_core.cl

Modified: 
    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

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index eab8206b104dc..06c2647149dfa 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -360,4 +360,8 @@ def note_suggest_disabling_all_checkers : Note<
 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;
 }

diff  --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index b91cee9a9e5f8..7d4e670c7e7d5 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1286,3 +1286,5 @@ in addition with the pragmas or -fmax-tokens flag to get any warnings.
 def WebAssemblyExceptionSpec : DiagGroup<"wasm-exception-spec">;
 
 def RTTI : DiagGroup<"rtti">;
+
+def OpenCLCoreFeaturesDiagGroup : DiagGroup<"pedantic-core-features">;

diff  --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 8b3da909dd118..274ed728d94d5 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1246,7 +1246,8 @@ def warn_pragma_unknown_extension : Warning<
 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<

diff  --git a/clang/include/clang/Basic/OpenCLOptions.h b/clang/include/clang/Basic/OpenCLOptions.h
index 17923d2b8d3cb..44fda029411f1 100644
--- a/clang/include/clang/Basic/OpenCLOptions.h
+++ b/clang/include/clang/Basic/OpenCLOptions.h
@@ -59,6 +59,7 @@ static inline bool isOpenCLVersionContainedInMask(const LangOptions &LO,
   OpenCLVersionID Code = encodeOpenCLVersion(CLVer);
   return Mask & Code;
 }
+
 } // end anonymous namespace
 
 /// OpenCL supported extensions and optional core features
@@ -167,6 +168,17 @@ class OpenCLOptions {
 
   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;

diff  --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 77b4746333597..3300fe012aa81 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1234,6 +1234,12 @@ class TargetInfo : public virtual TransferrableTargetInfo,
     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,
@@ -1481,7 +1487,8 @@ class TargetInfo : public virtual TransferrableTargetInfo,
   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"
   }
 
@@ -1501,10 +1508,6 @@ class TargetInfo : public virtual TransferrableTargetInfo,
     }
   }
 
-  /// 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;
@@ -1544,6 +1547,11 @@ class TargetInfo : public virtual TransferrableTargetInfo,
     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/functions.

diff  --git a/clang/lib/Basic/OpenCLOptions.cpp b/clang/lib/Basic/OpenCLOptions.cpp
index 78b7493855e66..7a647f02b1bd0 100644
--- a/clang/lib/Basic/OpenCLOptions.cpp
+++ b/clang/lib/Basic/OpenCLOptions.cpp
@@ -85,9 +85,8 @@ void OpenCLOptions::support(llvm::StringRef Ext, bool V) {
 }
 
 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"
 }
 

diff  --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index 8df5cb7a3a61a..894db333613e6 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -726,30 +726,24 @@ TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
 
   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;
 }

diff  --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp
index 75d4aa77ab6e2..ee5b6cb3c087f 100644
--- a/clang/lib/Basic/Targets/X86.cpp
+++ b/clang/lib/Basic/Targets/X86.cpp
@@ -1398,13 +1398,13 @@ bool X86TargetInfo::validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
       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 @@ bool X86TargetInfo::validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
     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;

diff  --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index b76baae2e0134..4a765b9203cc7 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -133,6 +133,11 @@ bool CompilerInstance::createTarget() {
     // 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.

diff  --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 557869a2571e0..41b08ed56134a 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -601,6 +601,29 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
     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,
@@ -1137,7 +1160,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
 
   // OpenCL definitions.
   if (LangOpts.OpenCL) {
-    TI.getOpenCLFeatureDefines(LangOpts, Builder);
+    InitializeOpenCLFeatureTestMacros(TI, LangOpts, Builder);
 
     if (TI.getTriple().isSPIR())
       Builder.defineMacro("__IMAGE_SUPPORT__");

diff  --git a/clang/test/Misc/nvptx.unsupported_core.cl b/clang/test/Misc/nvptx.unsupported_core.cl
new file mode 100644
index 0000000000000..b56a4828914ee
--- /dev/null
+++ b/clang/test/Misc/nvptx.unsupported_core.cl
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -cl-std=CL2.0 -triple nvptx-unknown-unknown -Wpedantic-core-features %s 2> %t
+// RUN: FileCheck --check-prefixes=CHECK-C < %t %s
+// RUN: %clang_cc1 -cl-std=CLC++ -triple nvptx-unknown-unknown -Wpedantic-core-features %s 2> %t
+// RUN: FileCheck --check-prefixes=CHECK-CPP < %t %s
+
+// CHECK-C: cl_khr_3d_image_writes is a core feature in OpenCL C version 2.0 but not supported on this target
+// CHECK-CPP: cl_khr_3d_image_writes is a core feature in C++ for OpenCL version 1.0 but not supported on this target

diff  --git a/clang/test/Misc/r600.unsupported_core.cl b/clang/test/Misc/r600.unsupported_core.cl
new file mode 100644
index 0000000000000..db3d74880d8b1
--- /dev/null
+++ b/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


        


More information about the cfe-commits mailing list