PR target/81988
[official-gcc.git] / libgomp / testsuite / libgomp.c++ / udr-3.C
blob74a01389c7b196e66719194b222f20d2f5105cf5
1 // { dg-do run }
3 extern "C" void abort ();
5 void
6 dblinit (double *p)
8   *p = 2.0;
11 namespace NS
13   template <int N>
14   struct U
15   {
16     void foo (U &, bool);
17     U ();
18   };
19   template <int N>
20   struct S
21   {
22     int s;
23     #pragma omp declare reduction (foo : U<0>, S : omp_out.foo (omp_in, false))
24     #pragma omp declare reduction (foo : int : omp_out += omp_in) \
25         initializer (omp_priv = N + 2)
26     #pragma omp declare reduction (foo : double : omp_out += omp_in) \
27         initializer (dblinit (&omp_priv))
28     void baz (int v)
29     {
30       S s;
31       int q = 0;
32       if (s.s != 6 || v != 0) abort ();
33       s.s = 20;
34       double d = 4.0;
35       #pragma omp parallel num_threads (4) reduction (foo : s, v, d) \
36         reduction (::NS::U<N>::operator + : q)
37       {
38         if (s.s != 6 || q != 0 || v != N + 2 || d != 2.0) abort ();
39         asm volatile ("" : "+m" (s.s), "+r" (q), "+r" (v));
40         s.s++; q++; v++;
41       }
42       if (s.s != 20 + q * 7 || (N + 3) * q != v || d != 4.0 + 2.0 * q)
43         abort ();
44     }
45     void foo (S &x) { s += x.s; }
46     void foo (S &x, bool y) { s += x.s; if (y) abort (); }
47     S (const S &x) { s = x.s + 1; }
48     S (const S &x, bool y) { s = x.s + 2; if (y) abort (); }
49     S () { s = 6; }
50     S (int x) { s = x; }
51     ~S ();
52   };
53   #pragma omp declare reduction (bar : S<1> : omp_out.foo (omp_in)) \
54         initializer (omp_priv (8))
57 template <int N>
58 NS::S<N>::~S ()
60   if (s < 6) abort ();
61   s = -1;
62   /* Ensure the above store is not DSEd.  */
63   asm volatile ("" : : "r" (&s) : "memory");
66 template <int N>
67 struct T : public NS::S<N>
69   void baz ()
70   {
71     NS::S<N> s;
72     int q = 0;
73     if (s.s != 6) abort ();
74     #pragma omp parallel num_threads (4) reduction (foo:s) \
75         reduction (+: q)
76     {
77       if (s.s != 6 || q != 0) abort ();
78       asm volatile ("" : "+m" (s.s), "+r" (q));
79       s.s += 2; q++;
80     }
81     if (s.s != 6 + q * 8) abort ();
82   }
85 struct W
87   int v;
88   W () : v (6) {}
89   ~W () {}
92 template <typename T, typename D>
93 struct V
95   #pragma omp declare reduction (baz: T: omp_out.s += omp_in.s) \
96         initializer (omp_priv (11))
97   #pragma omp declare reduction (baz: D: omp_out += omp_in) \
98         initializer (dblinit (&omp_priv))
99   static void dblinit (D *x) { *x = 3.0; }
100   void baz ()
101   {
102     T t;
103     V v;
104     int q = 0;
105     D d = 4.0;
106     if (t.s != 6 || v.v != 4) abort ();
107     #pragma omp declare reduction (+ : V, W : omp_out.v -= omp_in.v) \
108         initializer (omp_priv (12))
109     {
110       #pragma omp declare reduction (+ : W, V : omp_out.v += omp_in.v) \
111         initializer (omp_priv (9))
112       #pragma omp parallel num_threads (4) reduction (+: v, q) \
113         reduction (baz: t, d)
114       {
115         if (t.s != 11 || v.v != 9 || q != 0 || d != 3.0) abort ();
116         asm volatile ("" : "+m" (t.s), "+m" (v.v), "+r" (q));
117         t.s += 2; v.v += 3; q++;
118       }
119       if (t.s != 6 + 13 * q || v.v != 4 + 12 * q || d != 4.0 + 3.0 * q)
120         abort ();
121     }
122   }
123   int v;
124   V () : v (4) {}
125   V (int x) : v (x) {}
126   ~V () {}
130 main ()
132   NS::S<0> u;
133   u.baz (0);
134   T<2> t;
135   t.baz ();
136   NS::S<1> s;
137   int q = 0;
138   if (s.s != 6) abort ();
139   // Test ADL
140   #pragma omp parallel num_threads (4) reduction (bar:s) reduction (+:q)
141   {
142     if (s.s != 8 || q != 0) abort ();
143     asm volatile ("" : "+m" (s.s), "+r" (q));
144     s.s += 4; q++;
145   }
146   if (s.s != 6 + q * 12) abort ();
147   V <NS::S <0>, double> v;
148   v.baz ();