Yaxun Liu | 99d56d2 | 2017-08-15 16:30:31 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -fsyntax-only -triple=spir64 |
| 2 | // RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -fsyntax-only -triple=amdgcn-amdhsa-amd-opencl |
Yaxun Liu | 3919506 | 2017-08-04 18:16:31 +0000 | [diff] [blame] | 3 | |
| 4 | // Basic parsing/Sema tests for __opencl_atomic_* |
| 5 | |
| 6 | #pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable |
| 7 | #pragma OPENCL EXTENSION cl_khr_int64_extended_atomics : enable |
| 8 | |
Yaxun Liu | 99d56d2 | 2017-08-15 16:30:31 +0000 | [diff] [blame] | 9 | typedef __INTPTR_TYPE__ intptr_t; |
| 10 | typedef int int8 __attribute__((ext_vector_type(8))); |
| 11 | |
| 12 | typedef enum memory_order { |
| 13 | memory_order_relaxed = __ATOMIC_RELAXED, |
| 14 | memory_order_acquire = __ATOMIC_ACQUIRE, |
| 15 | memory_order_release = __ATOMIC_RELEASE, |
| 16 | memory_order_acq_rel = __ATOMIC_ACQ_REL, |
| 17 | memory_order_seq_cst = __ATOMIC_SEQ_CST |
| 18 | } memory_order; |
| 19 | |
| 20 | typedef enum memory_scope { |
| 21 | memory_scope_work_item = __OPENCL_MEMORY_SCOPE_WORK_ITEM, |
| 22 | memory_scope_work_group = __OPENCL_MEMORY_SCOPE_WORK_GROUP, |
| 23 | memory_scope_device = __OPENCL_MEMORY_SCOPE_DEVICE, |
| 24 | memory_scope_all_svm_devices = __OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES, |
| 25 | #if defined(cl_intel_subgroups) || defined(cl_khr_subgroups) |
| 26 | memory_scope_sub_group = __OPENCL_MEMORY_SCOPE_SUB_GROUP |
| 27 | #endif |
| 28 | } memory_scope; |
| 29 | |
Yaxun Liu | 3919506 | 2017-08-04 18:16:31 +0000 | [diff] [blame] | 30 | struct S { char c[3]; }; |
| 31 | |
| 32 | char i8; |
| 33 | short i16; |
| 34 | int i32; |
| 35 | int8 i64; |
| 36 | |
| 37 | atomic_int gn; |
Yaxun Liu | 3919506 | 2017-08-04 18:16:31 +0000 | [diff] [blame] | 38 | void f(atomic_int *i, const atomic_int *ci, |
| 39 | atomic_intptr_t *p, atomic_float *d, |
| 40 | int *I, const int *CI, |
| 41 | intptr_t *P, float *D, struct S *s1, struct S *s2, |
| 42 | global atomic_int *i_g, local atomic_int *i_l, private atomic_int *i_p, |
| 43 | constant atomic_int *i_c) { |
| 44 | __opencl_atomic_init(I, 5); // expected-error {{address argument to atomic operation must be a pointer to _Atomic type ('__generic int *' invalid)}} |
| 45 | __opencl_atomic_init(ci, 5); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}} |
| 46 | |
| 47 | __opencl_atomic_load(0); // expected-error {{too few arguments to function call, expected 3, have 1}} |
| 48 | __opencl_atomic_load(0, 0, 0, 0); // expected-error {{too many arguments to function call, expected 3, have 4}} |
| 49 | __opencl_atomic_store(0,0,0,0); // expected-error {{address argument to atomic builtin must be a pointer}} |
| 50 | __opencl_atomic_store((int *)0, 0, 0, 0); // expected-error {{address argument to atomic operation must be a pointer to _Atomic type ('__generic int *' invalid)}} |
| 51 | __opencl_atomic_store(i, 0, memory_order_relaxed, memory_scope_work_group); |
| 52 | __opencl_atomic_store(ci, 0, memory_order_relaxed, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}} |
| 53 | __opencl_atomic_store(i_g, 0, memory_order_relaxed, memory_scope_work_group); |
| 54 | __opencl_atomic_store(i_l, 0, memory_order_relaxed, memory_scope_work_group); |
| 55 | __opencl_atomic_store(i_p, 0, memory_order_relaxed, memory_scope_work_group); |
| 56 | __opencl_atomic_store(i_c, 0, memory_order_relaxed, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-constant _Atomic type ('__constant atomic_int *' (aka '__constant _Atomic(int) *') invalid)}} |
| 57 | |
| 58 | __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_work_group); |
| 59 | __opencl_atomic_load(p, memory_order_seq_cst, memory_scope_work_group); |
| 60 | __opencl_atomic_load(d, memory_order_seq_cst, memory_scope_work_group); |
JF Bastien | b4b1f59 | 2018-08-02 17:35:46 +0000 | [diff] [blame] | 61 | __opencl_atomic_load(ci, memory_order_seq_cst, memory_scope_work_group); |
| 62 | __opencl_atomic_load(i_c, memory_order_seq_cst, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-constant _Atomic type ('__constant atomic_int *' (aka '__constant _Atomic(int) *') invalid)}} |
Yaxun Liu | 3919506 | 2017-08-04 18:16:31 +0000 | [diff] [blame] | 63 | |
| 64 | __opencl_atomic_store(i, 1, memory_order_seq_cst, memory_scope_work_group); |
| 65 | __opencl_atomic_store(p, 1, memory_order_seq_cst, memory_scope_work_group); |
| 66 | (int)__opencl_atomic_store(d, 1, memory_order_seq_cst, memory_scope_work_group); // expected-error {{operand of type 'void' where arithmetic or pointer type is required}} |
| 67 | |
| 68 | int exchange_1 = __opencl_atomic_exchange(i, 1, memory_order_seq_cst, memory_scope_work_group); |
| 69 | int exchange_2 = __opencl_atomic_exchange(I, 1, memory_order_seq_cst, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to _Atomic}} |
| 70 | |
| 71 | __opencl_atomic_fetch_add(i, 1, memory_order_seq_cst, memory_scope_work_group); |
| 72 | __opencl_atomic_fetch_add(p, 1, memory_order_seq_cst, memory_scope_work_group); |
| 73 | __opencl_atomic_fetch_add(d, 1, memory_order_seq_cst, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to atomic integer or pointer ('__generic atomic_float *' (aka '__generic _Atomic(float) *') invalid)}} |
| 74 | __opencl_atomic_fetch_and(i, 1, memory_order_seq_cst, memory_scope_work_group); |
| 75 | __opencl_atomic_fetch_and(p, 1, memory_order_seq_cst, memory_scope_work_group); |
| 76 | __opencl_atomic_fetch_and(d, 1, memory_order_seq_cst, memory_scope_work_group); // expected-error {{address argument to bitwise atomic operation must be a pointer to atomic integer ('__generic atomic_float *' (aka '__generic _Atomic(float) *') invalid)}} |
| 77 | |
| 78 | __opencl_atomic_fetch_min(i, 1, memory_order_seq_cst, memory_scope_work_group); |
| 79 | __opencl_atomic_fetch_max(i, 1, memory_order_seq_cst, memory_scope_work_group); |
| 80 | __opencl_atomic_fetch_min(d, 1, memory_order_seq_cst, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to atomic integer or pointer ('__generic atomic_float *' (aka '__generic _Atomic(float) *') invalid)}} |
| 81 | __opencl_atomic_fetch_max(d, 1, memory_order_seq_cst, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to atomic integer or pointer ('__generic atomic_float *' (aka '__generic _Atomic(float) *') invalid)}} |
| 82 | |
| 83 | bool cmpexch_1 = __opencl_atomic_compare_exchange_strong(i, I, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_group); |
| 84 | bool cmpexch_2 = __opencl_atomic_compare_exchange_strong(p, P, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_group); |
| 85 | bool cmpexch_3 = __opencl_atomic_compare_exchange_strong(d, I, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_group); // expected-warning {{incompatible pointer types passing '__generic int *' to parameter of type '__generic float *'}} |
| 86 | (void)__opencl_atomic_compare_exchange_strong(i, CI, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_group); // expected-warning {{passing 'const __generic int *' to parameter of type '__generic int *' discards qualifiers}} |
| 87 | |
| 88 | bool cmpexchw_1 = __opencl_atomic_compare_exchange_weak(i, I, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_group); |
| 89 | bool cmpexchw_2 = __opencl_atomic_compare_exchange_weak(p, P, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_group); |
| 90 | bool cmpexchw_3 = __opencl_atomic_compare_exchange_weak(d, I, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_group); // expected-warning {{incompatible pointer types passing '__generic int *' to parameter of type '__generic float *'}} |
| 91 | (void)__opencl_atomic_compare_exchange_weak(i, CI, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_group); // expected-warning {{passing 'const __generic int *' to parameter of type '__generic int *' discards qualifiers}} |
| 92 | |
| 93 | // Pointers to different address spaces are allowed. |
| 94 | bool cmpexch_10 = __opencl_atomic_compare_exchange_strong((global atomic_int *)0x308, (constant int *)0x309, 1, memory_order_seq_cst, memory_order_seq_cst, memory_scope_work_group); |
| 95 | |
| 96 | __opencl_atomic_init(ci, 0); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}} |
| 97 | __opencl_atomic_store(ci, 0, memory_order_release, memory_scope_work_group); // expected-error {{address argument to atomic operation must be a pointer to non-const _Atomic type ('const __generic atomic_int *' (aka 'const __generic _Atomic(int) *') invalid)}} |
JF Bastien | b4b1f59 | 2018-08-02 17:35:46 +0000 | [diff] [blame] | 98 | __opencl_atomic_load(ci, memory_order_acquire, memory_scope_work_group); |
Yaxun Liu | 3919506 | 2017-08-04 18:16:31 +0000 | [diff] [blame] | 99 | |
| 100 | __opencl_atomic_init(&gn, 456); |
| 101 | __opencl_atomic_init(&gn, (void*)0); // expected-warning{{incompatible pointer to integer conversion passing '__generic void *' to parameter of type 'int'}} |
| 102 | } |
| 103 | |
| 104 | void memory_checks(atomic_int *Ap, int *p, int val) { |
Yaxun Liu | 30d652a | 2017-08-15 16:02:49 +0000 | [diff] [blame] | 105 | // non-integer memory order argument is casted to integer type. |
| 106 | (void)__opencl_atomic_load(Ap, 1.0f, memory_scope_work_group); |
| 107 | float forder; |
| 108 | (void)__opencl_atomic_load(Ap, forder, memory_scope_work_group); |
| 109 | struct S s; |
| 110 | (void)__opencl_atomic_load(Ap, s, memory_scope_work_group); // expected-error {{passing 'struct S' to parameter of incompatible type 'int'}} |
| 111 | |
Yaxun Liu | 3919506 | 2017-08-04 18:16:31 +0000 | [diff] [blame] | 112 | (void)__opencl_atomic_load(Ap, memory_order_relaxed, memory_scope_work_group); |
| 113 | (void)__opencl_atomic_load(Ap, memory_order_acquire, memory_scope_work_group); |
| 114 | (void)__opencl_atomic_load(Ap, memory_order_consume, memory_scope_work_group); // expected-error {{use of undeclared identifier 'memory_order_consume'}} |
| 115 | (void)__opencl_atomic_load(Ap, memory_order_release, memory_scope_work_group); // expected-warning {{memory order argument to atomic operation is invalid}} |
| 116 | (void)__opencl_atomic_load(Ap, memory_order_acq_rel, memory_scope_work_group); // expected-warning {{memory order argument to atomic operation is invalid}} |
| 117 | (void)__opencl_atomic_load(Ap, memory_order_seq_cst, memory_scope_work_group); |
| 118 | |
| 119 | (void)__opencl_atomic_store(Ap, val, memory_order_relaxed, memory_scope_work_group); |
| 120 | (void)__opencl_atomic_store(Ap, val, memory_order_acquire, memory_scope_work_group); // expected-warning {{memory order argument to atomic operation is invalid}} |
| 121 | (void)__opencl_atomic_store(Ap, val, memory_order_release, memory_scope_work_group); |
| 122 | (void)__opencl_atomic_store(Ap, val, memory_order_acq_rel, memory_scope_work_group); // expected-warning {{memory order argument to atomic operation is invalid}} |
| 123 | (void)__opencl_atomic_store(Ap, val, memory_order_seq_cst, memory_scope_work_group); |
| 124 | |
| 125 | (void)__opencl_atomic_fetch_add(Ap, 1, memory_order_relaxed, memory_scope_work_group); |
| 126 | (void)__opencl_atomic_fetch_add(Ap, 1, memory_order_acquire, memory_scope_work_group); |
| 127 | (void)__opencl_atomic_fetch_add(Ap, 1, memory_order_release, memory_scope_work_group); |
| 128 | (void)__opencl_atomic_fetch_add(Ap, 1, memory_order_acq_rel, memory_scope_work_group); |
| 129 | (void)__opencl_atomic_fetch_add(Ap, 1, memory_order_seq_cst, memory_scope_work_group); |
| 130 | |
| 131 | (void)__opencl_atomic_init(Ap, val); |
| 132 | |
| 133 | (void)__opencl_atomic_fetch_sub(Ap, val, memory_order_relaxed, memory_scope_work_group); |
| 134 | (void)__opencl_atomic_fetch_sub(Ap, val, memory_order_acquire, memory_scope_work_group); |
| 135 | (void)__opencl_atomic_fetch_sub(Ap, val, memory_order_release, memory_scope_work_group); |
| 136 | (void)__opencl_atomic_fetch_sub(Ap, val, memory_order_acq_rel, memory_scope_work_group); |
| 137 | (void)__opencl_atomic_fetch_sub(Ap, val, memory_order_seq_cst, memory_scope_work_group); |
| 138 | |
| 139 | (void)__opencl_atomic_fetch_and(Ap, val, memory_order_relaxed, memory_scope_work_group); |
| 140 | (void)__opencl_atomic_fetch_and(Ap, val, memory_order_acquire, memory_scope_work_group); |
| 141 | (void)__opencl_atomic_fetch_and(Ap, val, memory_order_release, memory_scope_work_group); |
| 142 | (void)__opencl_atomic_fetch_and(Ap, val, memory_order_acq_rel, memory_scope_work_group); |
| 143 | (void)__opencl_atomic_fetch_and(Ap, val, memory_order_seq_cst, memory_scope_work_group); |
| 144 | |
| 145 | (void)__opencl_atomic_fetch_or(Ap, val, memory_order_relaxed, memory_scope_work_group); |
| 146 | (void)__opencl_atomic_fetch_or(Ap, val, memory_order_acquire, memory_scope_work_group); |
| 147 | (void)__opencl_atomic_fetch_or(Ap, val, memory_order_release, memory_scope_work_group); |
| 148 | (void)__opencl_atomic_fetch_or(Ap, val, memory_order_acq_rel, memory_scope_work_group); |
| 149 | (void)__opencl_atomic_fetch_or(Ap, val, memory_order_seq_cst, memory_scope_work_group); |
| 150 | |
| 151 | (void)__opencl_atomic_fetch_xor(Ap, val, memory_order_relaxed, memory_scope_work_group); |
| 152 | (void)__opencl_atomic_fetch_xor(Ap, val, memory_order_acquire, memory_scope_work_group); |
| 153 | (void)__opencl_atomic_fetch_xor(Ap, val, memory_order_release, memory_scope_work_group); |
| 154 | (void)__opencl_atomic_fetch_xor(Ap, val, memory_order_acq_rel, memory_scope_work_group); |
| 155 | (void)__opencl_atomic_fetch_xor(Ap, val, memory_order_seq_cst, memory_scope_work_group); |
| 156 | |
| 157 | (void)__opencl_atomic_exchange(Ap, val, memory_order_relaxed, memory_scope_work_group); |
| 158 | (void)__opencl_atomic_exchange(Ap, val, memory_order_acquire, memory_scope_work_group); |
| 159 | (void)__opencl_atomic_exchange(Ap, val, memory_order_release, memory_scope_work_group); |
| 160 | (void)__opencl_atomic_exchange(Ap, val, memory_order_acq_rel, memory_scope_work_group); |
| 161 | (void)__opencl_atomic_exchange(Ap, val, memory_order_seq_cst, memory_scope_work_group); |
| 162 | |
| 163 | (void)__opencl_atomic_compare_exchange_strong(Ap, p, val, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group); |
| 164 | (void)__opencl_atomic_compare_exchange_strong(Ap, p, val, memory_order_acquire, memory_order_relaxed, memory_scope_work_group); |
| 165 | (void)__opencl_atomic_compare_exchange_strong(Ap, p, val, memory_order_release, memory_order_relaxed, memory_scope_work_group); |
| 166 | (void)__opencl_atomic_compare_exchange_strong(Ap, p, val, memory_order_acq_rel, memory_order_relaxed, memory_scope_work_group); |
| 167 | (void)__opencl_atomic_compare_exchange_strong(Ap, p, val, memory_order_seq_cst, memory_order_relaxed, memory_scope_work_group); |
| 168 | |
| 169 | (void)__opencl_atomic_compare_exchange_weak(Ap, p, val, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group); |
| 170 | (void)__opencl_atomic_compare_exchange_weak(Ap, p, val, memory_order_acquire, memory_order_relaxed, memory_scope_work_group); |
| 171 | (void)__opencl_atomic_compare_exchange_weak(Ap, p, val, memory_order_release, memory_order_relaxed, memory_scope_work_group); |
| 172 | (void)__opencl_atomic_compare_exchange_weak(Ap, p, val, memory_order_acq_rel, memory_order_relaxed, memory_scope_work_group); |
| 173 | (void)__opencl_atomic_compare_exchange_weak(Ap, p, val, memory_order_seq_cst, memory_order_relaxed, memory_scope_work_group); |
| 174 | } |
| 175 | |
| 176 | void synchscope_checks(atomic_int *Ap, int scope) { |
| 177 | (void)__opencl_atomic_load(Ap, memory_order_relaxed, memory_scope_work_item); // expected-error{{synchronization scope argument to atomic operation is invalid}} |
| 178 | (void)__opencl_atomic_load(Ap, memory_order_relaxed, memory_scope_work_group); |
| 179 | (void)__opencl_atomic_load(Ap, memory_order_relaxed, memory_scope_device); |
| 180 | (void)__opencl_atomic_load(Ap, memory_order_relaxed, memory_scope_all_svm_devices); |
| 181 | (void)__opencl_atomic_load(Ap, memory_order_relaxed, memory_scope_sub_group); |
Yaxun Liu | 30d652a | 2017-08-15 16:02:49 +0000 | [diff] [blame] | 182 | (void)__opencl_atomic_load(Ap, memory_order_relaxed, scope); |
Yaxun Liu | 3919506 | 2017-08-04 18:16:31 +0000 | [diff] [blame] | 183 | (void)__opencl_atomic_load(Ap, memory_order_relaxed, 10); //expected-error{{synchronization scope argument to atomic operation is invalid}} |
Yaxun Liu | 30d652a | 2017-08-15 16:02:49 +0000 | [diff] [blame] | 184 | |
| 185 | // non-integer memory scope is casted to integer type. |
| 186 | float fscope; |
| 187 | (void)__opencl_atomic_load(Ap, memory_order_relaxed, 1.0f); |
| 188 | (void)__opencl_atomic_load(Ap, memory_order_relaxed, fscope); |
| 189 | struct S s; |
| 190 | (void)__opencl_atomic_load(Ap, memory_order_relaxed, s); //expected-error{{passing 'struct S' to parameter of incompatible type 'int'}} |
Yaxun Liu | 3919506 | 2017-08-04 18:16:31 +0000 | [diff] [blame] | 191 | } |
| 192 | |
| 193 | void nullPointerWarning(atomic_int *Ap, int *p, int val) { |
| 194 | // The 'expected' pointer shouldn't be NULL. |
Yaxun Liu | 99d56d2 | 2017-08-15 16:30:31 +0000 | [diff] [blame] | 195 | (void)__opencl_atomic_compare_exchange_strong(Ap, (void *)0, val, memory_order_relaxed, memory_order_relaxed, memory_scope_work_group); // expected-warning {{null passed to a callee that requires a non-null argument}} |
Yaxun Liu | 3919506 | 2017-08-04 18:16:31 +0000 | [diff] [blame] | 196 | } |