12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- // { dg-do run }
- extern "C" void abort ();
- namespace NS
- {
- struct U
- {
- void foo (U &, bool);
- U ();
- };
- struct S
- {
- int s;
- #pragma omp declare reduction (foo : U, S : omp_out.foo (omp_in, false))
- #pragma omp declare reduction (foo : int : omp_out += omp_in) \
- initializer (omp_priv = int ())
- void baz (int v)
- {
- S s;
- int q = 0;
- if (s.s != 6 || v != 0) abort ();
- s.s = 20;
- #pragma omp parallel num_threads (4) reduction (foo : s, v) \
- reduction (::NS::U::operator + : q)
- {
- if (s.s != 6 || q != 0 || v != 0) abort ();
- asm volatile ("" : "+m" (s.s), "+r" (q), "+r" (v));
- s.s++; q++; v++;
- }
- if (s.s != 20 + q * 7 || q != v) 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 : omp_out.foo (omp_in)) \
- initializer (omp_priv (8))
- }
- NS::S::~S ()
- {
- if (s < 6) abort ();
- s = -1;
- /* Ensure the above store is not DSEd. */
- asm volatile ("" : : "r" (&s) : "memory");
- }
- struct T : public NS::S
- {
- void baz ()
- {
- S 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 ();
- }
- };
- int
- main ()
- {
- NS::S s;
- s.baz (0);
- T t;
- t.baz ();
- 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 ();
- }
|