diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 39af84c8d0872..1f5932225d31e 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -1848,6 +1848,9 @@ class TargetInfo : public TransferrableTargetInfo, } } + /// Set features that depend on other features. + virtual void setDependentOpenCLOpts(); + /// Get supported OpenCL extensions and optional core features. llvm::StringMap &getSupportedOpenCLOpts() { return getTargetOpts().OpenCLFeaturesMap; diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 9a5db6e164f66..c0ed900ebd45c 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -640,6 +640,17 @@ bool TargetInfo::areDefaultedSMFStillPOD(const LangOptions &LangOpts) const { return LangOpts.getClangABICompat() > LangOptions::ClangABI::Ver15; } +void TargetInfo::setDependentOpenCLOpts() { + auto &Opts = getSupportedOpenCLOpts(); + if (!hasFeatureEnabled(Opts, "cl_khr_fp64") || + !hasFeatureEnabled(Opts, "__opencl_c_fp64")) { + setFeatureEnabled(Opts, "__opencl_c_ext_fp64_global_atomic_add", false); + setFeatureEnabled(Opts, "__opencl_c_ext_fp64_local_atomic_add", false); + setFeatureEnabled(Opts, "__opencl_c_ext_fp64_global_atomic_min_max", false); + setFeatureEnabled(Opts, "__opencl_c_ext_fp64_local_atomic_min_max", false); + } +} + LangAS TargetInfo::getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const { switch (TK) { case OCLTK_Image: diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index f39c698b5d734..38eb1edd4bfb7 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -862,6 +862,7 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, Target->setSupportedOpenCLOpts(); Target->setCommandLineOpenCLOpts(); + Target->setDependentOpenCLOpts(); Target->setMaxAtomicWidth(); if (!Opts->DarwinTargetVariantTriple.empty()) diff --git a/clang/test/Misc/opencl-c-3.0.incorrect_define.cl b/clang/test/Misc/opencl-c-3.0.incorrect_define.cl new file mode 100644 index 0000000000000..7857175e46209 --- /dev/null +++ b/clang/test/Misc/opencl-c-3.0.incorrect_define.cl @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -verify -triple spir-unknown-unknown -cl-std=CL3.0 -cl-ext=-__opencl_c_fp64,-cl_khr_fp64 %s +// RUN: %clang_cc1 -verify -triple spir-unknown-unknown -cl-std=clc++2021 -cl-ext=-__opencl_c_fp64,-cl_khr_fp64 %s + +#if __opencl_c_ext_fp64_global_atomic_add != 0 +#error "Incorrectly defined __opencl_c_ext_fp64_global_atomic_add" +#endif +#if __opencl_c_ext_fp64_local_atomic_add != 0 +#error "Incorrectly defined __opencl_c_ext_fp64_local_atomic_add" +#endif +#if __opencl_c_ext_fp64_global_atomic_min_max != 0 +#error "Incorrectly defined __opencl_c_ext_fp64_global_atomic_min_max" +#endif +#if __opencl_c_ext_fp64_local_atomic_min_max != 0 +#error "Incorrectly defined __opencl_c_ext_fp64_local_atomic_min_max" +#endif + +// expected-no-diagnostics