Summary:
This patch adds a command line option '-cl-ext' to control a set of
supported OpenCL extensions. Option accepts a comma-separated list
of extensions prefixed with '+' or '-'.
It can be used together with a target triple to override support for some
extensions:
// spir target supports all extensions, but we want to disable fp64
clang -cc1 -triple spir-unknown-unknown -cl-ext=-cl_khr_fp64
Special 'all' extension allows to enable or disable all possible
extensions:
// only fp64 will be supported
clang -cc1 -triple spir-unknown-unknown -cl-ext=-all,+cl_khr_fp64
Patch by asavonic (Andrew Savonichev).
Reviewers: joey, yaxunl
Subscribers: yaxunl, bader, Anastasia, cfe-commits
Differential Revision: https://reviews.llvm.org/D23712
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@285700
91177308-0d34-0410-b5e6-
96231b3b80d8
#ifndef LLVM_CLANG_BASIC_OPENCLOPTIONS_H
#define LLVM_CLANG_BASIC_OPENCLOPTIONS_H
+#include "llvm/ADT/StringRef.h"
+
namespace clang {
/// \brief OpenCL supported extensions and optional core features
#include "clang/Basic/OpenCLExtensions.def"
}
- // Enable all options.
- void setAll() {
-#define OPENCLEXT(nm) nm = 1;
+ // Enable or disable all options.
+ void setAll(bool Enable = true) {
+#define OPENCLEXT(nm) nm = Enable;
+#include "clang/Basic/OpenCLExtensions.def"
+ }
+
+ /// \brief Enable or disable support for OpenCL extensions
+ /// \param Ext name of the extension optionally prefixed with
+ /// '+' or '-'
+ /// \param Enable used when \p Ext is not prefixed by '+' or '-'
+ void set(llvm::StringRef Ext, bool Enable = true) {
+ assert(!Ext.empty() && "Extension is empty.");
+
+ switch (Ext[0]) {
+ case '+':
+ Enable = true;
+ Ext = Ext.drop_front();
+ break;
+ case '-':
+ Enable = false;
+ Ext = Ext.drop_front();
+ break;
+ }
+
+ if (Ext.equals("all")) {
+ setAll(Enable);
+ return;
+ }
+
+#define OPENCLEXT(nm) \
+ if (Ext.equals(#nm)) { \
+ nm = Enable; \
+ }
#include "clang/Basic/OpenCLExtensions.def"
}
/// \brief Set supported OpenCL extensions and optional core features.
virtual void setSupportedOpenCLOpts() {}
+ /// \brief Set supported OpenCL extensions as written on command line
+ virtual void setOpenCLExtensionOpts() {
+ for (const auto &Ext : getTargetOpts().OpenCLExtensionsAsWritten) {
+ getTargetOpts().SupportedOpenCLOptions.set(Ext);
+ }
+ }
+
/// \brief Get supported OpenCL extensions and optional core features.
OpenCLOptions &getSupportedOpenCLOpts() {
return getTargetOpts().SupportedOpenCLOptions;
/// Supported OpenCL extensions and optional core features.
OpenCLOptions SupportedOpenCLOptions;
+
+ /// \brief The list of OpenCL extensions to enable or disable, as written on
+ /// the command line.
+ std::vector<std::string> OpenCLExtensionsAsWritten;
};
} // end namespace clang
def detailed_preprocessing_record : Flag<["-"], "detailed-preprocessing-record">,
HelpText<"include a detailed record of preprocessing actions">;
+//===----------------------------------------------------------------------===//
+// OpenCL Options
+//===----------------------------------------------------------------------===//
+
+def cl_ext_EQ : CommaJoined<["-"], "cl-ext=">,
+ HelpText<"OpenCL only. Enable or disable OpenCL extensions. The argument is a comma-separated sequence of one or more extension names, each prefixed by '+' or '-'.">;
+
//===----------------------------------------------------------------------===//
// CUDA Options
//===----------------------------------------------------------------------===//
return nullptr;
Target->setSupportedOpenCLOpts();
+ Target->setOpenCLExtensionOpts();
if (!Target->validateTarget(Diags))
return nullptr;
// Use the default target triple if unspecified.
if (Opts.Triple.empty())
Opts.Triple = llvm::sys::getDefaultTargetTriple();
+ Opts.OpenCLExtensionsAsWritten = Args.getAllArgValues(OPT_cl_ext_EQ);
}
bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL1.1
// Test with a target not supporting fp64.
-// RUN: %clang_cc1 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -DNOFP64
+// RUN: %clang_cc1 %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
+//
+// Target does not support fp64 and fp16 - override it
+// RUN: %clang_cc1 %s -triple r600-unknown-unknown -target-cpu r600 -verify -pedantic -fsyntax-only -cl-ext=+cl_khr_fp64,+cl_khr_fp16
+//
+// Disable or enable all extensions
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-ext=-all -DNOFP64 -DNOFP16
+// 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
+//
+// 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
+
+
void f1(double da) { // expected-error {{type 'double' requires cl_khr_fp64 extension}}
double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}}
// expected-warning@-2{{unsupported OpenCL extension 'cl_khr_fp64' - ignoring}}
#endif
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+#ifdef NOFP16
+// expected-warning@-2{{unsupported OpenCL extension 'cl_khr_fp16' - ignoring}}
+#endif
+
void f2(void) {
double d;
#ifdef NOFP64