diff options
Diffstat (limited to 'libgomp/testsuite/libgomp.c++/udr-3.C')
-rw-r--r-- | libgomp/testsuite/libgomp.c++/udr-3.C | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/libgomp/testsuite/libgomp.c++/udr-3.C b/libgomp/testsuite/libgomp.c++/udr-3.C new file mode 100644 index 00000000000..74a01389c7b --- /dev/null +++ b/libgomp/testsuite/libgomp.c++/udr-3.C @@ -0,0 +1,149 @@ +// { dg-do run } + +extern "C" void abort (); + +void +dblinit (double *p) +{ + *p = 2.0; +} + +namespace NS +{ + template <int N> + struct U + { + void foo (U &, bool); + U (); + }; + template <int N> + struct S + { + int s; + #pragma omp declare reduction (foo : U<0>, S : omp_out.foo (omp_in, false)) + #pragma omp declare reduction (foo : int : omp_out += omp_in) \ + initializer (omp_priv = N + 2) + #pragma omp declare reduction (foo : double : omp_out += omp_in) \ + initializer (dblinit (&omp_priv)) + void baz (int v) + { + S s; + int q = 0; + if (s.s != 6 || v != 0) abort (); + s.s = 20; + double d = 4.0; + #pragma omp parallel num_threads (4) reduction (foo : s, v, d) \ + reduction (::NS::U<N>::operator + : q) + { + if (s.s != 6 || q != 0 || v != N + 2 || d != 2.0) abort (); + asm volatile ("" : "+m" (s.s), "+r" (q), "+r" (v)); + s.s++; q++; v++; + } + if (s.s != 20 + q * 7 || (N + 3) * q != v || d != 4.0 + 2.0 * q) + abort (); + } + void foo (S &x) { s += x.s; } + void foo (S &x, bool y) { s += x.s; if (y) abort (); } + S (const S &x) { s = x.s + 1; } + S (const S &x, bool y) { s = x.s + 2; if (y) abort (); } + S () { s = 6; } + S (int x) { s = x; } + ~S (); + }; + #pragma omp declare reduction (bar : S<1> : omp_out.foo (omp_in)) \ + initializer (omp_priv (8)) +} + +template <int N> +NS::S<N>::~S () +{ + if (s < 6) abort (); + s = -1; + /* Ensure the above store is not DSEd. */ + asm volatile ("" : : "r" (&s) : "memory"); +} + +template <int N> +struct T : public NS::S<N> +{ + void baz () + { + NS::S<N> s; + int q = 0; + if (s.s != 6) abort (); + #pragma omp parallel num_threads (4) reduction (foo:s) \ + reduction (+: q) + { + if (s.s != 6 || q != 0) abort (); + asm volatile ("" : "+m" (s.s), "+r" (q)); + s.s += 2; q++; + } + if (s.s != 6 + q * 8) abort (); + } +}; + +struct W +{ + int v; + W () : v (6) {} + ~W () {} +}; + +template <typename T, typename D> +struct V +{ + #pragma omp declare reduction (baz: T: omp_out.s += omp_in.s) \ + initializer (omp_priv (11)) + #pragma omp declare reduction (baz: D: omp_out += omp_in) \ + initializer (dblinit (&omp_priv)) + static void dblinit (D *x) { *x = 3.0; } + void baz () + { + T t; + V v; + int q = 0; + D d = 4.0; + if (t.s != 6 || v.v != 4) abort (); + #pragma omp declare reduction (+ : V, W : omp_out.v -= omp_in.v) \ + initializer (omp_priv (12)) + { + #pragma omp declare reduction (+ : W, V : omp_out.v += omp_in.v) \ + initializer (omp_priv (9)) + #pragma omp parallel num_threads (4) reduction (+: v, q) \ + reduction (baz: t, d) + { + if (t.s != 11 || v.v != 9 || q != 0 || d != 3.0) abort (); + asm volatile ("" : "+m" (t.s), "+m" (v.v), "+r" (q)); + t.s += 2; v.v += 3; q++; + } + if (t.s != 6 + 13 * q || v.v != 4 + 12 * q || d != 4.0 + 3.0 * q) + abort (); + } + } + int v; + V () : v (4) {} + V (int x) : v (x) {} + ~V () {} +}; + +int +main () +{ + NS::S<0> u; + u.baz (0); + T<2> t; + t.baz (); + NS::S<1> s; + int q = 0; + if (s.s != 6) abort (); + // Test ADL + #pragma omp parallel num_threads (4) reduction (bar:s) reduction (+:q) + { + if (s.s != 8 || q != 0) abort (); + asm volatile ("" : "+m" (s.s), "+r" (q)); + s.s += 4; q++; + } + if (s.s != 6 + q * 12) abort (); + V <NS::S <0>, double> v; + v.baz (); +} |