llvm-project/clang/test/SemaOpenCL/cl20-device-side-enqueue.cl
YexuanXiao 7c402b8b81
Reland [Clang] Make the SizeType, SignedSizeType and PtrdiffType be named sugar types (#149613)
The checks for the 'z' and 't' format specifiers added in the original
PR #143653 had some issues and were overly strict, causing some build
failures and were consequently reverted at
4c85bf2fe8.

In the latest commit
27c58629ec,
I relaxed the checks for the 'z' and 't' format specifiers, so warnings
are now only issued when they are used with mismatched types.

The original intent of these checks was to diagnose code that assumes
the underlying type of `size_t` is `unsigned` or `unsigned long`, for
example:

```c
printf("%zu", 1ul); // Not portable, but not an error when size_t is unsigned long
```  

However, it produced a significant number of false positives. This was
partly because Clang does not treat the `typedef` `size_t` and
`__size_t` as having a common "sugar" type, and partly because a large
amount of existing code either assumes `unsigned` (or `unsigned long`)
is `size_t`, or they define the equivalent of size_t in their own way
(such as
sanitizer_internal_defs.h).2e67dcfdcd/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h (L203)
2025-07-19 03:44:14 -03:00

253 lines
13 KiB
Common Lisp

// RUN: %clang_cc1 %s -cl-std=CL2.0 -triple "spir-unknown-unknown" -verify -pedantic -fsyntax-only -DB32 -DQUALS=
// RUN: %clang_cc1 %s -cl-std=CL2.0 -triple "spir-unknown-unknown" -verify -pedantic -fsyntax-only -DB32 -DQUALS= -cl-ext=-cl_khr_subgroups
// RUN: %clang_cc1 %s -cl-std=CL2.0 -triple "spir-unknown-unknown" -verify -pedantic -fsyntax-only -DB32 -DQUALS="const volatile"
// RUN: %clang_cc1 %s -cl-std=CL2.0 -triple "spir64-unknown-unknown" -verify -pedantic -fsyntax-only -Wconversion -DWCONV -DQUALS=
// RUN: %clang_cc1 %s -cl-std=CL2.0 -triple "spir64-unknown-unknown" -verify -pedantic -fsyntax-only -Wconversion -DWCONV -DQUALS="const volatile"
// RUN: %clang_cc1 %s -cl-std=CL3.0 -triple "spir-unknown-unknown" -verify -pedantic -fsyntax-only -DB32 -DQUALS=
// RUN: %clang_cc1 %s -cl-std=CL3.0 -triple "spir-unknown-unknown" -verify -pedantic -fsyntax-only -DB32 -DQUALS= -cl-ext=-cl_khr_subgroups,-__opencl_c_subgroups
// RUN: %clang_cc1 %s -cl-std=CL3.0 -triple "spir-unknown-unknown" -verify -pedantic -fsyntax-only -DB32 -DQUALS="const volatile"
// RUN: %clang_cc1 %s -cl-std=CL3.0 -triple "spir64-unknown-unknown" -verify -pedantic -fsyntax-only -Wconversion -DWCONV -DQUALS=
// RUN: %clang_cc1 %s -cl-std=CL3.0 -triple "spir64-unknown-unknown" -verify -pedantic -fsyntax-only -Wconversion -DWCONV -DQUALS="const volatile"
typedef struct {int a;} ndrange_t;
// Diagnostic tests for different overloads of enqueue_kernel from Table 6.13.17.1 of OpenCL 2.0 Spec.
kernel void enqueue_kernel_tests(void) {
queue_t default_queue;
unsigned flags = 0;
QUALS ndrange_t ndrange = { 0 };
clk_event_t evt;
clk_event_t event_wait_list;
clk_event_t event_wait_list2[] = {evt, evt};
void *vptr;
// Testing the first overload type
enqueue_kernel(default_queue, flags, ndrange, ^(void) {
return 0;
});
enqueue_kernel(vptr, flags, ndrange, ^(void) { // expected-error{{illegal call to 'enqueue_kernel', expected 'queue_t' argument type}}
return 0;
});
enqueue_kernel(default_queue, vptr, ndrange, ^(void) { // expected-error{{illegal call to 'enqueue_kernel', expected 'kernel_enqueue_flags_t' (i.e. uint) argument type}}
return 0;
});
enqueue_kernel(default_queue, flags, vptr, ^(void) { // expected-error{{illegal call to 'enqueue_kernel', expected 'ndrange_t' argument type}}
return 0;
});
enqueue_kernel(default_queue, flags, ndrange, vptr); // expected-error{{illegal call to 'enqueue_kernel', expected block argument}}
enqueue_kernel(default_queue, flags, ndrange, ^(int i) { // expected-error{{blocks with parameters are not accepted in this prototype of enqueue_kernel call}}
return 0;
});
// Testing the second overload type
enqueue_kernel(default_queue, flags, ndrange, 1, &event_wait_list, &evt, ^(void) {
return 0;
});
enqueue_kernel(default_queue, flags, ndrange, 1, 0, 0, ^(void) {
return 0;
});
enqueue_kernel(default_queue, flags, ndrange, vptr, &event_wait_list, &evt, ^(void) { // expected-error{{illegal call to 'enqueue_kernel', expected integer argument type}}
return 0;
});
enqueue_kernel(default_queue, flags, ndrange, 1, vptr, &evt, ^(void) // expected-error{{illegal call to 'enqueue_kernel', expected 'clk_event_t *' argument type}}
{
return 0;
});
enqueue_kernel(default_queue, flags, ndrange, 1, &event_wait_list, vptr, ^(void) // expected-error{{illegal call to 'enqueue_kernel', expected 'clk_event_t *' argument type}}
{
return 0;
});
enqueue_kernel(default_queue, flags, ndrange, 1, &event_wait_list, &evt, vptr); // expected-error{{illegal call to 'enqueue_kernel', expected block argument}}
// Testing the third overload type
enqueue_kernel(default_queue, flags, ndrange,
^(local void *a, local void *b) {
return 0;
},
1024, 1024);
enqueue_kernel(default_queue, flags, ndrange,
^(local void *a, local void *b) {
return 0;
},
1024L, 1024);
enqueue_kernel(default_queue, flags, ndrange,
^(local void *a, local void *b) {
return 0;
},
1024, 4294967296L);
#ifdef B32
// expected-warning@-2{{implicit conversion from 'long' to '__size_t' (aka 'unsigned int') changes value from 4294967296 to 0}}
#endif
char c;
enqueue_kernel(default_queue, flags, ndrange,
^(local void *a, local void *b) {
return 0;
},
c, 1024L);
#ifdef WCONV
// expected-warning-re@-2{{implicit conversion changes signedness: 'char' to '__size_t' (aka 'unsigned {{int|long}}')}}
#endif
#define UINT_MAX 4294967295
enqueue_kernel(default_queue, flags, ndrange,
^(local void *a, local void *b) {
return 0;
},
sizeof(int), sizeof(int) * UINT_MAX);
#ifdef B32
// expected-warning@-2{{implicit conversion from 'long' to '__size_t' (aka 'unsigned int') changes value from 17179869180 to 4294967292}}
#endif
typedef void (^bl_A_t)(local void *);
const bl_A_t block_A = (bl_A_t) ^ (local void *a) {};
enqueue_kernel(default_queue, flags, ndrange, block_A, 1024);
typedef void (^bl_B_t)(local void *, local int *);
const bl_B_t block_B = (bl_B_t) ^ (local void *a, local int *b) {};
enqueue_kernel(default_queue, flags, ndrange, block_B, 1024, 1024); // expected-error{{blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'}}
enqueue_kernel(default_queue, flags, ndrange, // expected-error{{mismatch in number of block parameters and local size arguments passed}}
^(local void *a, local void *b) {
return 0;
},
1024);
float illegal_mem_size = (float)0.5f;
enqueue_kernel(default_queue, flags, ndrange,
^(local void *a, local void *b) {
return 0;
},
illegal_mem_size, illegal_mem_size); // expected-error{{illegal call to enqueue_kernel, parameter needs to be specified as integer type}} expected-error{{illegal call to enqueue_kernel, parameter needs to be specified as integer type}}
enqueue_kernel(default_queue, flags, ndrange,
^(local void *a, local void *b) {
return 0;
},
illegal_mem_size, 1024); // expected-error{{illegal call to enqueue_kernel, parameter needs to be specified as integer type}}
// Testing the forth overload type
enqueue_kernel(default_queue, flags, ndrange, 1, event_wait_list2, &evt,
^(local void *a, local void *b) {
return 0;
},
1024, 1024);
enqueue_kernel(default_queue, flags, ndrange, 1, 0, 0,
^(local void *a, local void *b) {
return 0;
},
1024, 1024);
enqueue_kernel(default_queue, flags, ndrange, 1, &event_wait_list, &evt, // expected-error{{mismatch in number of block parameters and local size arguments passed}}
^(local void *a, local void *b) {
return 0;
},
1024, 1024, 1024);
// More random misc cases that can't be deduced
enqueue_kernel(default_queue, flags, ndrange, 1, &event_wait_list, &evt); // expected-error{{illegal call to enqueue_kernel, incorrect argument types}}
enqueue_kernel(default_queue, flags, ndrange, 1, 1); // expected-error{{illegal call to enqueue_kernel, incorrect argument types}}
enqueue_kernel(default_queue, ndrange, ^{}); // expected-error{{too few arguments to function call, expected at least 4, have 3}}
}
// Diagnostic tests for get_kernel_work_group_size and allowed block parameter types in dynamic parallelism.
kernel void work_group_size_tests(void) {
void (^const block_A)(void) = ^{
return;
};
void (^const block_B)(int) = ^(int a) {
return;
};
void (^const block_C)(local void *) = ^(local void *a) {
return;
};
void (^const block_D)(local int *) = ^(local int *a) {
return;
};
unsigned size = get_kernel_work_group_size(block_A);
size = get_kernel_work_group_size(block_C);
size = get_kernel_work_group_size(^(local void *a) {
return;
});
size = get_kernel_work_group_size(^(local int *a) { // expected-error {{blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'}}
return;
});
size = get_kernel_work_group_size(block_B); // expected-error {{blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'}}
size = get_kernel_work_group_size(block_D); // expected-error {{blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'}}
size = get_kernel_work_group_size(^(int a) { // expected-error {{blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'}}
return;
});
size = get_kernel_work_group_size(); // expected-error {{too few arguments to function call, expected 1, have 0}}
size = get_kernel_work_group_size(1); // expected-error{{expected block argument}}
size = get_kernel_work_group_size(block_A, 1); // expected-error{{too many arguments to function call, expected 1, have 2}}
size = get_kernel_preferred_work_group_size_multiple(block_A);
size = get_kernel_preferred_work_group_size_multiple(block_C);
size = get_kernel_preferred_work_group_size_multiple(^(local void *a) {
return;
});
size = get_kernel_preferred_work_group_size_multiple(^(local int *a) { // expected-error {{blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'}}
return;
});
size = get_kernel_preferred_work_group_size_multiple(^(int a) { // expected-error {{blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'}}
return;
});
size = get_kernel_preferred_work_group_size_multiple(block_B); // expected-error {{blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'}}
size = get_kernel_preferred_work_group_size_multiple(block_D); // expected-error {{blocks used in enqueue_kernel call are expected to have parameters of type 'local void*'}}
size = get_kernel_preferred_work_group_size_multiple(); // expected-error {{too few arguments to function call, expected 1, have 0}}
size = get_kernel_preferred_work_group_size_multiple(1); // expected-error{{expected block argument}}
size = get_kernel_preferred_work_group_size_multiple(block_A, 1); // expected-error{{too many arguments to function call, expected 1, have 2}}
}
#ifdef cl_khr_subgroups
#pragma OPENCL EXTENSION cl_khr_subgroups : enable
kernel void foo(global unsigned int *buf)
{
ndrange_t n;
buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, ^(){});
buf[0] = get_kernel_max_sub_group_size_for_ndrange(0, ^(){}); // expected-error{{illegal call to 'get_kernel_max_sub_group_size_for_ndrange', expected 'ndrange_t' argument type}}
buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, 1); // expected-error{{illegal call to 'get_kernel_max_sub_group_size_for_ndrange', expected block argument type}}
}
kernel void bar(global unsigned int *buf)
{
__private ndrange_t n;
buf[0] = get_kernel_sub_group_count_for_ndrange(n, ^(){});
buf[0] = get_kernel_sub_group_count_for_ndrange(0, ^(){}); // expected-error{{illegal call to 'get_kernel_sub_group_count_for_ndrange', expected 'ndrange_t' argument type}}
buf[0] = get_kernel_sub_group_count_for_ndrange(n, 1); // expected-error{{illegal call to 'get_kernel_sub_group_count_for_ndrange', expected block argument type}}
}
#pragma OPENCL EXTENSION cl_khr_subgroups : disable
#else
kernel void foo1(global unsigned int *buf)
{
ndrange_t n;
buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, ^(){}); // expected-error {{use of declaration 'get_kernel_max_sub_group_size_for_ndrange' requires cl_khr_subgroups or __opencl_c_subgroups support}}
}
kernel void bar1(global unsigned int *buf)
{
ndrange_t n;
buf[0] = get_kernel_sub_group_count_for_ndrange(n, ^(){}); // expected-error {{use of declaration 'get_kernel_sub_group_count_for_ndrange' requires cl_khr_subgroups or __opencl_c_subgroups support}}
}
#endif // ifdef cl_khr_subgroups