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 <[email protected]> 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@-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@-10{{use of undeclared identifier 'bitfield_insert'}} +// expected-error@-10{{use of undeclared identifier 'dot_acc_sat'}} +// expected-error@-10{{use of undeclared identifier 'dot_4x8packed_uu_uint'}} +// expected-error@-10{{no matching function for call to 'sub_group_broadcast'}} +// expected-note@-11 0+{{candidate function not viable}} +// expected-error@-11{{use of undeclared identifier 'sub_group_rotate'}} +// expected-error@-11{{use of undeclared identifier 'sub_group_shuffle'}} +// expected-error@-11{{use of undeclared identifier 'sub_group_shuffle_xor'}} +// expected-error@-11{{use of undeclared identifier 'sub_group_shuffle_up'}} +// expected-error@-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 <[email protected]> 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@-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@-10{{use of undeclared identifier 'bitfield_insert'}} -// expected-error@-10{{use of undeclared identifier 'dot_acc_sat'}} -// expected-error@-10{{use of undeclared identifier 'dot_4x8packed_uu_uint'}} -// expected-error@-10{{no matching function for call to 'sub_group_broadcast'}} -// expected-note@-11 0+{{candidate function not viable}} -// expected-error@-11{{use of undeclared identifier 'sub_group_rotate'}} -// expected-error@-11{{use of undeclared identifier 'sub_group_shuffle'}} -// expected-error@-11{{use of undeclared identifier 'sub_group_shuffle_xor'}} -// expected-error@-11{{use of undeclared identifier 'sub_group_shuffle_up'}} -// expected-error@-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 <[email protected]> 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 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
