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