diff --git a/clang/lib/Sema/OpenCLBuiltins.td b/clang/lib/Sema/OpenCLBuiltins.td --- a/clang/lib/Sema/OpenCLBuiltins.td +++ b/clang/lib/Sema/OpenCLBuiltins.td @@ -55,6 +55,7 @@ def FuncExtKhrSubgroups : FunctionExtension<"cl_khr_subgroups">; def FuncExtKhrSubgroupNonUniformVote : FunctionExtension<"cl_khr_subgroup_non_uniform_vote">; def FuncExtKhrSubgroupBallot : FunctionExtension<"cl_khr_subgroup_ballot">; +def FuncExtKhrSubgroupNonUniformArithmetic: FunctionExtension<"cl_khr_subgroup_non_uniform_arithmetic">; def FuncExtKhrSubgroupShuffle : FunctionExtension<"cl_khr_subgroup_shuffle">; def FuncExtKhrSubgroupShuffleRelative : FunctionExtension<"cl_khr_subgroup_shuffle_relative">; def FuncExtKhrGlobalInt32BaseAtomics : FunctionExtension<"cl_khr_global_int32_base_atomics">; @@ -1523,7 +1524,19 @@ } // Section 38.7.1 - cl_khr_subgroup_non_uniform_arithmetic -// TODO +let Extension = FuncExtKhrSubgroupNonUniformArithmetic in { + foreach name = ["reduce_", "scan_exclusive_", "scan_inclusive_"] in { + foreach op = ["add", "min", "max", "mul"] in { + def : Builtin<"sub_group_non_uniform_" # name # op, [AGenType1, AGenType1]>; + } + foreach op = ["and", "or", "xor"] in { + def : Builtin<"sub_group_non_uniform_" # name # op, [AIGenType1, AIGenType1]>; + } + foreach op = ["and", "or", "xor"] in { + def : Builtin<"sub_group_non_uniform_" # name # "logical_" # op, [Int, Int]>; + } + } +} // Section 38.8.1 - cl_khr_subgroup_shuffle let Extension = FuncExtKhrSubgroupShuffle in { diff --git a/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl b/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl --- a/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl +++ b/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl @@ -37,6 +37,7 @@ // Enable extensions that are enabled in opencl-c-base.h. #if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200) #define cl_khr_subgroup_ballot 1 +#define cl_khr_subgroup_non_uniform_arithmetic 1 #endif #endif @@ -140,11 +141,13 @@ #endif } -kernel void extended_subgroup(global uint4 *out) { +kernel void extended_subgroup(global uint4 *out, global int *scalar) { out[0] = get_sub_group_eq_mask(); + scalar[0] = sub_group_non_uniform_scan_inclusive_or(3); #if __OPENCL_C_VERSION__ < CL_VERSION_2_0 && !defined(__OPENCL_CPP_VERSION__) - // expected-error@-2{{implicit declaration of function 'get_sub_group_eq_mask' is invalid in OpenCL}} - // expected-error@-3{{implicit conversion changes signedness}} + // expected-error@-3{{implicit declaration of function 'get_sub_group_eq_mask' is invalid in OpenCL}} + // expected-error@-4{{implicit conversion changes signedness}} + // expected-error@-4{{implicit declaration of function 'sub_group_non_uniform_scan_inclusive_or' is invalid in OpenCL}} #endif }