blob: 540520d4e325164ea02ddb692c9d4ae18f64e1da [file] [log] [blame]
Yaxun Liu99d56d22017-08-15 16:30:31 +00001// 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 Liu39195062017-08-04 18:16:31 +00003
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 Liu99d56d22017-08-15 16:30:31 +00009typedef __INTPTR_TYPE__ intptr_t;
10typedef int int8 __attribute__((ext_vector_type(8)));
11
12typedef 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
20typedef 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 Liu39195062017-08-04 18:16:31 +000030struct S { char c[3]; };
31
32char i8;
33short i16;
34int i32;
35int8 i64;
36
37atomic_int gn;
Yaxun Liu39195062017-08-04 18:16:31 +000038void 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 Bastienb4b1f592018-08-02 17:35:46 +000061 __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 Liu39195062017-08-04 18:16:31 +000063
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 Bastienb4b1f592018-08-02 17:35:46 +000098 __opencl_atomic_load(ci, memory_order_acquire, memory_scope_work_group);
Yaxun Liu39195062017-08-04 18:16:31 +000099
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
104void memory_checks(atomic_int *Ap, int *p, int val) {
Yaxun Liu30d652a2017-08-15 16:02:49 +0000105 // 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 Liu39195062017-08-04 18:16:31 +0000112 (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
176void 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 Liu30d652a2017-08-15 16:02:49 +0000182 (void)__opencl_atomic_load(Ap, memory_order_relaxed, scope);
Yaxun Liu39195062017-08-04 18:16:31 +0000183 (void)__opencl_atomic_load(Ap, memory_order_relaxed, 10); //expected-error{{synchronization scope argument to atomic operation is invalid}}
Yaxun Liu30d652a2017-08-15 16:02:49 +0000184
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 Liu39195062017-08-04 18:16:31 +0000191}
192
193void nullPointerWarning(atomic_int *Ap, int *p, int val) {
194 // The 'expected' pointer shouldn't be NULL.
Yaxun Liu99d56d22017-08-15 16:30:31 +0000195 (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 Liu39195062017-08-04 18:16:31 +0000196}