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