forked from OSchip/llvm-project
[OpenCL] Add support of OpenCL C 3.0 __opencl_c_fp64
There already exists cl_khr_fp64 extension. So OpenCL C 3.0 and higher should use the feature, earlier versions still use the extension. OpenCL C 3.0 API spec states that extension will be not described in the option string if corresponding optional functionality is not supported (see 4.2. Querying Devices). Due to that fact the usage of features for OpenCL C 3.0 must be as follows: ``` $ clang -Xclang -cl-ext=+cl_khr_fp64,+__opencl_c_fp64 ... $ clang -Xclang -cl-ext=-cl_khr_fp64,-__opencl_c_fp64 ... ``` e.g. the feature and the equivalent extension (if exists) must be set to the same values Reviewed By: Anastasia Differential Revision: https://reviews.llvm.org/D96524
This commit is contained in:
parent
469833f418
commit
826905787a
|
@ -339,7 +339,24 @@ Missing features or with limited support
|
|||
|
||||
.. _opencl_300:
|
||||
|
||||
OpenCL 3.0 Implementation Status
|
||||
OpenCL C 3.0 Usage
|
||||
================================
|
||||
|
||||
OpenCL C 3.0 language standard makes most OpenCL C 2.0 features optional. Optional
|
||||
functionality in OpenCL C 3.0 is indicated with the presence of feature-test macros
|
||||
(list of feature-test macros is `here <https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_C.html#features>`_).
|
||||
Command-line flag :ref:`-cl-ext <opencl_cl_ext>` can be used to override features supported by a target.
|
||||
|
||||
For cases when there is an associated extension for a specific feature (fp64 and 3d image writes)
|
||||
user should specify both (extension and feature) in command-line flag:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ clang -cc1 -cl-std=CL3.0 -cl-ext=+cl_khr_fp64,+__opencl_c_fp64 ...
|
||||
$ clang -cc1 -cl-std=CL3.0 -cl-ext=-cl_khr_fp64,-__opencl_c_fp64 ...
|
||||
|
||||
|
||||
OpenCL C 3.0 Implementation Status
|
||||
================================
|
||||
|
||||
The following table provides an overview of features in OpenCL C 3.0 and their
|
||||
|
|
|
@ -364,4 +364,7 @@ def warn_poison_system_directories : Warning <
|
|||
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">;
|
||||
}
|
||||
|
|
|
@ -118,7 +118,8 @@ def warn_float_underflow : Warning<
|
|||
"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|cl_khr_fp64 and __opencl_c_fp64}0, "
|
||||
"casting to single precision">;
|
||||
def err_half_const_requires_fp16 : Error<
|
||||
"half precision constant requires cl_khr_fp16">;
|
||||
|
||||
|
@ -10027,6 +10028,8 @@ def err_opencl_requires_extension : Error<
|
|||
def ext_opencl_double_without_pragma : Extension<
|
||||
"Clang permits use of type 'double' regardless pragma if 'cl_khr_fp64' is"
|
||||
" supported">;
|
||||
def err_opencl_double_requires_extension : Error<
|
||||
"use of type 'double' requires %select{cl_khr_fp64|cl_khr_fp64 and __opencl_c_fp64}0 support">;
|
||||
def warn_opencl_generic_address_space_arg : Warning<
|
||||
"passing non-generic address space pointer to %0"
|
||||
" may cause dynamic conversion affecting performance">,
|
||||
|
|
|
@ -743,7 +743,20 @@ bool TargetInfo::validateOpenCLTarget(const LangOptions &Opts,
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -292,6 +292,7 @@ public:
|
|||
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;
|
||||
|
|
|
@ -138,6 +138,7 @@ public:
|
|||
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;
|
||||
|
|
|
@ -135,8 +135,9 @@ bool CompilerInstance::createTarget() {
|
|||
|
||||
// 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
|
||||
|
|
|
@ -3843,7 +3843,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
|
|||
} 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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1526,8 +1526,9 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
|
|||
case DeclSpec::TST_double:
|
||||
if (S.getLangOpts().OpenCL) {
|
||||
if (!S.getOpenCLOptions().isSupported("cl_khr_fp64", S.getLangOpts()))
|
||||
S.Diag(DS.getTypeSpecTypeLoc(), diag::err_opencl_requires_extension)
|
||||
<< 0 << Context.DoubleTy << "cl_khr_fp64";
|
||||
S.Diag(DS.getTypeSpecTypeLoc(),
|
||||
diag::err_opencl_double_requires_extension)
|
||||
<< (S.getLangOpts().OpenCLVersion >= 300);
|
||||
else if (!S.getOpenCLOptions().isAvailableOption("cl_khr_fp64", S.getLangOpts()))
|
||||
S.Diag(DS.getTypeSpecTypeLoc(), diag::ext_opencl_double_without_pragma);
|
||||
}
|
||||
|
|
|
@ -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 @@ kernel void test_printf_half2(half2 arg) {
|
|||
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) {
|
||||
|
|
|
@ -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
|
|
@ -5,6 +5,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
|
||||
//
|
||||
|
@ -16,12 +17,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
|
||||
|
@ -85,18 +92,30 @@ int isfinite(float x) {
|
|||
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 cl_khr_fp64 and __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}}
|
||||
#if (defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ >= 300)
|
||||
// expected-error@-4 {{use of type 'double' requires cl_khr_fp64 and __opencl_c_fp64 support}}
|
||||
#else
|
||||
// expected-error@-6 {{use of type 'double' requires cl_khr_fp64 support}}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
(void) 1.0;
|
||||
#ifdef NOFP64
|
||||
// expected-warning@-2{{double precision constant requires cl_khr_fp64, casting to single precision}}
|
||||
#if (defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ >= 300)
|
||||
// expected-warning@-3{{double precision constant requires cl_khr_fp64 and __opencl_c_fp64, casting to single precision}}
|
||||
#else
|
||||
// expected-warning@-5{{double precision constant requires cl_khr_fp64, casting to single precision}}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue