mirror of
https://github.com/autc04/Retro68.git
synced 2024-11-05 04:06:45 +00:00
150 lines
3.2 KiB
C
150 lines
3.2 KiB
C
// { 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 ();
|
|
}
|