(root)/
gcc-13.2.0/
gcc/
testsuite/
c-c++-common/
goacc/
firstprivate-mappings-1.c
       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
      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
      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
      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
     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
     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
     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
     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
     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
     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
     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
     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
     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  }