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

Rebased to use `::validateOpenCLTarget`. Decided to use explicit simulatneous 
extensions/feature disabling in command line due to API spec limitations:

clGetDeviceInfo: Will not describe support for the cl_khr_3d_image_writes 
extension if device does not support writing to 3D image objects.

Will update docs.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D96524

Files:
  clang/include/clang/Basic/DiagnosticCommonKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Basic/Targets.cpp
  clang/lib/Basic/Targets/AMDGPU.h
  clang/lib/Basic/Targets/NVPTX.h
  clang/lib/Frontend/CompilerInstance.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/CodeGenOpenCL/printf.cl
  clang/test/Misc/opencl-c-3.0.incorrect_options.cl
  clang/test/SemaOpenCL/extensions.cl
  clang/test/SemaOpenCL/fp64-fp16-options.cl

Index: clang/test/SemaOpenCL/fp64-fp16-options.cl
===================================================================
--- clang/test/SemaOpenCL/fp64-fp16-options.cl
+++ clang/test/SemaOpenCL/fp64-fp16-options.cl
@@ -4,6 +4,7 @@
 
 // Test with a target not supporting fp64.
 // RUN: %clang_cc1 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -DNOFP64 -DNOFP16
+// RUN: %clang_cc1 -cl-std=CL3.0 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -DNOFP64 -DNOFP16
 
 // Test with some extensions enabled or disabled by cmd-line args
 //
@@ -15,12 +16,18 @@
 // RUN: %clang_cc1 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -cl-ext=+all
 // RUN: %clang_cc1 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -cl-ext=+all,-cl_khr_fp64 -DNOFP64
 // RUN: %clang_cc1 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -cl-ext=-all,+cl_khr_fp64 -DNOFP16
+// RUN: %clang_cc1 -cl-std=CL3.0 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-all -DNOFP64 -DNOFP16
+// RUN: %clang_cc1 -cl-std=CL3.0 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -cl-ext=+all -DFP64
+// RUN: %clang_cc1 -cl-std=CL3.0 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -cl-ext=+all,-__opencl_c_fp64,-cl_khr_fp64 -DNOFP64
 //
 // Concatenating
 // RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-cl_khr_fp64 -cl-ext=+cl_khr_fp64
 // RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-cl_khr_fp64,+cl_khr_fp64
 // RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-all -cl-ext=+cl_khr_fp64 -cl-ext=+cl_khr_fp16 -cl-ext=-cl_khr_fp64 -DNOFP64
 // RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-all -cl-ext=+cl_khr_fp64,-cl_khr_fp64,+cl_khr_fp16 -DNOFP64
+// RUN: %clang_cc1 -cl-std=CL3.0 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-__opencl_c_fp64,-cl_khr_fp64 -cl-ext=+__opencl_c_fp64,+cl_khr_fp64 -DFP64
+// RUN: %clang_cc1 -cl-std=CL3.0 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-__opencl_c_fp64,+__opencl_c_fp64,+cl_khr_fp64 -DFP64
+// RUN: %clang_cc1 -cl-std=CL3.0 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-__opencl_c_fp64,-cl_khr_fp64 -DNOFP64
 
 // Test with -finclude-default-header, which includes opencl-c.h. opencl-c.h
 // disables all extensions by default, but supported core extensions for a
@@ -72,20 +79,33 @@
 void f2(void) {
   double d;
 #ifdef NOFP64
-// expected-error@-2{{use of type 'double' requires cl_khr_fp64 support}}
+#if (defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ == 300)
+// expected-error@-3{{use of type 'double' requires __opencl_c_fp64 support}}
+#else
+// expected-error@-5{{use of type 'double' requires cl_khr_fp64 support}}
+#endif
 #endif
 
   typedef double double4 __attribute__((ext_vector_type(4)));
   double4 d4 = {0.0f, 2.0f, 3.0f, 1.0f};
 #ifdef NOFP64
-// expected-error@-3 {{use of type 'double' requires cl_khr_fp64 support}}
-// expected-error@-3 {{use of type 'double4' (vector of 4 'double' values) requires cl_khr_fp64 support}}
+#if (defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ == 300)
+// expected-error@-4 {{use of type 'double' requires __opencl_c_fp64 support}}
+// expected-error@-4 {{use of type 'double4' (vector of 4 'double' values) requires __opencl_c_fp64 support}}
+#else
+// expected-error@-7 {{use of type 'double' requires cl_khr_fp64 support}}
+// expected-error@-7 {{use of type 'double4' (vector of 4 'double' values) requires cl_khr_fp64 support}}
+#endif
 #endif
 
   (void) 1.0;
 
 #ifdef NOFP64
-// expected-warning@-3{{double precision constant requires cl_khr_fp64, casting to single precision}}
+#if (defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ == 300)
+// expected-warning@-4{{double precision constant requires __opencl_c_fp64, casting to single precision}}
+#else
+// expected-warning@-6{{double precision constant requires cl_khr_fp64, casting to single precision}}
+#endif
 #endif
 }
 
