1 /* Verify OpenACC 'firstprivate' mappings. */
2
3 /* This file is also sourced from
4 '../../../../libgomp/testsuite/libgomp.oacc-c-c++-common/firstprivate-mappings-1.c'
5 as an execution test.
6
7 'long double' tests are compiled/used unless DO_LONG_DOUBLE is set to 0. */
8
9 /* See also '../../g++.dg/goacc/firstprivate-mappings-1.C'. */
10
11 /* { dg-additional-options "-fdump-tree-omplower" } */
12
13 /* { dg-additional-options "-fext-numeric-literals" { target c++ } } */
14
15 /* { dg-additional-options "-Wno-psabi" } as apparently we're doing funny
16 things with vector arguments. */
17
18 #include <stdbool.h>
19 #include <stdint.h>
20 #include <string.h>
21
22
23 #ifdef __SIZEOF_INT128__
24 # define HAVE_INT128 1
25 #else
26 # define HAVE_INT128 0
27 #endif
28
29 #ifndef DO_LONG_DOUBLE
30 # define DO_LONG_DOUBLE 1
31 #endif
32
33
34 /* Simplify scanning for function names in tree dumps. */
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38
39
40 /* Inside the following OpenACC 'parallel' constructs' regions, we modify the
41 'firstprivate' variables, so that we can check that we don't copy these
42 back. */
43
44
45 static void
p(short * spi)46 p (short *spi)
47 {
48 short *spo;
49 #pragma acc parallel \
50 copyout (spo) \
51 firstprivate (spi)
52 {
53 spo = ++spi;
54 }
55 if (spo != spi + 1)
56 __builtin_abort ();
57 }
58
59
60 static void
b(bool bi)61 b (bool bi)
62 {
63 bool bo;
64 #pragma acc parallel \
65 copyout (bo) \
66 firstprivate (bi)
67 {
68 bo = (bi = !bi);
69 }
70 if (bo != !bi)
71 __builtin_abort ();
72 }
73
74
75 static void
i(int8_t i8i,uint8_t u8i,int16_t i16i,uint16_t u16i,int32_t i32i,uint32_t u32i,int64_t i64i,uint64_t u64i)76 i (int8_t i8i,
77 uint8_t u8i,
78 int16_t i16i,
79 uint16_t u16i,
80 int32_t i32i,
81 uint32_t u32i,
82 int64_t i64i,
83 uint64_t u64i)
84 {
85 int8_t i8o;
86 uint8_t u8o;
87 int16_t i16o;
88 uint16_t u16o;
89 int32_t i32o;
90 uint32_t u32o;
91 int64_t i64o;
92 uint64_t u64o;
93 #pragma acc parallel \
94 copyout (i8o) \
95 firstprivate (i8i) \
96 copyout (u8o) \
97 firstprivate (u8i) \
98 copyout (i16o) \
99 firstprivate (i16i) \
100 copyout (u16o) \
101 firstprivate (u16i) \
102 copyout (i32o) \
103 firstprivate (i32i) \
104 copyout (u32o) \
105 firstprivate (u32i) \
106 copyout (i64o) \
107 firstprivate (i64i) \
108 copyout (u64o) \
109 firstprivate (u64i)
110 {
111 i8o = --i8i;
112 u8o = ++u8i;
113 i16o = --i16i;
114 u16o = ++u16i;
115 i32o = --i32i;
116 u32o = ++u32i;
117 i64o = --i64i;
118 u64o = ++u64i;
119 }
120 if (i8o != i8i - 1)
121 __builtin_abort ();
122 if (u8o != u8i + 1)
123 __builtin_abort ();
124 if (i16o != i16i - 1)
125 __builtin_abort ();
126 if (u16o != u16i + 1)
127 __builtin_abort ();
128 if (i32o != i32i - 1)
129 __builtin_abort ();
130 if (u32o != u32i + 1)
131 __builtin_abort ();
132 if (i64o != i64i - 1)
133 __builtin_abort ();
134 if (u64o != u64i + 1)
135 __builtin_abort ();
136 }
137
138
139 #if HAVE_INT128
140 static void
i128(__int128 i128i,unsigned __int128 u128i)141 i128 (__int128 i128i, unsigned __int128 u128i)
142 {
143 __int128 i128o;
144 unsigned __int128 u128o;
145 # pragma acc parallel \
146 copyout (i128o) \
147 firstprivate (i128i) \
148 copyout(u128o) \
149 firstprivate (u128i)
150 {
151 i128o = --i128i;
152 u128o = ++u128i;
153 }
154 if (i128o != i128i - 1)
155 __builtin_abort ();
156 if (u128o != u128i + 1)
157 __builtin_abort ();
158 }
159 #endif
160
161
162 static void
flt_dbl(float flti,double dbli)163 flt_dbl (float flti, double dbli)
164 {
165 float flto;
166 double dblo;
167 #pragma acc parallel \
168 copyout (flto) \
169 firstprivate (flti) \
170 copyout (dblo) \
171 firstprivate (dbli)
172 {
173 flto = --flti;
174 dblo = --dbli;
175 }
176 if (flto != flti - 1)
177 __builtin_abort ();
178 if (dblo != dbli - 1)
179 __builtin_abort ();
180 }
181
182
183 static void
ldbl(long double ldbli)184 ldbl (long double ldbli)
185 {
186 #if DO_LONG_DOUBLE
187 long double ldblo;
188 # pragma acc parallel \
189 copyout (ldblo) \
190 firstprivate (ldbli)
191 {
192 ldblo = --ldbli;
193 }
194 if (ldblo != ldbli - 1)
195 __builtin_abort ();
196 #endif
197 }
198
199
200 static void
c(_Complex unsigned char cuci,_Complex signed short cssi,_Complex unsigned int cuii,_Complex signed long csli,_Complex float cflti,_Complex double cdbli)201 c (_Complex unsigned char cuci,
202 _Complex signed short cssi,
203 _Complex unsigned int cuii,
204 _Complex signed long csli,
205 _Complex float cflti,
206 _Complex double cdbli)
207 {
208 _Complex unsigned char cuco;
209 _Complex signed short csso;
210 _Complex unsigned int cuio;
211 _Complex signed long cslo;
212 _Complex float cflto;
213 _Complex double cdblo;
214 #pragma acc parallel \
215 copyout (cuco) \
216 firstprivate (cuci) \
217 copyout (csso) \
218 firstprivate (cssi) \
219 copyout (cuio) \
220 firstprivate (cuii) \
221 copyout (cslo) \
222 firstprivate (csli) \
223 copyout (cflto) \
224 firstprivate (cflti) \
225 copyout (cdblo) \
226 firstprivate (cdbli)
227 {
228 cuco = (cuci += (1 + 1j));
229 csso = (cssi -= (1 + 1j));
230 cuio = (cuii += (1 + 1j));
231 cslo = (csli -= (1 + 1j));
232 cflto = (cflti -= (1 + 1j));
233 cdblo = (cdbli -= (1 + 1j));
234 }
235 if (cuco != cuci + (1 + 1j))
236 __builtin_abort ();
237 if (csso != cssi - (1 + 1j))
238 __builtin_abort ();
239 if (cuio != cuii + (1 + 1j))
240 __builtin_abort ();
241 if (cslo != csli - (1 + 1j))
242 __builtin_abort ();
243 if (cflto != cflti - (1 + 1j))
244 __builtin_abort ();
245 if (cdblo != cdbli - (1 + 1j))
246 __builtin_abort ();
247 }
248
249
250 static void
cldbl(_Complex long double cldbli)251 cldbl (_Complex long double cldbli)
252 {
253 #if DO_LONG_DOUBLE
254 _Complex long double cldblo;
255 # pragma acc parallel \
256 copyout (cldblo) \
257 firstprivate (cldbli)
258 {
259 cldblo = (cldbli -= (1 + 1j));
260 }
261 if (cldblo != cldbli - (1 + 1j))
262 __builtin_abort ();
263 #endif
264 }
265
266
267 #define V_EQ(v1, v2) \
268 ({ \
269 __typeof__ (v1) v_d = (v1) != (v2); \
270 __typeof__ (v_d) v_0 = { 0 }; \
271 memcmp (&v_d, &v_0, sizeof v_d) == 0; \
272 })
273
274 typedef uint8_t __attribute__ ((vector_size (2 * sizeof (uint8_t)))) v2u8;
275 typedef int16_t __attribute__ ((vector_size (4 * sizeof (int16_t)))) v4i16;
276 typedef uint32_t __attribute__ ((vector_size (8 * sizeof (uint32_t)))) v8u32;
277 typedef int64_t __attribute__ ((vector_size (16 * sizeof (int64_t)))) v16i64;
278 typedef float __attribute__ ((vector_size (1 * sizeof (float)))) v1flt;
279 typedef float __attribute__ ((vector_size (2 * sizeof (float)))) v2flt;
280 typedef float __attribute__ ((vector_size (4 * sizeof (float)))) v4flt;
281 typedef float __attribute__ ((vector_size (8 * sizeof (float)))) v8flt;
282 typedef double __attribute__ ((vector_size (1 * sizeof (double)))) v1dbl;
283 typedef double __attribute__ ((vector_size (2 * sizeof (double)))) v2dbl;
284 typedef double __attribute__ ((vector_size (4 * sizeof (double)))) v4dbl;
285 typedef double __attribute__ ((vector_size (8 * sizeof (double)))) v8dbl;
286
287 static void
v(v2u8 v2u8i,v4i16 v4i16i,v8u32 v8u32i,v16i64 v16i64i,v1flt v1flti,v2flt v2flti,v4flt v4flti,v8flt v8flti,v1dbl v1dbli,v2dbl v2dbli,v4dbl v4dbli,v8dbl v8dbli)288 v (v2u8 v2u8i, v4i16 v4i16i, v8u32 v8u32i, v16i64 v16i64i,
289 v1flt v1flti, v2flt v2flti, v4flt v4flti, v8flt v8flti,
290 v1dbl v1dbli, v2dbl v2dbli, v4dbl v4dbli, v8dbl v8dbli)
291 {
292 v2u8 v2u8o;
293 v4i16 v4i16o;
294 v8u32 v8u32o;
295 v16i64 v16i64o;
296 v1flt v1flto;
297 v2flt v2flto;
298 v4flt v4flto;
299 v8flt v8flto;
300 v1dbl v1dblo;
301 v2dbl v2dblo;
302 v4dbl v4dblo;
303 v8dbl v8dblo;
304 #pragma acc parallel \
305 copyout (v2u8o) \
306 firstprivate (v2u8i) \
307 copyout (v4i16o) \
308 firstprivate (v4i16i) \
309 copyout (v8u32o) \
310 firstprivate (v8u32i) \
311 copyout (v16i64o) \
312 firstprivate (v16i64i) \
313 copyout (v1flto) \
314 firstprivate (v1flti) \
315 copyout (v2flto) \
316 firstprivate (v2flti) \
317 copyout (v4flto) \
318 firstprivate (v4flti) \
319 copyout (v8flto) \
320 firstprivate (v8flti) \
321 copyout (v1dblo) \
322 firstprivate (v1dbli) \
323 copyout (v2dblo) \
324 firstprivate (v2dbli) \
325 copyout (v4dblo) \
326 firstprivate (v4dbli) \
327 copyout (v8dblo) \
328 firstprivate (v8dbli)
329 {
330 v2u8o = ++v2u8i;
331 v4i16o = --v4i16i;
332 v8u32o = ++v8u32i;
333 v16i64o = --v16i64i;
334 v1flto = --v1flti;
335 v2flto = --v2flti;
336 v4flto = --v4flti;
337 v8flto = --v8flti;
338 v1dblo = --v1dbli;
339 v2dblo = --v2dbli;
340 v4dblo = --v4dbli;
341 v8dblo = --v8dbli;
342 }
343 if (!V_EQ (v2u8o, v2u8i + 1))
344 __builtin_abort ();
345 if (!V_EQ (v4i16o, v4i16i - 1))
346 __builtin_abort ();
347 if (!V_EQ (v8u32o, v8u32i + 1))
348 __builtin_abort ();
349 if (!V_EQ (v16i64o, v16i64i - 1))
350 __builtin_abort ();
351 if (!V_EQ (v1flto, v1flti - 1))
352 __builtin_abort ();
353 if (!V_EQ (v2flto, v2flti - 1))
354 __builtin_abort ();
355 if (!V_EQ (v4flto, v4flti - 1))
356 __builtin_abort ();
357 if (!V_EQ (v8flto, v8flti - 1))
358 __builtin_abort ();
359 if (!V_EQ (v1dblo, v1dbli - 1))
360 __builtin_abort ();
361 if (!V_EQ (v2dblo, v2dbli - 1))
362 __builtin_abort ();
363 if (!V_EQ (v4dblo, v4dbli - 1))
364 __builtin_abort ();
365 if (!V_EQ (v8dblo, v8dbli - 1))
366 __builtin_abort ();
367 }
368
369
370 /* "error: could not find an integer type of the same size as 'long double'" */
371 #if HAVE_INT128
372 typedef long double __attribute__ ((vector_size (1 * sizeof (long double)))) v1ldbl;
373 typedef long double __attribute__ ((vector_size (2 * sizeof (long double)))) v2ldbl;
374 typedef long double __attribute__ ((vector_size (4 * sizeof (long double)))) v4ldbl;
375 typedef long double __attribute__ ((vector_size (8 * sizeof (long double)))) v8ldbl;
376
377 static void
vldbl(v1ldbl v1ldbli,v2ldbl v2ldbli,v4ldbl v4ldbli,v8ldbl v8ldbli)378 vldbl (v1ldbl v1ldbli, v2ldbl v2ldbli, v4ldbl v4ldbli, v8ldbl v8ldbli)
379 {
380 # if DO_LONG_DOUBLE
381 v1ldbl v1ldblo;
382 v2ldbl v2ldblo;
383 v4ldbl v4ldblo;
384 v8ldbl v8ldblo;
385 # pragma acc parallel \
386 copyout (v1ldblo) \
387 firstprivate (v1ldbli) \
388 copyout (v2ldblo) \
389 firstprivate (v2ldbli) \
390 copyout (v4ldblo) \
391 firstprivate (v4ldbli) \
392 copyout (v8ldblo) \
393 firstprivate (v8ldbli)
394 {
395 v1ldblo = --v1ldbli;
396 v2ldblo = --v2ldbli;
397 v4ldblo = --v4ldbli;
398 v8ldblo = --v8ldbli;
399 }
400 if (!V_EQ (v1ldblo, v1ldbli - 1))
401 __builtin_abort ();
402 if (!V_EQ (v2ldblo, v2ldbli - 1))
403 __builtin_abort ();
404 if (!V_EQ (v4ldblo, v4ldbli - 1))
405 __builtin_abort ();
406 if (!V_EQ (v8ldblo, v8ldbli - 1))
407 __builtin_abort ();
408 # endif
409 }
410 #endif
411
412
413 static void
vla(int array_li)414 vla (int array_li)
415 {
416 _Complex double array[array_li];
417 uint32_t array_so;
418 #pragma acc parallel \
419 copyout (array_so)
420 /* The gimplifier has created an implicit 'firstprivate' clause for the array
421 length.
422 { dg-final { scan-tree-dump {(?n)#pragma omp target oacc_parallel map\(from:array_so \[len: 4\]\) firstprivate\(array_li.[0-9]+\)} omplower { target { ! c++ } } } }
423 { dg-final { scan-tree-dump {(?n)#pragma omp target oacc_parallel map\(from:array_so \[len: 4\]\) firstprivate\(} omplower { target { c++ } } } }
424 (C++ computes an intermediate value, so can't scan for 'firstprivate(array_li)'.) */
425 /* For C, non-LP64, the gimplifier has also created a mapping for the array
426 itself; PR90859.
427 { dg-final { scan-tree-dump {(?n)#pragma omp target oacc_parallel map\(from:array_so \[len: 4\]\) firstprivate\(array_li.[0-9]+\) map\(tofrom:\(\*array.[0-9]+\) \[len: D\.[0-9]+\]\) map\(firstprivate:array \[pointer assign, bias: 0\]\) \[} omplower { target { c && { ! lp64 } } } } } */
428 {
429 array_so = sizeof array;
430 }
431 if (array_so != sizeof array)
432 __builtin_abort ();
433 }
434
435
436 #ifdef __cplusplus
437 }
438 #endif
439
440
441 int
main(int argc,char * argv[])442 main (int argc, char *argv[])
443 {
444 {
445 short s;
446 short *sp = &s;
447 p (sp);
448 }
449
450 {
451 bool bi = true;
452 b (bi);
453 }
454
455 {
456 int8_t i8i = -1;
457 uint8_t u8i = 1;
458 int16_t i16i = -2;
459 uint16_t u16i = 2;
460 int32_t i32i = -3;
461 uint32_t u32i = 3;
462 int64_t i64i = -4;
463 uint64_t u64i = 4;
464 i (i8i, u8i, i16i, u16i, i32i, u32i, i64i, u64i);
465 }
466
467 #if HAVE_INT128
468 {
469 __int128 i128i = -8;
470 unsigned __int128 u128i = 8;
471 i128 (i128i, u128i);
472 }
473 #endif
474
475 {
476 float flti = .5;
477 double dbli = .25;
478 flt_dbl (flti, dbli);
479 }
480
481 {
482 long double ldbli = .125;
483 ldbl (ldbli);
484 }
485
486 {
487 _Complex unsigned char cuci = 1 + 2j;
488 _Complex signed short cssi = -2 + (-4j);
489 _Complex unsigned int cuii = 3 + 6j;
490 _Complex signed long csli = -4 + (-8j);
491 _Complex float cflti = .5 + 1j;
492 _Complex double cdbli = .25 + .5j;
493 c (cuci, cssi, cuii, csli, cflti, cdbli);
494 }
495
496 {
497 _Complex long double cldbli = .125 + .25j;
498 cldbl (cldbli);
499 }
500
501 {
502 v2u8 v2u8i = {2, 3};
503 v4i16 v4i16i = { -1, -2, 5, 4 };
504 v8u32 v8u32i = { 3, 6, 9, 11};
505 v16i64 v16i64i = { 10, 21, -25, 44, 31, -1, 1, 222, -1, -12, 52, -44, -13, 1, -1, -222};
506 v1flt v1flti = { -.5 };
507 v2flt v2flti = { 1.5, -2.5 };
508 v4flt v4flti = { 3.5, -4.5, -5.5, -6.5 };
509 v8flt v8flti = { -7.5, 8.5, 9.5, 10.5, -11.5, -12.5, 13.5, 14.5 };
510 v1dbl v1dbli = { 0.25 };
511 v2dbl v2dbli = { -1.25, -2.25 };
512 v4dbl v4dbli = { 3.25, -4.25, 5.25, 6.25 };
513 v8dbl v8dbli = { 7.25, 8.25, -9.25, -10.25, -11.25, 12.25, 13.25, -14.25 };
514 v (v2u8i, v4i16i, v8u32i, v16i64i,
515 v1flti, v2flti, v4flti, v8flti,
516 v1dbli, v2dbli, v4dbli, v8dbli);
517 }
518
519 #if HAVE_INT128
520 {
521 v1ldbl v1ldbli = { -0.125 };
522 v2ldbl v2ldbli = { 1.125, -2.125 };
523 v4ldbl v4ldbli = { -3.125, -4.125, 5.125, -6.125 };
524 v8ldbl v8ldbli = { 7.125, -8.125, -9.125, 10.125, 11.125, 12.125, 13.125, 14.125 };
525 vldbl (v1ldbli, v2ldbli, v4ldbli, v8ldbli);
526 }
527 #endif
528
529 vla (argc);
530
531 return 0;
532 }
533