Index: include/clang/Basic/LangOptions.h =================================================================== --- include/clang/Basic/LangOptions.h +++ include/clang/Basic/LangOptions.h @@ -160,18 +160,6 @@ fp_contract(LangOpts.DefaultFPContract) {} }; -/// \brief OpenCL volatile options -class OpenCLOptions { -public: -#define OPENCLEXT(nm) unsigned nm : 1; -#include "clang/Basic/OpenCLExtensions.def" - - OpenCLOptions() { -#define OPENCLEXT(nm) nm = 0; -#include "clang/Basic/OpenCLExtensions.def" - } -}; - /// \brief Describes the kind of translation unit being processed. enum TranslationUnitKind { /// \brief The translation unit is a complete translation unit. Index: include/clang/Basic/OpenCLOptions.h =================================================================== --- /dev/null +++ include/clang/Basic/OpenCLOptions.h @@ -0,0 +1,43 @@ +//===--- OpenCLOptions.h ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Defines the clang::OpenCLOptions class. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_OPENCLOPTIONS_H +#define LLVM_CLANG_BASIC_OPENCLOPTIONS_H + +#include +#include + +namespace clang { + +/// \brief OpenCL supported extensions and optional core features +class OpenCLOptions { +public: +#define OPENCLEXT(nm) unsigned nm : 1; +#include "clang/Basic/OpenCLExtensions.def" + + OpenCLOptions() { +#define OPENCLEXT(nm) nm = 0; +#include "clang/Basic/OpenCLExtensions.def" + } + + // Enable all options. + void setAll() { +#define OPENCLEXT(nm) nm = 1; +#include "clang/Basic/OpenCLExtensions.def" + } +}; + +} // end namespace clang + +#endif Index: include/clang/Basic/TargetInfo.h =================================================================== --- include/clang/Basic/TargetInfo.h +++ include/clang/Basic/TargetInfo.h @@ -956,6 +956,19 @@ /// \brief Whether target allows to overalign ABI-specified prefered alignment virtual bool allowsLargerPreferedTypeAlignment() const { return true; } + /// \brief Set supported OpenCL extensions and optional core features. + virtual void setSupportedOpenCLOpts() {} + + /// \brief Get supported OpenCL extensions and optional core features. + OpenCLOptions &getSupportedOpenCLOpts() { + return getTargetOpts().SupportedOpenCLOptions; + } + + /// \brief Get const supported OpenCL extensions and optional core features. + const OpenCLOptions &getSupportedOpenCLOpts() const { + return getTargetOpts().SupportedOpenCLOptions; + } + protected: virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return PointerWidth; Index: include/clang/Basic/TargetOptions.h =================================================================== --- include/clang/Basic/TargetOptions.h +++ include/clang/Basic/TargetOptions.h @@ -17,6 +17,7 @@ #include #include +#include "clang/Basic/OpenCLOptions.h" namespace clang { @@ -50,6 +51,9 @@ std::vector Features; std::vector Reciprocals; + + /// Supported OpenCL extensions and optional core features. + OpenCLOptions SupportedOpenCLOptions; }; } // end namespace clang Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -1969,6 +1969,12 @@ return true; } + + void setSupportedOpenCLOpts() { + getSupportedOpenCLOpts().setAll(); + if (!hasFP64) + getSupportedOpenCLOpts().cl_khr_fp64 = 0; + } }; const Builtin::Info AMDGPUTargetInfo::BuiltinInfo[] = { @@ -2588,6 +2594,10 @@ bool hasSjLjLowering() const override { return true; } + + void setSupportedOpenCLOpts() { + getSupportedOpenCLOpts().setAll(); + } }; bool X86TargetInfo::setFPMath(StringRef Name) { @@ -7706,6 +7716,12 @@ CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override { return CC_SpirFunction; } + + void setSupportedOpenCLOpts() { + // Assume all OpenCL extensions and optional core features are supported + // for SPIR since it is a generic target. + getSupportedOpenCLOpts().setAll(); + } }; class SPIR32TargetInfo : public SPIRTargetInfo { @@ -8304,5 +8320,7 @@ if (!Target->handleTargetFeatures(Opts->Features, Diags)) return nullptr; + Target->setSupportedOpenCLOpts(); + return Target.release(); } Index: lib/Parse/ParsePragma.cpp =================================================================== --- lib/Parse/ParsePragma.cpp +++ lib/Parse/ParsePragma.cpp @@ -477,7 +477,8 @@ #define OPENCLEXT(nm) f.nm = 0; #include "clang/Basic/OpenCLExtensions.def" } -#define OPENCLEXT(nm) else if (ename->isStr(#nm)) { f.nm = state; } +#define OPENCLEXT(nm) else if (ename->isStr(#nm) \ + && getTargetInfo().getSupportedOpenCLOpts().nm) { f.nm = state; } #include "clang/Basic/OpenCLExtensions.def" else { PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << ename; Index: lib/Sema/Sema.cpp =================================================================== --- lib/Sema/Sema.cpp +++ lib/Sema/Sema.cpp @@ -206,10 +206,14 @@ addImplicitTypedef("size_t", Context.getSizeType()); } - // Initialize predefined OpenCL types. + // Initialize predefined OpenCL types and supported optional core features. if (getLangOpts().OpenCL) { addImplicitTypedef("sampler_t", Context.OCLSamplerTy); addImplicitTypedef("event_t", Context.OCLEventTy); + if (getLangOpts().OpenCLVersion >= 120 && + Context.getTargetInfo().getSupportedOpenCLOpts().cl_khr_fp64) + getOpenCLOptions().cl_khr_fp64 = 1; + if (getLangOpts().OpenCLVersion >= 200) { addImplicitTypedef("clk_event_t", Context.OCLClkEventTy); addImplicitTypedef("queue_t", Context.OCLQueueTy); Index: test/CodeGenOpenCL/builtins-r600.cl =================================================================== --- test/CodeGenOpenCL/builtins-r600.cl +++ test/CodeGenOpenCL/builtins-r600.cl @@ -1,5 +1,5 @@ // REQUIRES: amdgpu-registered-target -// RUN: %clang_cc1 -triple r600-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple r600-unknown-unknown -target-cpu rv670 -S -emit-llvm -o - %s | FileCheck %s #pragma OPENCL EXTENSION cl_khr_fp64 : enable Index: test/Parser/opencl-atomics-cl20.cl =================================================================== --- test/Parser/opencl-atomics-cl20.cl +++ test/Parser/opencl-atomics-cl20.cl @@ -44,15 +44,14 @@ // expected-error@-28 {{use of type 'atomic_ulong' (aka '_Atomic(unsigned long)') requires cl_khr_int64_extended_atomics extension to be enabled}} // expected-error@-27 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_base_atomics extension to be enabled}} // expected-error@-28 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_extended_atomics extension to be enabled}} -// expected-error@-29 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_fp64 extension to be enabled}} -// expected-error-re@-28 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} -// expected-error-re@-29 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} -// expected-error-re@-29 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} -// expected-error-re@-30 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} -// expected-error-re@-30 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} -// expected-error-re@-31 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} -// expected-error-re@-31 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} -// expected-error-re@-32 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} +// expected-error-re@-27 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} +// expected-error-re@-28 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} +// expected-error-re@-28 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} +// expected-error-re@-29 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} +// expected-error-re@-29 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} +// expected-error-re@-30 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} +// expected-error-re@-30 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} +// expected-error-re@-31 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} #endif #ifdef CL20 Index: test/SemaOpenCL/extension-fp64-cl1.1.cl =================================================================== --- test/SemaOpenCL/extension-fp64-cl1.1.cl +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL1.1 - -void f1(double da) { // expected-error {{type 'double' requires cl_khr_fp64 extension}} - double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}} - (void) 1.0; // expected-warning {{double precision constant requires cl_khr_fp64}} -} - -#pragma OPENCL EXTENSION cl_khr_fp64 : enable - -void f2(void) { - double d; - (void) 1.0; -} - -#pragma OPENCL EXTENSION cl_khr_fp64 : disable - -void f3(void) { - double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}} -} Index: test/SemaOpenCL/extension-fp64.cl =================================================================== --- test/SemaOpenCL/extension-fp64.cl +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only - -void f1(double da) { // expected-error {{type 'double' requires cl_khr_fp64 extension}} - double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}} - (void) 1.0; // expected-warning {{double precision constant requires cl_khr_fp64}} -} - -#pragma OPENCL EXTENSION cl_khr_fp64 : enable - -void f2(void) { - double d; - (void) 1.0; -} - -#pragma OPENCL EXTENSION cl_khr_fp64 : disable - -void f3(void) { - double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}} -} Index: test/SemaOpenCL/extensions.cl =================================================================== --- /dev/null +++ test/SemaOpenCL/extensions.cl @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL1.1 + +void f1(double da) { // expected-error {{type 'double' requires cl_khr_fp64 extension}} + double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}} + (void) 1.0; // expected-warning {{double precision constant requires cl_khr_fp64}} +} + +#pragma OPENCL EXTENSION cl_khr_fp64 : enable + +void f2(void) { + double d; + (void) 1.0; +} + +#pragma OPENCL EXTENSION cl_khr_fp64 : disable + +void f3(void) { + double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}} +}