Index: clang/test/Misc/opencl-c-3.0.incorrect_options.cl
===================================================================
--- /dev/null
+++ clang/test/Misc/opencl-c-3.0.incorrect_options.cl
@@ -0,0 +1,4 @@
+// RUN: not %clang_cc1 -cl-std=CL3.0 -triple spir-unknown-unknown -cl-ext=-__opencl_c_fp64,+cl_khr_fp64 %s 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -cl-std=CL3.0 -triple spir-unknown-unknown -cl-ext=+__opencl_c_fp64,-cl_khr_fp64 %s 2>&1 | FileCheck %s
+
+// CHECK: error: Options cl_khr_fp64 and __opencl_c_fp64 are set to different values which is illegal in OpenCL C 3.0
Index: clang/test/CodeGenOpenCL/printf.cl
===================================================================
--- clang/test/CodeGenOpenCL/printf.cl
+++ clang/test/CodeGenOpenCL/printf.cl
@@ -1,10 +1,12 @@
 // RUN: %clang_cc1 -cl-std=CL1.2 -cl-ext=-+cl_khr_fp64 -triple spir-unknown-unknown -disable-llvm-passes -emit-llvm -o - %s | FileCheck -check-prefixes=FP64,ALL %s
 // RUN: %clang_cc1 -cl-std=CL1.2 -cl-ext=-cl_khr_fp64 -triple spir-unknown-unknown -disable-llvm-passes -emit-llvm -o - %s | FileCheck -check-prefixes=NOFP64,ALL %s
+// RUN: %clang_cc1 -cl-std=CL3.0 -cl-ext=+__opencl_c_fp64,+cl_khr_fp64 -triple spir-unknown-unknown -disable-llvm-passes -emit-llvm -o - %s | FileCheck -check-prefixes=FP64,ALL %s
+// RUN: %clang_cc1 -cl-std=CL3.0 -cl-ext=-__opencl_c_fp64,-cl_khr_fp64 -triple spir-unknown-unknown -disable-llvm-passes -emit-llvm -o - %s | FileCheck -check-prefixes=NOFP64,ALL %s
 
 typedef __attribute__((ext_vector_type(2))) float float2;
 typedef __attribute__((ext_vector_type(2))) half half2;
 
-#ifdef cl_khr_fp64
+#if defined(cl_khr_fp64) || defined(__opencl_c_fp64)
 typedef __attribute__((ext_vector_type(2))) double double2;
 #endif
 
@@ -28,7 +30,7 @@
   printf("%v2hf", arg);
 }
 
-#ifdef cl_khr_fp64
+#if defined(cl_khr_fp64) || defined(__opencl_c_fp64)
 // FP64-LABEL: @test_printf_double2(
 // FP64: call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([6 x i8], [6 x i8] addrspace(2)* @.str.2, i32 0, i32 0), <2 x double> %0)
 kernel void test_printf_double2(double2 arg) {
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -3830,7 +3830,8 @@
       } else if (getLangOpts().OpenCL && !getOpenCLOptions().isAvailableOption(
                                              "cl_khr_fp64", getLangOpts())) {
         // Impose single-precision float type when cl_khr_fp64 is not enabled.
-        Diag(Tok.getLocation(), diag::warn_double_const_requires_fp64);
+        Diag(Tok.getLocation(), diag::warn_double_const_requires_fp64)
+            << (getLangOpts().OpenCLVersion >= 300);
         Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get();
       }
     }
Index: clang/lib/Sema/Sema.cpp
===================================================================
--- clang/lib/Sema/Sema.cpp
+++ clang/lib/Sema/Sema.cpp
@@ -301,6 +301,11 @@
         Context.getTargetInfo().getSupportedOpenCLOpts(), getLangOpts());
     addImplicitTypedef("sampler_t", Context.OCLSamplerTy);
     addImplicitTypedef("event_t", Context.OCLEventTy);
+
+    // Set conditionally to provide correct diagnostics for 'double' type
+    llvm::StringRef FP64Feature(
+        getLangOpts().OpenCLVersion >= 300 ? "__opencl_c_fp64" : "cl_khr_fp64");
+
     if (getLangOpts().OpenCLCPlusPlus || getLangOpts().OpenCLVersion >= 200) {
       addImplicitTypedef("clk_event_t", Context.OCLClkEventTy);
       addImplicitTypedef("queue_t", Context.OCLQueueTy);
@@ -332,10 +337,10 @@
                                          getLangOpts()) &&
           getOpenCLOptions().isSupported("cl_khr_int64_extended_atomics",
                                          getLangOpts())) {
-        if (getOpenCLOptions().isSupported("cl_khr_fp64", getLangOpts())) {
+        if (getOpenCLOptions().isSupported(FP64Feature, getLangOpts())) {
           auto AtomicDoubleT = Context.getAtomicType(Context.DoubleTy);
           addImplicitTypedef("atomic_double", AtomicDoubleT);
-          setOpenCLExtensionForType(AtomicDoubleT, "cl_khr_fp64");
+          setOpenCLExtensionForType(AtomicDoubleT, FP64Feature);
           Atomic64BitTypes.push_back(AtomicDoubleT);
         }
         auto AtomicLongT = Context.getAtomicType(Context.LongTy);
@@ -366,7 +371,7 @@
             "cl_khr_int64_base_atomics cl_khr_int64_extended_atomics");
     }
 
-    setOpenCLExtensionForType(Context.DoubleTy, "cl_khr_fp64");
+    setOpenCLExtensionForType(Context.DoubleTy, FP64Feature);
 
 #define GENERIC_IMAGE_TYPE_EXT(Type, Id, Ext) \
     setOpenCLExtensionForType(Context.Id, Ext);
Index: clang/lib/Frontend/CompilerInstance.cpp
===================================================================
--- clang/lib/Frontend/CompilerInstance.cpp
+++ clang/lib/Frontend/CompilerInstance.cpp
@@ -135,8 +135,9 @@
 
   // We should do it here because target knows nothing about
   // language options when it's being created.
-  if (getLangOpts().OpenCL)
-    getTarget().validateOpenCLTarget(getLangOpts(), getDiagnostics());
+  if (getLangOpts().OpenCL &&
+      !getTarget().validateOpenCLTarget(getLangOpts(), getDiagnostics()))
+    return false;
 
   // Inform the target of the language options.
   // FIXME: We shouldn't need to do this, the target should be immutable once
Index: clang/lib/Basic/Targets/NVPTX.h
===================================================================
--- clang/lib/Basic/Targets/NVPTX.h
+++ clang/lib/Basic/Targets/NVPTX.h
@@ -136,6 +136,7 @@
     Opts["__cl_clang_non_portable_kernel_param_types"] = true;
 
     Opts["cl_khr_fp64"] = true;
+    Opts["__opencl_c_fp64"] = true;
     Opts["cl_khr_byte_addressable_store"] = true;
     Opts["cl_khr_global_int32_base_atomics"] = true;
     Opts["cl_khr_global_int32_extended_atomics"] = true;
Index: clang/lib/Basic/Targets/AMDGPU.h
===================================================================
--- clang/lib/Basic/Targets/AMDGPU.h
+++ clang/lib/Basic/Targets/AMDGPU.h
@@ -292,6 +292,7 @@
     bool IsAMDGCN = isAMDGCN(getTriple());
 
     Opts["cl_khr_fp64"] = hasFP64();
+    Opts["__opencl_c_fp64"] = hasFP64();
 
     if (IsAMDGCN || GPUKind >= llvm::AMDGPU::GK_CEDAR) {
       Opts["cl_khr_byte_addressable_store"] = true;
Index: clang/lib/Basic/Targets.cpp
===================================================================
--- clang/lib/Basic/Targets.cpp
+++ clang/lib/Basic/Targets.cpp
@@ -743,7 +743,20 @@
   diagnoseNotSupportedCore(#Ext, __VA_ARGS__);
 #include "clang/Basic/OpenCLExtensions.def"
 
-  // For now assume that OpenCL target is always
-  // valid and just provide necessary diagnostics
+  // Validate that feature macros are set properly for OpenCL C 3.0.
+  // In other cases assume that target is always valid.
+  if (Opts.OpenCLCPlusPlus || Opts.OpenCLVersion < 300)
+    return true;
+
+  // Feature and corresponding equivalent extension must be set
+  // simultaneously to the same value.
+  for (auto &ExtAndFeat : {std::make_pair("cl_khr_fp64", "__opencl_c_fp64")})
+    if (hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.first) !=
+        hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.second)) {
+      Diags.Report(diag::err_opencl_extension_and_feature_differs)
+          << ExtAndFeat.first << ExtAndFeat.second;
+      return false;
+    }
+
   return true;
 }
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -118,7 +118,8 @@
   "magnitude of floating-point constant too small for type %0; minimum is %1">,
   InGroup<LiteralRange>;
 def warn_double_const_requires_fp64 : Warning<
-  "double precision constant requires cl_khr_fp64, casting to single precision">;
+  "double precision constant requires %select{cl_khr_fp64|__opencl_c_fp64}0, "
+  "casting to single precision">;
 def err_half_const_requires_fp16 : Error<
   "half precision constant requires cl_khr_fp16">;
 
Index: clang/include/clang/Basic/DiagnosticCommonKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -364,4 +364,7 @@
 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;
+
+def err_opencl_extension_and_feature_differs : Error<
+  "Options %0 and %1 are set to different values which is illegal in OpenCL C 3.0">;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to