[clang] [Clang][OpenCL] Promote a few extensions to OpenCL 3.1 core (PR #204330)
Wenju He via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 15 17:46:51 PDT 2026
https://github.com/wenju-he updated https://github.com/llvm/llvm-project/pull/204330
>From f4aa82f80e00592bf7bf4d45e0cdde8f46b62f0e Mon Sep 17 00:00:00 2001
From: Wenju He <wenju.he at intel.com>
Date: Wed, 17 Jun 2026 12:05:19 +0200
Subject: [PATCH 1/3] [Clang][OpenCL] Promote a few extensions to OpenCL 3.1
core
Following 6 OpenCL extensions are promoted to core features in 3.1:
https://github.com/KhronosGroup/OpenCL-Docs/commit/9fff1a87a975
- cl_khr_extended_bit_ops
- cl_khr_integer_dot_product
- cl_khr_subgroup_extended_types
- cl_khr_subgroup_rotate
- cl_khr_subgroup_shuffle
- cl_khr_subgroup_shuffle_relative
Built-in functions in these extensions are available in OpenCL 3.1
without explicitly enabling them via `-cl-ext=+ext`.
Updated release notes for the change.
Assisted-by: Claude
---
clang/docs/ReleaseNotes.rst | 6 +++
clang/lib/Headers/opencl-c.h | 32 +++++++-----
clang/lib/Sema/OpenCLBuiltins.td | 21 +++++---
clang/lib/Sema/SemaLookup.cpp | 27 ++++++----
clang/test/SemaOpenCL/extension-version.cl | 2 +
.../SemaOpenCL/fdeclare-opencl-builtins.cl | 39 ++++++++++++++
.../TableGen/ClangOpenCLBuiltinEmitter.cpp | 52 ++++++++++++++-----
7 files changed, 137 insertions(+), 42 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 89909fe27cbb9..9c33970ac448d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -825,6 +825,12 @@ OpenACC Specific Changes
OpenCL Specific Changes
-----------------------
- Added support for OpenCL C 3.1 language version (``-cl-std=CL3.1``).
+- Extensions ``cl_khr_extended_bit_ops``, ``cl_khr_integer_dot_product``,
+ ``cl_khr_subgroup_extended_types``, ``cl_khr_subgroup_rotate``,
+ ``cl_khr_subgroup_shuffle``, and ``cl_khr_subgroup_shuffle_relative`` are
+ promoted to core features in OpenCL C 3.1. Built-in functions from these
+ extensions are available in OpenCL C 3.1 without explicitly enabling them via
+ ``-cl-ext=+ext``.
Target Specific Changes
-----------------------
diff --git a/clang/lib/Headers/opencl-c.h b/clang/lib/Headers/opencl-c.h
index 6d0bf7cb89974..fb84c5223361b 100644
--- a/clang/lib/Headers/opencl-c.h
+++ b/clang/lib/Headers/opencl-c.h
@@ -16439,7 +16439,8 @@ double __ovld __conv sub_group_scan_inclusive_max(double);
#endif // __opencl_subgroup_builtins
-#if defined(cl_khr_subgroup_extended_types)
+#if defined(cl_khr_subgroup_extended_types) || \
+ (__OPENCL_C_VERSION__ >= CL_VERSION_3_1)
char __ovld __conv sub_group_broadcast( char value, uint index );
char2 __ovld __conv sub_group_broadcast( char2 value, uint index );
char3 __ovld __conv sub_group_broadcast( char3 value, uint index );
@@ -16566,7 +16567,7 @@ double8 __ovld __conv sub_group_broadcast( double8 value, uint index );
double16 __ovld __conv sub_group_broadcast( double16 value, uint index );
#endif // cl_khr_fp64
-#endif // cl_khr_subgroup_extended_types
+#endif // cl_khr_subgroup_extended_types || CL_VERSION_3_1
#if defined(cl_khr_subgroup_non_uniform_vote)
int __ovld sub_group_elect(void);
@@ -16953,7 +16954,7 @@ double __ovld sub_group_non_uniform_scan_exclusive_max( double value );
#endif // cl_khr_subgroup_non_uniform_arithmetic
-#if defined(cl_khr_subgroup_shuffle)
+#if defined(cl_khr_subgroup_shuffle) || (__OPENCL_C_VERSION__ >= CL_VERSION_3_1)
char __ovld sub_group_shuffle( char value, uint index );
uchar __ovld sub_group_shuffle( uchar value, uint index );
short __ovld sub_group_shuffle( short value, uint index );
@@ -16984,9 +16985,10 @@ double __ovld sub_group_shuffle( double value, uint index );
double __ovld sub_group_shuffle_xor( double value, uint mask );
#endif // cl_khr_fp64
-#endif // cl_khr_subgroup_shuffle
+#endif // cl_khr_subgroup_shuffle || CL_VERSION_3_1
-#if defined(cl_khr_subgroup_shuffle_relative)
+#if defined(cl_khr_subgroup_shuffle_relative) || \
+ (__OPENCL_C_VERSION__ >= CL_VERSION_3_1)
char __ovld sub_group_shuffle_up( char value, uint delta );
uchar __ovld sub_group_shuffle_up( uchar value, uint delta );
short __ovld sub_group_shuffle_up( short value, uint delta );
@@ -17017,7 +17019,7 @@ double __ovld sub_group_shuffle_up( double value, uint delta );
double __ovld sub_group_shuffle_down( double value, uint delta );
#endif // cl_khr_fp64
-#endif // cl_khr_subgroup_shuffle_relative
+#endif // cl_khr_subgroup_shuffle_relative || CL_VERSION_3_1
#if defined(cl_khr_subgroup_clustered_reduce)
char __ovld sub_group_clustered_reduce_add( char value, uint clustersize );
@@ -17107,7 +17109,7 @@ double __ovld sub_group_clustered_reduce_max( double value, uint clustersize );
#endif // cl_khr_subgroup_clustered_reduce
-#if defined(cl_khr_extended_bit_ops)
+#if defined(cl_khr_extended_bit_ops) || (__OPENCL_C_VERSION__ >= CL_VERSION_3_1)
char __ovld __cnfn bitfield_insert(char, char, uint, uint);
uchar __ovld __cnfn bitfield_insert(uchar, uchar, uint, uint);
short __ovld __cnfn bitfield_insert(short, short, uint, uint);
@@ -17305,9 +17307,10 @@ int16 __ovld __cnfn bit_reverse(int16);
uint16 __ovld __cnfn bit_reverse(uint16);
long16 __ovld __cnfn bit_reverse(long16);
ulong16 __ovld __cnfn bit_reverse(ulong16);
-#endif // cl_khr_extended_bit_ops
+#endif // cl_khr_extended_bit_ops || CL_VERSION_3_1
-#if defined(__opencl_c_integer_dot_product_input_4x8bit)
+#if defined(__opencl_c_integer_dot_product_input_4x8bit) || \
+ (__OPENCL_C_VERSION__ >= CL_VERSION_3_1)
uint __ovld __cnfn dot(uchar4, uchar4);
int __ovld __cnfn dot(char4, char4);
int __ovld __cnfn dot(uchar4, char4);
@@ -17317,9 +17320,10 @@ uint __ovld __cnfn dot_acc_sat(uchar4, uchar4, uint);
int __ovld __cnfn dot_acc_sat(char4, char4, int);
int __ovld __cnfn dot_acc_sat(uchar4, char4, int);
int __ovld __cnfn dot_acc_sat(char4, uchar4, int);
-#endif // __opencl_c_integer_dot_product_input_4x8bit
+#endif // __opencl_c_integer_dot_product_input_4x8bit || CL_VERSION_3_1
-#if defined(__opencl_c_integer_dot_product_input_4x8bit_packed)
+#if defined(__opencl_c_integer_dot_product_input_4x8bit_packed) || \
+ (__OPENCL_C_VERSION__ >= CL_VERSION_3_1)
uint __ovld __cnfn dot_4x8packed_uu_uint(uint, uint);
int __ovld __cnfn dot_4x8packed_ss_int(uint, uint);
int __ovld __cnfn dot_4x8packed_us_int(uint, uint);
@@ -17329,9 +17333,9 @@ uint __ovld __cnfn dot_acc_sat_4x8packed_uu_uint(uint, uint, uint);
int __ovld __cnfn dot_acc_sat_4x8packed_ss_int(uint, uint, int);
int __ovld __cnfn dot_acc_sat_4x8packed_us_int(uint, uint, int);
int __ovld __cnfn dot_acc_sat_4x8packed_su_int(uint, uint, int);
-#endif // __opencl_c_integer_dot_product_input_4x8bit_packed
+#endif // __opencl_c_integer_dot_product_input_4x8bit_packed || CL_VERSION_3_1
-#if defined(cl_khr_subgroup_rotate)
+#if defined(cl_khr_subgroup_rotate) || (__OPENCL_C_VERSION__ >= CL_VERSION_3_1)
char __ovld __conv sub_group_rotate(char, int);
uchar __ovld __conv sub_group_rotate(uchar, int);
short __ovld __conv sub_group_rotate(short, int);
@@ -17363,7 +17367,7 @@ double __ovld __conv sub_group_clustered_rotate(double, int, uint);
#if defined(cl_khr_fp16)
half __ovld __conv sub_group_clustered_rotate(half, int, uint);
#endif // cl_khr_fp16
-#endif // cl_khr_subgroup_rotate
+#endif // cl_khr_subgroup_rotate || CL_VERSION_3_1
#if defined(cl_khr_kernel_clock)
#if defined(__opencl_c_kernel_clock_scope_device)
diff --git a/clang/lib/Sema/OpenCLBuiltins.td b/clang/lib/Sema/OpenCLBuiltins.td
index 761c9771b0891..273bcf2704bc1 100644
--- a/clang/lib/Sema/OpenCLBuiltins.td
+++ b/clang/lib/Sema/OpenCLBuiltins.td
@@ -27,6 +27,8 @@ def CL10 : Version<100>;
def CL11 : Version<110>;
def CL12 : Version<120>;
def CL20 : Version<200>;
+def CL30 : Version<300>;
+def CL31 : Version<310>;
// Address spaces
// Pointer types need to be assigned an address space.
@@ -337,6 +339,11 @@ class Builtin<string _Name, list<Type> _Signature, list<bit> _Attributes = Attr.
// MaxVersion is exclusive.
// CLAll makes the function available for all versions.
Version MaxVersion = CLAll;
+ // If the function belongs to an extension that was promoted to core in a later
+ // OpenCL version, set CoreMinVersion to that version so the function is also
+ // available without the extension macro from that version on.
+ // CLAll (the default) means no such promotion applies.
+ Version CoreMinVersion = CLAll;
}
//===----------------------------------------------------------------------===//
@@ -1759,7 +1766,7 @@ let Extension = FuncExtKhrSubgroups in {
// OpenCL Extension v3.0 s38 - Extended Subgroup Functions
// Section 38.4.1 - cl_khr_subgroup_extended_types
-let Extension = FuncExtKhrSubgroupExtendedTypes in {
+let Extension = FuncExtKhrSubgroupExtendedTypes, CoreMinVersion = CL31 in {
// For sub_group_broadcast, add scalar char, uchar, short, and ushort support,
def : Builtin<"sub_group_broadcast", [CharShortGenType1, CharShortGenType1, UInt], Attr.Convergent>;
// gentype may additionally be one of the supported built-in vector data types.
@@ -1815,13 +1822,13 @@ let Extension = FuncExtKhrSubgroupNonUniformArithmetic in {
}
// Section 38.8.1 - cl_khr_subgroup_shuffle
-let Extension = FuncExtKhrSubgroupShuffle in {
+let Extension = FuncExtKhrSubgroupShuffle, CoreMinVersion = CL31 in {
def : Builtin<"sub_group_shuffle", [AGenType1, AGenType1, UInt]>;
def : Builtin<"sub_group_shuffle_xor", [AGenType1, AGenType1, UInt]>;
}
// Section 38.9.1 - cl_khr_subgroup_shuffle_relative
-let Extension = FuncExtKhrSubgroupShuffleRelative in {
+let Extension = FuncExtKhrSubgroupShuffleRelative, CoreMinVersion = CL31 in {
def : Builtin<"sub_group_shuffle_up", [AGenType1, AGenType1, UInt]>;
def : Builtin<"sub_group_shuffle_down", [AGenType1, AGenType1, UInt]>;
}
@@ -1840,7 +1847,7 @@ let Extension = FuncExtKhrSubgroupClusteredReduce in {
}
// Section 40.3.1 - cl_khr_extended_bit_ops
-let Extension = FuncExtKhrExtendedBitOps in {
+let Extension = FuncExtKhrExtendedBitOps, CoreMinVersion = CL31 in {
def : Builtin<"bitfield_insert", [AIGenTypeN, AIGenTypeN, AIGenTypeN, UInt, UInt], Attr.Const>;
def : Builtin<"bitfield_extract_signed", [SGenTypeN, SGenTypeN, UInt, UInt], Attr.Const>;
def : Builtin<"bitfield_extract_signed", [SGenTypeN, UGenTypeN, UInt, UInt], Attr.Const>;
@@ -1850,7 +1857,7 @@ let Extension = FuncExtKhrExtendedBitOps in {
}
// Section 42.3 - cl_khr_integer_dot_product
-let Extension = FunctionExtension<"__opencl_c_integer_dot_product_input_4x8bit"> in {
+let Extension = FunctionExtension<"__opencl_c_integer_dot_product_input_4x8bit">, CoreMinVersion = CL31 in {
def : Builtin<"dot", [UInt, VectorType<UChar, 4>, VectorType<UChar, 4>], Attr.Const>;
def : Builtin<"dot", [Int, VectorType<Char, 4>, VectorType<Char, 4>], Attr.Const>;
def : Builtin<"dot", [Int, VectorType<UChar, 4>, VectorType<Char, 4>], Attr.Const>;
@@ -1862,7 +1869,7 @@ let Extension = FunctionExtension<"__opencl_c_integer_dot_product_input_4x8bit">
def : Builtin<"dot_acc_sat", [Int, VectorType<Char, 4>, VectorType<UChar, 4>, Int], Attr.Const>;
}
-let Extension = FunctionExtension<"__opencl_c_integer_dot_product_input_4x8bit_packed"> in {
+let Extension = FunctionExtension<"__opencl_c_integer_dot_product_input_4x8bit_packed">, CoreMinVersion = CL31 in {
def : Builtin<"dot_4x8packed_uu_uint", [UInt, UInt, UInt], Attr.Const>;
def : Builtin<"dot_4x8packed_ss_int", [Int, UInt, UInt], Attr.Const>;
def : Builtin<"dot_4x8packed_us_int", [Int, UInt, UInt], Attr.Const>;
@@ -1875,7 +1882,7 @@ let Extension = FunctionExtension<"__opencl_c_integer_dot_product_input_4x8bit_p
}
// Section 48.3 - cl_khr_subgroup_rotate
-let Extension = FunctionExtension<"cl_khr_subgroup_rotate"> in {
+let Extension = FunctionExtension<"cl_khr_subgroup_rotate">, CoreMinVersion = CL31 in {
def : Builtin<"sub_group_rotate", [AGenType1, AGenType1, Int], Attr.Convergent>;
def : Builtin<"sub_group_clustered_rotate", [AGenType1, AGenType1, Int, UInt], Attr.Convergent>;
}
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 65b60964d1192..30996984e7a68 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -844,19 +844,28 @@ static void InsertOCLBuiltinDeclarationsFromTable(Sema &S, LookupResult &LR,
// Ignore this builtin function if it carries an extension macro that is
// not defined. This indicates that the extension is not supported by the
// target, so the builtin function should not be available.
+ // Exception: if CoreVersions is set and the current OpenCL version is
+ // greater than or equal to the value, the builtin is available as core
+ // regardless of whether the extension macro is defined.
StringRef Extensions = FunctionExtensionTable[OpenCLBuiltin.Extension];
if (!Extensions.empty()) {
- SmallVector<StringRef, 2> ExtVec;
- Extensions.split(ExtVec, " ");
- bool AllExtensionsDefined = true;
- for (StringRef Ext : ExtVec) {
- if (!S.getPreprocessor().isMacroDefined(Ext)) {
- AllExtensionsDefined = false;
- break;
+ bool AvailableAsCore =
+ OpenCLBuiltin.CoreVersions &&
+ isOpenCLVersionContainedInMask(Context.getLangOpts(),
+ OpenCLBuiltin.CoreVersions);
+ if (!AvailableAsCore) {
+ SmallVector<StringRef, 2> ExtVec;
+ Extensions.split(ExtVec, " ");
+ bool AllExtensionsDefined = true;
+ for (StringRef Ext : ExtVec) {
+ if (!S.getPreprocessor().isMacroDefined(Ext)) {
+ AllExtensionsDefined = false;
+ break;
+ }
}
+ if (!AllExtensionsDefined)
+ continue;
}
- if (!AllExtensionsDefined)
- continue;
}
SmallVector<QualType, 1> RetTypes;
diff --git a/clang/test/SemaOpenCL/extension-version.cl b/clang/test/SemaOpenCL/extension-version.cl
index a02dbb93a535d..ee53b345a7eb2 100644
--- a/clang/test/SemaOpenCL/extension-version.cl
+++ b/clang/test/SemaOpenCL/extension-version.cl
@@ -4,12 +4,14 @@
// RUN: %clang_cc1 -x cl -cl-std=CL2.0 %s -verify -triple spir-unknown-unknown
// RUN: %clang_cc1 -x cl -cl-std=clc++ %s -verify -triple spir-unknown-unknown
// RUN: %clang_cc1 -x cl -cl-std=CL3.0 %s -verify -triple spir-unknown-unknown
+// RUN: %clang_cc1 -x cl -cl-std=CL3.1 %s -verify -triple spir-unknown-unknown
// RUN: %clang_cc1 -x cl -cl-std=CL %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
// RUN: %clang_cc1 -x cl -cl-std=CL1.1 %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
// RUN: %clang_cc1 -x cl -cl-std=CL1.2 %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
// RUN: %clang_cc1 -x cl -cl-std=CL2.0 %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
// RUN: %clang_cc1 -x cl -cl-std=clc++ %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
// RUN: %clang_cc1 -x cl -cl-std=CL3.0 %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
+// RUN: %clang_cc1 -x cl -cl-std=CL3.1 %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
// Extensions in all versions
#ifndef cl_clang_storage_class_specifiers
diff --git a/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl b/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl
index 1fb2579bdc483..0b0cca5dbe2de 100644
--- a/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl
+++ b/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl
@@ -5,11 +5,15 @@
// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CL2.0 -fdeclare-opencl-builtins -DNO_HEADER
// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CL2.0 -fdeclare-opencl-builtins -finclude-default-header
// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CL3.0 -fdeclare-opencl-builtins -finclude-default-header
+// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CL3.1 -fdeclare-opencl-builtins -finclude-default-header
+// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CL3.1 -fdeclare-opencl-builtins -DNO_HEADER
// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CLC++ -fdeclare-opencl-builtins -DNO_HEADER
// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CLC++ -fdeclare-opencl-builtins -finclude-default-header
// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CLC++2021 -fdeclare-opencl-builtins -finclude-default-header
// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CL2.0 -fdeclare-opencl-builtins -finclude-default-header -cl-ext=-cl_khr_fp64 -DNO_FP64
// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CL3.0 -fdeclare-opencl-builtins -finclude-default-header -DNO_ATOMSCOPE
+// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CL3.0 -fdeclare-opencl-builtins -finclude-default-header -DTEST_3_1_CORE_EXT -DNO_3_1_BUILTIN
+// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CL3.1 -fdeclare-opencl-builtins -finclude-default-header -DTEST_3_1_CORE_EXT
// Test the -fdeclare-opencl-builtins option. This is not a completeness
// test, so it should not test for all builtins defined by OpenCL. Instead
@@ -551,3 +555,38 @@ void test_extension_types(char2 c2) {
// expected-note at -3 6 {{candidate function not viable: no known conversion from '__private char2' (vector of 2 'char' values) to 'half}}
}
#endif
+
+// Test builtins from extensions promoted to OpenCL 3.1 core.
+#ifdef TEST_3_1_CORE_EXT
+#undef cl_khr_extended_bit_ops
+#undef cl_khr_subgroup_rotate
+#undef cl_khr_subgroup_shuffle
+#undef cl_khr_subgroup_shuffle_relative
+#undef cl_khr_subgroup_extended_types
+#undef __opencl_c_integer_dot_product_input_4x8bit
+#undef __opencl_c_integer_dot_product_input_4x8bit_packed
+
+kernel void test_core_builtins(int i, char c, uchar4 uc4, char4 c4, uint u1) {
+ int x = bitfield_insert(i, i, 0u, 8u); // cl_khr_extended_bit_ops
+ uint u2 = dot_acc_sat(uc4, uc4, u1); // cl_khr_integer_dot_product (4x8bit)
+ u2 = dot_4x8packed_uu_uint(u1, u1); // cl_khr_integer_dot_product (4x8bit_packed)
+ x = sub_group_broadcast((char2)c, 0u).x; // cl_khr_subgroup_extended_types
+ x = sub_group_rotate(i, 1); // cl_khr_subgroup_rotate
+ x = sub_group_shuffle(i, 0u); // cl_khr_subgroup_shuffle
+ x = sub_group_shuffle_xor(i, 1u); // cl_khr_subgroup_shuffle
+ x = sub_group_shuffle_up(i, 1u); // cl_khr_subgroup_shuffle_relative
+ x = sub_group_shuffle_down(i, 1u); // cl_khr_subgroup_shuffle_relative
+#ifdef NO_3_1_BUILTIN
+// expected-error at -10{{use of undeclared identifier 'bitfield_insert'}}
+// expected-error at -10{{use of undeclared identifier 'dot_acc_sat'}}
+// expected-error at -10{{use of undeclared identifier 'dot_4x8packed_uu_uint'}}
+// expected-error at -10{{no matching function for call to 'sub_group_broadcast'}}
+// expected-note at -11 0+{{candidate function not viable}}
+// expected-error at -11{{use of undeclared identifier 'sub_group_rotate'}}
+// expected-error at -11{{use of undeclared identifier 'sub_group_shuffle'}}
+// expected-error at -11{{use of undeclared identifier 'sub_group_shuffle_xor'}}
+// expected-error at -11{{use of undeclared identifier 'sub_group_shuffle_up'}}
+// expected-error at -11{{use of undeclared identifier 'sub_group_shuffle_down'}}
+#endif
+}
+#endif // TEST_3_1_CORE_EXT
diff --git a/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp b/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp
index a666dd1ed795d..89feefa2b293a 100644
--- a/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp
+++ b/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp
@@ -446,6 +446,9 @@ struct OpenCLBuiltinStruct {
const unsigned short Extension;
// OpenCL versions in which this overload is available.
const unsigned short Versions;
+ // OpenCL versions in which this overload is available as core
+ // (i.e. without requiring the extension macro). Zero means not promoted.
+ const unsigned short CoreVersions;
};
)";
@@ -632,6 +635,8 @@ void BuiltinNameEmitter::EmitBuiltinTable() {
Overload.first->getValueAsDef("MinVersion")->getValueAsInt("ID");
unsigned int MaxVersion =
Overload.first->getValueAsDef("MaxVersion")->getValueAsInt("ID");
+ unsigned int CoreMinVersion =
+ Overload.first->getValueAsDef("CoreMinVersion")->getValueAsInt("ID");
OS << " { " << Overload.second << ", "
<< Overload.first->getValueAsListOfDefs("Signature").size() << ", "
@@ -639,7 +644,8 @@ void BuiltinNameEmitter::EmitBuiltinTable() {
<< (Overload.first->getValueAsBit("IsConst")) << ", "
<< (Overload.first->getValueAsBit("IsConv")) << ", "
<< FunctionExtensionIndex[ExtName] << ", "
- << EncodeVersions(MinVersion, MaxVersion) << " },\n";
+ << EncodeVersions(MinVersion, MaxVersion) << ", "
+ << (CoreMinVersion ? EncodeVersions(CoreMinVersion, 0) : 0) << " },\n";
Index++;
}
}
@@ -664,6 +670,8 @@ bool BuiltinNameEmitter::CanReuseSignature(
Rec2->getValueAsDef("MinVersion")->getValueAsInt("ID") &&
Rec->getValueAsDef("MaxVersion")->getValueAsInt("ID") ==
Rec2->getValueAsDef("MaxVersion")->getValueAsInt("ID") &&
+ Rec->getValueAsDef("CoreMinVersion")->getValueAsInt("ID") ==
+ Rec2->getValueAsDef("CoreMinVersion")->getValueAsInt("ID") &&
Rec->getValueAsDef("Extension")->getName() ==
Rec2->getValueAsDef("Extension")->getName()) {
return true;
@@ -1123,19 +1131,39 @@ OpenCLBuiltinFileEmitterBase::emitExtensionGuard(const Record *Builtin) {
if (Extensions.empty())
return "";
- OS << "#if";
-
- SmallVector<StringRef, 2> ExtVec;
- Extensions.split(ExtVec, " ");
- bool isFirst = true;
- for (StringRef Ext : ExtVec) {
- if (!isFirst) {
- OS << " &&";
+ int CoreMinVersion =
+ Builtin->getValueAsDef("CoreMinVersion")->getValueAsInt("ID");
+
+ // If this extension was promoted to core, guard as:
+ // #if defined(EXT) || __OPENCL_C_VERSION__ >= CORE_VERSION
+ // Otherwise guard as:
+ // #if defined(EXT0) && defined(EXT1) && ...
+ if (CoreMinVersion) {
+ SmallVector<StringRef, 2> ExtVec;
+ Extensions.split(ExtVec, " ");
+ OS << "#if (";
+ bool isFirst = true;
+ for (StringRef Ext : ExtVec) {
+ if (!isFirst)
+ OS << " && ";
+ OS << "defined(" << Ext << ")";
+ isFirst = false;
}
- OS << " defined(" << Ext << ")";
- isFirst = false;
+ OS << ") || (__OPENCL_C_VERSION__ >= CL_VERSION_" << (CoreMinVersion / 100)
+ << "_" << ((CoreMinVersion % 100) / 10) << ")\n";
+ } else {
+ OS << "#if";
+ SmallVector<StringRef, 2> ExtVec;
+ Extensions.split(ExtVec, " ");
+ bool isFirst = true;
+ for (StringRef Ext : ExtVec) {
+ if (!isFirst)
+ OS << " &&";
+ OS << " defined(" << Ext << ")";
+ isFirst = false;
+ }
+ OS << "\n";
}
- OS << "\n";
return "#endif // Extension\n";
}
>From 0a0ae5bd4c948d8f8fe3309750aa7cb8e19b5587 Mon Sep 17 00:00:00 2001
From: Wenju He <wenju.he at intel.com>
Date: Wed, 15 Jul 2026 14:48:14 +0200
Subject: [PATCH 2/3] enable features in OpenCLExtensions.def
---
clang/docs/ReleaseNotes.md | 5 +-
.../include/clang/Basic/OpenCLExtensions.def | 14 ++---
clang/lib/Headers/opencl-c.h | 32 +++++-------
clang/lib/Sema/OpenCLBuiltins.td | 21 +++-----
clang/lib/Sema/SemaLookup.cpp | 27 ++++------
.../SemaOpenCL/fdeclare-opencl-builtins.cl | 39 --------------
.../TableGen/ClangOpenCLBuiltinEmitter.cpp | 52 +++++--------------
7 files changed, 51 insertions(+), 139 deletions(-)
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index ffd6af8aed455..3642fb7de4f4c 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -149,9 +149,8 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the
- Extensions ``cl_khr_extended_bit_ops``, ``cl_khr_integer_dot_product``,
``cl_khr_subgroup_extended_types``, ``cl_khr_subgroup_rotate``,
``cl_khr_subgroup_shuffle``, and ``cl_khr_subgroup_shuffle_relative`` are
- promoted to core features in OpenCL C 3.1. Built-in functions from these
- extensions are available in OpenCL C 3.1 without explicitly enabling them via
- ``-cl-ext=+ext``.
+ promoted to optional core features in OpenCL C 3.1. Their extension macros
+ are defined automatically in OpenCL C 3.1 without needing ``-cl-ext=+ext``.
### Target Specific Changes
diff --git a/clang/include/clang/Basic/OpenCLExtensions.def b/clang/include/clang/Basic/OpenCLExtensions.def
index 08ac5f692616a..84a30114f553c 100644
--- a/clang/include/clang/Basic/OpenCLExtensions.def
+++ b/clang/include/clang/Basic/OpenCLExtensions.def
@@ -69,7 +69,7 @@ OPENCL_EXTENSION(cl_khr_fp16, true, 100)
OPENCL_EXTENSION(cl_khr_int64_base_atomics, true, 100)
OPENCL_EXTENSION(cl_khr_int64_extended_atomics, true, 100)
OPENCL_EXTENSION(cl_khr_depth_images, true, 100)
-OPENCL_EXTENSION(cl_khr_extended_bit_ops, false, 100)
+OPENCL_OPTIONALCOREFEATURE(cl_khr_extended_bit_ops, false, 100, OCL_C_31)
OPENCL_EXTENSION(cl_ext_float_atomics, false, 100)
OPENCL_EXTENSION(cl_khr_gl_msaa_sharing, true, 100)
OPENCL_EXTENSION(cl_khr_integer_dot_product, false, 100)
@@ -79,13 +79,13 @@ OPENCL_EXTENSION(cl_khr_mipmap_image_writes, true, 100)
OPENCL_EXTENSION(cl_khr_srgb_image_writes, true, 100)
OPENCL_EXTENSION(cl_khr_subgroup_ballot, false, 100)
OPENCL_EXTENSION(cl_khr_subgroup_clustered_reduce, false, 100)
-OPENCL_EXTENSION(cl_khr_subgroup_extended_types, false, 100)
+OPENCL_OPTIONALCOREFEATURE(cl_khr_subgroup_extended_types, false, 100, OCL_C_31)
OPENCL_EXTENSION(cl_khr_subgroup_named_barrier, false, 100)
OPENCL_EXTENSION(cl_khr_subgroup_non_uniform_arithmetic, false, 100)
OPENCL_EXTENSION(cl_khr_subgroup_non_uniform_vote, false, 100)
-OPENCL_EXTENSION(cl_khr_subgroup_rotate, false, 100)
-OPENCL_EXTENSION(cl_khr_subgroup_shuffle_relative, false, 100)
-OPENCL_EXTENSION(cl_khr_subgroup_shuffle, false, 100)
+OPENCL_OPTIONALCOREFEATURE(cl_khr_subgroup_rotate, false, 100, OCL_C_31)
+OPENCL_OPTIONALCOREFEATURE(cl_khr_subgroup_shuffle_relative, false, 100, OCL_C_31)
+OPENCL_OPTIONALCOREFEATURE(cl_khr_subgroup_shuffle, false, 100, OCL_C_31)
OPENCL_EXTENSION(cl_khr_subgroups, true, 100)
OPENCL_GENERIC_EXTENSION(cl_khr_3d_image_writes, true, 100, OCL_C_20, OCL_C_30)
@@ -117,8 +117,8 @@ OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_image_unorm_int_2_101010, false, 200,
OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_image_unsigned_10x6_12x4_14x2, false, 200, OCL_C_20)
OPENCL_GENERIC_EXTENSION(__opencl_c_generic_address_space, false, 200, OCL_C_20, OCL_C_30)
OPENCL_GENERIC_EXTENSION(__opencl_c_images, false, 200, OCL_C_20, OCL_C_30)
-OPENCL_OPTIONALCOREFEATURE(__opencl_c_integer_dot_product_input_4x8bit, false, 200, OCL_C_20)
-OPENCL_OPTIONALCOREFEATURE(__opencl_c_integer_dot_product_input_4x8bit_packed, false, 200, OCL_C_20)
+OPENCL_OPTIONALCOREFEATURE(__opencl_c_integer_dot_product_input_4x8bit, false, 200, OCL_C_20 | OCL_C_31)
+OPENCL_OPTIONALCOREFEATURE(__opencl_c_integer_dot_product_input_4x8bit_packed, false, 200, OCL_C_20 | OCL_C_31)
OPENCL_OPTIONALCOREFEATURE(__opencl_c_kernel_clock_scope_device, false, 200, OCL_C_20)
OPENCL_OPTIONALCOREFEATURE(__opencl_c_kernel_clock_scope_sub_group, false, 200, OCL_C_20)
OPENCL_OPTIONALCOREFEATURE(__opencl_c_kernel_clock_scope_work_group, false, 200, OCL_C_20)
diff --git a/clang/lib/Headers/opencl-c.h b/clang/lib/Headers/opencl-c.h
index fb84c5223361b..6d0bf7cb89974 100644
--- a/clang/lib/Headers/opencl-c.h
+++ b/clang/lib/Headers/opencl-c.h
@@ -16439,8 +16439,7 @@ double __ovld __conv sub_group_scan_inclusive_max(double);
#endif // __opencl_subgroup_builtins
-#if defined(cl_khr_subgroup_extended_types) || \
- (__OPENCL_C_VERSION__ >= CL_VERSION_3_1)
+#if defined(cl_khr_subgroup_extended_types)
char __ovld __conv sub_group_broadcast( char value, uint index );
char2 __ovld __conv sub_group_broadcast( char2 value, uint index );
char3 __ovld __conv sub_group_broadcast( char3 value, uint index );
@@ -16567,7 +16566,7 @@ double8 __ovld __conv sub_group_broadcast( double8 value, uint index );
double16 __ovld __conv sub_group_broadcast( double16 value, uint index );
#endif // cl_khr_fp64
-#endif // cl_khr_subgroup_extended_types || CL_VERSION_3_1
+#endif // cl_khr_subgroup_extended_types
#if defined(cl_khr_subgroup_non_uniform_vote)
int __ovld sub_group_elect(void);
@@ -16954,7 +16953,7 @@ double __ovld sub_group_non_uniform_scan_exclusive_max( double value );
#endif // cl_khr_subgroup_non_uniform_arithmetic
-#if defined(cl_khr_subgroup_shuffle) || (__OPENCL_C_VERSION__ >= CL_VERSION_3_1)
+#if defined(cl_khr_subgroup_shuffle)
char __ovld sub_group_shuffle( char value, uint index );
uchar __ovld sub_group_shuffle( uchar value, uint index );
short __ovld sub_group_shuffle( short value, uint index );
@@ -16985,10 +16984,9 @@ double __ovld sub_group_shuffle( double value, uint index );
double __ovld sub_group_shuffle_xor( double value, uint mask );
#endif // cl_khr_fp64
-#endif // cl_khr_subgroup_shuffle || CL_VERSION_3_1
+#endif // cl_khr_subgroup_shuffle
-#if defined(cl_khr_subgroup_shuffle_relative) || \
- (__OPENCL_C_VERSION__ >= CL_VERSION_3_1)
+#if defined(cl_khr_subgroup_shuffle_relative)
char __ovld sub_group_shuffle_up( char value, uint delta );
uchar __ovld sub_group_shuffle_up( uchar value, uint delta );
short __ovld sub_group_shuffle_up( short value, uint delta );
@@ -17019,7 +17017,7 @@ double __ovld sub_group_shuffle_up( double value, uint delta );
double __ovld sub_group_shuffle_down( double value, uint delta );
#endif // cl_khr_fp64
-#endif // cl_khr_subgroup_shuffle_relative || CL_VERSION_3_1
+#endif // cl_khr_subgroup_shuffle_relative
#if defined(cl_khr_subgroup_clustered_reduce)
char __ovld sub_group_clustered_reduce_add( char value, uint clustersize );
@@ -17109,7 +17107,7 @@ double __ovld sub_group_clustered_reduce_max( double value, uint clustersize );
#endif // cl_khr_subgroup_clustered_reduce
-#if defined(cl_khr_extended_bit_ops) || (__OPENCL_C_VERSION__ >= CL_VERSION_3_1)
+#if defined(cl_khr_extended_bit_ops)
char __ovld __cnfn bitfield_insert(char, char, uint, uint);
uchar __ovld __cnfn bitfield_insert(uchar, uchar, uint, uint);
short __ovld __cnfn bitfield_insert(short, short, uint, uint);
@@ -17307,10 +17305,9 @@ int16 __ovld __cnfn bit_reverse(int16);
uint16 __ovld __cnfn bit_reverse(uint16);
long16 __ovld __cnfn bit_reverse(long16);
ulong16 __ovld __cnfn bit_reverse(ulong16);
-#endif // cl_khr_extended_bit_ops || CL_VERSION_3_1
+#endif // cl_khr_extended_bit_ops
-#if defined(__opencl_c_integer_dot_product_input_4x8bit) || \
- (__OPENCL_C_VERSION__ >= CL_VERSION_3_1)
+#if defined(__opencl_c_integer_dot_product_input_4x8bit)
uint __ovld __cnfn dot(uchar4, uchar4);
int __ovld __cnfn dot(char4, char4);
int __ovld __cnfn dot(uchar4, char4);
@@ -17320,10 +17317,9 @@ uint __ovld __cnfn dot_acc_sat(uchar4, uchar4, uint);
int __ovld __cnfn dot_acc_sat(char4, char4, int);
int __ovld __cnfn dot_acc_sat(uchar4, char4, int);
int __ovld __cnfn dot_acc_sat(char4, uchar4, int);
-#endif // __opencl_c_integer_dot_product_input_4x8bit || CL_VERSION_3_1
+#endif // __opencl_c_integer_dot_product_input_4x8bit
-#if defined(__opencl_c_integer_dot_product_input_4x8bit_packed) || \
- (__OPENCL_C_VERSION__ >= CL_VERSION_3_1)
+#if defined(__opencl_c_integer_dot_product_input_4x8bit_packed)
uint __ovld __cnfn dot_4x8packed_uu_uint(uint, uint);
int __ovld __cnfn dot_4x8packed_ss_int(uint, uint);
int __ovld __cnfn dot_4x8packed_us_int(uint, uint);
@@ -17333,9 +17329,9 @@ uint __ovld __cnfn dot_acc_sat_4x8packed_uu_uint(uint, uint, uint);
int __ovld __cnfn dot_acc_sat_4x8packed_ss_int(uint, uint, int);
int __ovld __cnfn dot_acc_sat_4x8packed_us_int(uint, uint, int);
int __ovld __cnfn dot_acc_sat_4x8packed_su_int(uint, uint, int);
-#endif // __opencl_c_integer_dot_product_input_4x8bit_packed || CL_VERSION_3_1
+#endif // __opencl_c_integer_dot_product_input_4x8bit_packed
-#if defined(cl_khr_subgroup_rotate) || (__OPENCL_C_VERSION__ >= CL_VERSION_3_1)
+#if defined(cl_khr_subgroup_rotate)
char __ovld __conv sub_group_rotate(char, int);
uchar __ovld __conv sub_group_rotate(uchar, int);
short __ovld __conv sub_group_rotate(short, int);
@@ -17367,7 +17363,7 @@ double __ovld __conv sub_group_clustered_rotate(double, int, uint);
#if defined(cl_khr_fp16)
half __ovld __conv sub_group_clustered_rotate(half, int, uint);
#endif // cl_khr_fp16
-#endif // cl_khr_subgroup_rotate || CL_VERSION_3_1
+#endif // cl_khr_subgroup_rotate
#if defined(cl_khr_kernel_clock)
#if defined(__opencl_c_kernel_clock_scope_device)
diff --git a/clang/lib/Sema/OpenCLBuiltins.td b/clang/lib/Sema/OpenCLBuiltins.td
index 273bcf2704bc1..761c9771b0891 100644
--- a/clang/lib/Sema/OpenCLBuiltins.td
+++ b/clang/lib/Sema/OpenCLBuiltins.td
@@ -27,8 +27,6 @@ def CL10 : Version<100>;
def CL11 : Version<110>;
def CL12 : Version<120>;
def CL20 : Version<200>;
-def CL30 : Version<300>;
-def CL31 : Version<310>;
// Address spaces
// Pointer types need to be assigned an address space.
@@ -339,11 +337,6 @@ class Builtin<string _Name, list<Type> _Signature, list<bit> _Attributes = Attr.
// MaxVersion is exclusive.
// CLAll makes the function available for all versions.
Version MaxVersion = CLAll;
- // If the function belongs to an extension that was promoted to core in a later
- // OpenCL version, set CoreMinVersion to that version so the function is also
- // available without the extension macro from that version on.
- // CLAll (the default) means no such promotion applies.
- Version CoreMinVersion = CLAll;
}
//===----------------------------------------------------------------------===//
@@ -1766,7 +1759,7 @@ let Extension = FuncExtKhrSubgroups in {
// OpenCL Extension v3.0 s38 - Extended Subgroup Functions
// Section 38.4.1 - cl_khr_subgroup_extended_types
-let Extension = FuncExtKhrSubgroupExtendedTypes, CoreMinVersion = CL31 in {
+let Extension = FuncExtKhrSubgroupExtendedTypes in {
// For sub_group_broadcast, add scalar char, uchar, short, and ushort support,
def : Builtin<"sub_group_broadcast", [CharShortGenType1, CharShortGenType1, UInt], Attr.Convergent>;
// gentype may additionally be one of the supported built-in vector data types.
@@ -1822,13 +1815,13 @@ let Extension = FuncExtKhrSubgroupNonUniformArithmetic in {
}
// Section 38.8.1 - cl_khr_subgroup_shuffle
-let Extension = FuncExtKhrSubgroupShuffle, CoreMinVersion = CL31 in {
+let Extension = FuncExtKhrSubgroupShuffle in {
def : Builtin<"sub_group_shuffle", [AGenType1, AGenType1, UInt]>;
def : Builtin<"sub_group_shuffle_xor", [AGenType1, AGenType1, UInt]>;
}
// Section 38.9.1 - cl_khr_subgroup_shuffle_relative
-let Extension = FuncExtKhrSubgroupShuffleRelative, CoreMinVersion = CL31 in {
+let Extension = FuncExtKhrSubgroupShuffleRelative in {
def : Builtin<"sub_group_shuffle_up", [AGenType1, AGenType1, UInt]>;
def : Builtin<"sub_group_shuffle_down", [AGenType1, AGenType1, UInt]>;
}
@@ -1847,7 +1840,7 @@ let Extension = FuncExtKhrSubgroupClusteredReduce in {
}
// Section 40.3.1 - cl_khr_extended_bit_ops
-let Extension = FuncExtKhrExtendedBitOps, CoreMinVersion = CL31 in {
+let Extension = FuncExtKhrExtendedBitOps in {
def : Builtin<"bitfield_insert", [AIGenTypeN, AIGenTypeN, AIGenTypeN, UInt, UInt], Attr.Const>;
def : Builtin<"bitfield_extract_signed", [SGenTypeN, SGenTypeN, UInt, UInt], Attr.Const>;
def : Builtin<"bitfield_extract_signed", [SGenTypeN, UGenTypeN, UInt, UInt], Attr.Const>;
@@ -1857,7 +1850,7 @@ let Extension = FuncExtKhrExtendedBitOps, CoreMinVersion = CL31 in {
}
// Section 42.3 - cl_khr_integer_dot_product
-let Extension = FunctionExtension<"__opencl_c_integer_dot_product_input_4x8bit">, CoreMinVersion = CL31 in {
+let Extension = FunctionExtension<"__opencl_c_integer_dot_product_input_4x8bit"> in {
def : Builtin<"dot", [UInt, VectorType<UChar, 4>, VectorType<UChar, 4>], Attr.Const>;
def : Builtin<"dot", [Int, VectorType<Char, 4>, VectorType<Char, 4>], Attr.Const>;
def : Builtin<"dot", [Int, VectorType<UChar, 4>, VectorType<Char, 4>], Attr.Const>;
@@ -1869,7 +1862,7 @@ let Extension = FunctionExtension<"__opencl_c_integer_dot_product_input_4x8bit">
def : Builtin<"dot_acc_sat", [Int, VectorType<Char, 4>, VectorType<UChar, 4>, Int], Attr.Const>;
}
-let Extension = FunctionExtension<"__opencl_c_integer_dot_product_input_4x8bit_packed">, CoreMinVersion = CL31 in {
+let Extension = FunctionExtension<"__opencl_c_integer_dot_product_input_4x8bit_packed"> in {
def : Builtin<"dot_4x8packed_uu_uint", [UInt, UInt, UInt], Attr.Const>;
def : Builtin<"dot_4x8packed_ss_int", [Int, UInt, UInt], Attr.Const>;
def : Builtin<"dot_4x8packed_us_int", [Int, UInt, UInt], Attr.Const>;
@@ -1882,7 +1875,7 @@ let Extension = FunctionExtension<"__opencl_c_integer_dot_product_input_4x8bit_p
}
// Section 48.3 - cl_khr_subgroup_rotate
-let Extension = FunctionExtension<"cl_khr_subgroup_rotate">, CoreMinVersion = CL31 in {
+let Extension = FunctionExtension<"cl_khr_subgroup_rotate"> in {
def : Builtin<"sub_group_rotate", [AGenType1, AGenType1, Int], Attr.Convergent>;
def : Builtin<"sub_group_clustered_rotate", [AGenType1, AGenType1, Int, UInt], Attr.Convergent>;
}
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index ecadf1de07f11..43129800e9813 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -844,28 +844,19 @@ static void InsertOCLBuiltinDeclarationsFromTable(Sema &S, LookupResult &LR,
// Ignore this builtin function if it carries an extension macro that is
// not defined. This indicates that the extension is not supported by the
// target, so the builtin function should not be available.
- // Exception: if CoreVersions is set and the current OpenCL version is
- // greater than or equal to the value, the builtin is available as core
- // regardless of whether the extension macro is defined.
StringRef Extensions = FunctionExtensionTable[OpenCLBuiltin.Extension];
if (!Extensions.empty()) {
- bool AvailableAsCore =
- OpenCLBuiltin.CoreVersions &&
- isOpenCLVersionContainedInMask(Context.getLangOpts(),
- OpenCLBuiltin.CoreVersions);
- if (!AvailableAsCore) {
- SmallVector<StringRef, 2> ExtVec;
- Extensions.split(ExtVec, " ");
- bool AllExtensionsDefined = true;
- for (StringRef Ext : ExtVec) {
- if (!S.getPreprocessor().isMacroDefined(Ext)) {
- AllExtensionsDefined = false;
- break;
- }
+ SmallVector<StringRef, 2> ExtVec;
+ Extensions.split(ExtVec, " ");
+ bool AllExtensionsDefined = true;
+ for (StringRef Ext : ExtVec) {
+ if (!S.getPreprocessor().isMacroDefined(Ext)) {
+ AllExtensionsDefined = false;
+ break;
}
- if (!AllExtensionsDefined)
- continue;
}
+ if (!AllExtensionsDefined)
+ continue;
}
SmallVector<QualType, 1> RetTypes;
diff --git a/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl b/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl
index 0b0cca5dbe2de..1fb2579bdc483 100644
--- a/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl
+++ b/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl
@@ -5,15 +5,11 @@
// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CL2.0 -fdeclare-opencl-builtins -DNO_HEADER
// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CL2.0 -fdeclare-opencl-builtins -finclude-default-header
// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CL3.0 -fdeclare-opencl-builtins -finclude-default-header
-// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CL3.1 -fdeclare-opencl-builtins -finclude-default-header
-// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CL3.1 -fdeclare-opencl-builtins -DNO_HEADER
// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CLC++ -fdeclare-opencl-builtins -DNO_HEADER
// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CLC++ -fdeclare-opencl-builtins -finclude-default-header
// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CLC++2021 -fdeclare-opencl-builtins -finclude-default-header
// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CL2.0 -fdeclare-opencl-builtins -finclude-default-header -cl-ext=-cl_khr_fp64 -DNO_FP64
// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CL3.0 -fdeclare-opencl-builtins -finclude-default-header -DNO_ATOMSCOPE
-// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CL3.0 -fdeclare-opencl-builtins -finclude-default-header -DTEST_3_1_CORE_EXT -DNO_3_1_BUILTIN
-// RUN: %clang_cc1 %s -triple spir -verify -pedantic -Wconversion -Werror -fsyntax-only -cl-std=CL3.1 -fdeclare-opencl-builtins -finclude-default-header -DTEST_3_1_CORE_EXT
// Test the -fdeclare-opencl-builtins option. This is not a completeness
// test, so it should not test for all builtins defined by OpenCL. Instead
@@ -555,38 +551,3 @@ void test_extension_types(char2 c2) {
// expected-note at -3 6 {{candidate function not viable: no known conversion from '__private char2' (vector of 2 'char' values) to 'half}}
}
#endif
-
-// Test builtins from extensions promoted to OpenCL 3.1 core.
-#ifdef TEST_3_1_CORE_EXT
-#undef cl_khr_extended_bit_ops
-#undef cl_khr_subgroup_rotate
-#undef cl_khr_subgroup_shuffle
-#undef cl_khr_subgroup_shuffle_relative
-#undef cl_khr_subgroup_extended_types
-#undef __opencl_c_integer_dot_product_input_4x8bit
-#undef __opencl_c_integer_dot_product_input_4x8bit_packed
-
-kernel void test_core_builtins(int i, char c, uchar4 uc4, char4 c4, uint u1) {
- int x = bitfield_insert(i, i, 0u, 8u); // cl_khr_extended_bit_ops
- uint u2 = dot_acc_sat(uc4, uc4, u1); // cl_khr_integer_dot_product (4x8bit)
- u2 = dot_4x8packed_uu_uint(u1, u1); // cl_khr_integer_dot_product (4x8bit_packed)
- x = sub_group_broadcast((char2)c, 0u).x; // cl_khr_subgroup_extended_types
- x = sub_group_rotate(i, 1); // cl_khr_subgroup_rotate
- x = sub_group_shuffle(i, 0u); // cl_khr_subgroup_shuffle
- x = sub_group_shuffle_xor(i, 1u); // cl_khr_subgroup_shuffle
- x = sub_group_shuffle_up(i, 1u); // cl_khr_subgroup_shuffle_relative
- x = sub_group_shuffle_down(i, 1u); // cl_khr_subgroup_shuffle_relative
-#ifdef NO_3_1_BUILTIN
-// expected-error at -10{{use of undeclared identifier 'bitfield_insert'}}
-// expected-error at -10{{use of undeclared identifier 'dot_acc_sat'}}
-// expected-error at -10{{use of undeclared identifier 'dot_4x8packed_uu_uint'}}
-// expected-error at -10{{no matching function for call to 'sub_group_broadcast'}}
-// expected-note at -11 0+{{candidate function not viable}}
-// expected-error at -11{{use of undeclared identifier 'sub_group_rotate'}}
-// expected-error at -11{{use of undeclared identifier 'sub_group_shuffle'}}
-// expected-error at -11{{use of undeclared identifier 'sub_group_shuffle_xor'}}
-// expected-error at -11{{use of undeclared identifier 'sub_group_shuffle_up'}}
-// expected-error at -11{{use of undeclared identifier 'sub_group_shuffle_down'}}
-#endif
-}
-#endif // TEST_3_1_CORE_EXT
diff --git a/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp b/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp
index 89feefa2b293a..a666dd1ed795d 100644
--- a/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp
+++ b/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp
@@ -446,9 +446,6 @@ struct OpenCLBuiltinStruct {
const unsigned short Extension;
// OpenCL versions in which this overload is available.
const unsigned short Versions;
- // OpenCL versions in which this overload is available as core
- // (i.e. without requiring the extension macro). Zero means not promoted.
- const unsigned short CoreVersions;
};
)";
@@ -635,8 +632,6 @@ void BuiltinNameEmitter::EmitBuiltinTable() {
Overload.first->getValueAsDef("MinVersion")->getValueAsInt("ID");
unsigned int MaxVersion =
Overload.first->getValueAsDef("MaxVersion")->getValueAsInt("ID");
- unsigned int CoreMinVersion =
- Overload.first->getValueAsDef("CoreMinVersion")->getValueAsInt("ID");
OS << " { " << Overload.second << ", "
<< Overload.first->getValueAsListOfDefs("Signature").size() << ", "
@@ -644,8 +639,7 @@ void BuiltinNameEmitter::EmitBuiltinTable() {
<< (Overload.first->getValueAsBit("IsConst")) << ", "
<< (Overload.first->getValueAsBit("IsConv")) << ", "
<< FunctionExtensionIndex[ExtName] << ", "
- << EncodeVersions(MinVersion, MaxVersion) << ", "
- << (CoreMinVersion ? EncodeVersions(CoreMinVersion, 0) : 0) << " },\n";
+ << EncodeVersions(MinVersion, MaxVersion) << " },\n";
Index++;
}
}
@@ -670,8 +664,6 @@ bool BuiltinNameEmitter::CanReuseSignature(
Rec2->getValueAsDef("MinVersion")->getValueAsInt("ID") &&
Rec->getValueAsDef("MaxVersion")->getValueAsInt("ID") ==
Rec2->getValueAsDef("MaxVersion")->getValueAsInt("ID") &&
- Rec->getValueAsDef("CoreMinVersion")->getValueAsInt("ID") ==
- Rec2->getValueAsDef("CoreMinVersion")->getValueAsInt("ID") &&
Rec->getValueAsDef("Extension")->getName() ==
Rec2->getValueAsDef("Extension")->getName()) {
return true;
@@ -1131,39 +1123,19 @@ OpenCLBuiltinFileEmitterBase::emitExtensionGuard(const Record *Builtin) {
if (Extensions.empty())
return "";
- int CoreMinVersion =
- Builtin->getValueAsDef("CoreMinVersion")->getValueAsInt("ID");
-
- // If this extension was promoted to core, guard as:
- // #if defined(EXT) || __OPENCL_C_VERSION__ >= CORE_VERSION
- // Otherwise guard as:
- // #if defined(EXT0) && defined(EXT1) && ...
- if (CoreMinVersion) {
- SmallVector<StringRef, 2> ExtVec;
- Extensions.split(ExtVec, " ");
- OS << "#if (";
- bool isFirst = true;
- for (StringRef Ext : ExtVec) {
- if (!isFirst)
- OS << " && ";
- OS << "defined(" << Ext << ")";
- isFirst = false;
- }
- OS << ") || (__OPENCL_C_VERSION__ >= CL_VERSION_" << (CoreMinVersion / 100)
- << "_" << ((CoreMinVersion % 100) / 10) << ")\n";
- } else {
- OS << "#if";
- SmallVector<StringRef, 2> ExtVec;
- Extensions.split(ExtVec, " ");
- bool isFirst = true;
- for (StringRef Ext : ExtVec) {
- if (!isFirst)
- OS << " &&";
- OS << " defined(" << Ext << ")";
- isFirst = false;
+ OS << "#if";
+
+ SmallVector<StringRef, 2> ExtVec;
+ Extensions.split(ExtVec, " ");
+ bool isFirst = true;
+ for (StringRef Ext : ExtVec) {
+ if (!isFirst) {
+ OS << " &&";
}
- OS << "\n";
+ OS << " defined(" << Ext << ")";
+ isFirst = false;
}
+ OS << "\n";
return "#endif // Extension\n";
}
>From 1d476fbdf74a0426c1362de99b4be2b6a5de1ea8 Mon Sep 17 00:00:00 2001
From: Wenju He <wenju.he at intel.com>
Date: Thu, 16 Jul 2026 02:45:45 +0200
Subject: [PATCH 3/3] change to OPENCL_COREFEATURE
---
clang/docs/ReleaseNotes.md | 4 ++--
clang/include/clang/Basic/OpenCLExtensions.def | 16 ++++++++--------
clang/test/Misc/amdgcn.unsupported_core_3.1.cl | 8 ++++++++
3 files changed, 18 insertions(+), 10 deletions(-)
create mode 100644 clang/test/Misc/amdgcn.unsupported_core_3.1.cl
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 3642fb7de4f4c..ea48caec3c7f7 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -149,8 +149,8 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the
- Extensions ``cl_khr_extended_bit_ops``, ``cl_khr_integer_dot_product``,
``cl_khr_subgroup_extended_types``, ``cl_khr_subgroup_rotate``,
``cl_khr_subgroup_shuffle``, and ``cl_khr_subgroup_shuffle_relative`` are
- promoted to optional core features in OpenCL C 3.1. Their extension macros
- are defined automatically in OpenCL C 3.1 without needing ``-cl-ext=+ext``.
+ promoted to core features in OpenCL C 3.1. A target claiming OpenCL C 3.1
+ conformance without supporting one of these features is now diagnosed.
### Target Specific Changes
diff --git a/clang/include/clang/Basic/OpenCLExtensions.def b/clang/include/clang/Basic/OpenCLExtensions.def
index 84a30114f553c..f8af9b843f95f 100644
--- a/clang/include/clang/Basic/OpenCLExtensions.def
+++ b/clang/include/clang/Basic/OpenCLExtensions.def
@@ -69,23 +69,23 @@ OPENCL_EXTENSION(cl_khr_fp16, true, 100)
OPENCL_EXTENSION(cl_khr_int64_base_atomics, true, 100)
OPENCL_EXTENSION(cl_khr_int64_extended_atomics, true, 100)
OPENCL_EXTENSION(cl_khr_depth_images, true, 100)
-OPENCL_OPTIONALCOREFEATURE(cl_khr_extended_bit_ops, false, 100, OCL_C_31)
+OPENCL_COREFEATURE(cl_khr_extended_bit_ops, false, 100, OCL_C_31)
OPENCL_EXTENSION(cl_ext_float_atomics, false, 100)
OPENCL_EXTENSION(cl_khr_gl_msaa_sharing, true, 100)
-OPENCL_EXTENSION(cl_khr_integer_dot_product, false, 100)
+OPENCL_COREFEATURE(cl_khr_integer_dot_product, false, 100, OCL_C_31)
OPENCL_EXTENSION(cl_khr_kernel_clock, false, 100)
OPENCL_EXTENSION(cl_khr_mipmap_image, true, 100)
OPENCL_EXTENSION(cl_khr_mipmap_image_writes, true, 100)
OPENCL_EXTENSION(cl_khr_srgb_image_writes, true, 100)
OPENCL_EXTENSION(cl_khr_subgroup_ballot, false, 100)
OPENCL_EXTENSION(cl_khr_subgroup_clustered_reduce, false, 100)
-OPENCL_OPTIONALCOREFEATURE(cl_khr_subgroup_extended_types, false, 100, OCL_C_31)
+OPENCL_COREFEATURE(cl_khr_subgroup_extended_types, false, 100, OCL_C_31)
OPENCL_EXTENSION(cl_khr_subgroup_named_barrier, false, 100)
OPENCL_EXTENSION(cl_khr_subgroup_non_uniform_arithmetic, false, 100)
OPENCL_EXTENSION(cl_khr_subgroup_non_uniform_vote, false, 100)
-OPENCL_OPTIONALCOREFEATURE(cl_khr_subgroup_rotate, false, 100, OCL_C_31)
-OPENCL_OPTIONALCOREFEATURE(cl_khr_subgroup_shuffle_relative, false, 100, OCL_C_31)
-OPENCL_OPTIONALCOREFEATURE(cl_khr_subgroup_shuffle, false, 100, OCL_C_31)
+OPENCL_COREFEATURE(cl_khr_subgroup_rotate, false, 100, OCL_C_31)
+OPENCL_COREFEATURE(cl_khr_subgroup_shuffle_relative, false, 100, OCL_C_31)
+OPENCL_COREFEATURE(cl_khr_subgroup_shuffle, false, 100, OCL_C_31)
OPENCL_EXTENSION(cl_khr_subgroups, true, 100)
OPENCL_GENERIC_EXTENSION(cl_khr_3d_image_writes, true, 100, OCL_C_20, OCL_C_30)
@@ -117,8 +117,8 @@ OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_image_unorm_int_2_101010, false, 200,
OPENCL_OPTIONALCOREFEATURE(__opencl_c_ext_image_unsigned_10x6_12x4_14x2, false, 200, OCL_C_20)
OPENCL_GENERIC_EXTENSION(__opencl_c_generic_address_space, false, 200, OCL_C_20, OCL_C_30)
OPENCL_GENERIC_EXTENSION(__opencl_c_images, false, 200, OCL_C_20, OCL_C_30)
-OPENCL_OPTIONALCOREFEATURE(__opencl_c_integer_dot_product_input_4x8bit, false, 200, OCL_C_20 | OCL_C_31)
-OPENCL_OPTIONALCOREFEATURE(__opencl_c_integer_dot_product_input_4x8bit_packed, false, 200, OCL_C_20 | OCL_C_31)
+OPENCL_GENERIC_EXTENSION(__opencl_c_integer_dot_product_input_4x8bit, false, 200, OCL_C_31, OCL_C_20)
+OPENCL_GENERIC_EXTENSION(__opencl_c_integer_dot_product_input_4x8bit_packed, false, 200, OCL_C_31, OCL_C_20)
OPENCL_OPTIONALCOREFEATURE(__opencl_c_kernel_clock_scope_device, false, 200, OCL_C_20)
OPENCL_OPTIONALCOREFEATURE(__opencl_c_kernel_clock_scope_sub_group, false, 200, OCL_C_20)
OPENCL_OPTIONALCOREFEATURE(__opencl_c_kernel_clock_scope_work_group, false, 200, OCL_C_20)
diff --git a/clang/test/Misc/amdgcn.unsupported_core_3.1.cl b/clang/test/Misc/amdgcn.unsupported_core_3.1.cl
new file mode 100644
index 0000000000000..5a406670777ae
--- /dev/null
+++ b/clang/test/Misc/amdgcn.unsupported_core_3.1.cl
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -cl-std=CL3.1 -triple amdgcn-amd-amdhsa -Wpedantic-core-features %s 2>&1 | FileCheck %s
+
+// CHECK: cl_khr_extended_bit_ops is a core feature in OpenCL C version 3.1 but not supported on this target
+// CHECK: cl_khr_integer_dot_product is a core feature in OpenCL C version 3.1 but not supported on this target
+// CHECK: cl_khr_subgroup_extended_types is a core feature in OpenCL C version 3.1 but not supported on this target
+// CHECK: cl_khr_subgroup_rotate is a core feature in OpenCL C version 3.1 but not supported on this target
+// CHECK: cl_khr_subgroup_shuffle_relative is a core feature in OpenCL C version 3.1 but not supported on this target
+// CHECK: cl_khr_subgroup_shuffle is a core feature in OpenCL C version 3.1 but not supported on this target
More information about the cfe-commits
mailing list