1 // { dg-require-effective-target size32plus }
2 
3 extern "C" void abort ();
4 int r, a[1024], b[1024], q;
5 
6 #pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
7 
8 __attribute__((noipa)) void
foo(int * a,int * b,int & r)9 foo (int *a, int *b, int &r)
10 {
11   #pragma omp for reduction (inscan, foo:r)
12   for (int i = 0; i < 1024; i++)
13     {
14       b[i] = r;
15       #pragma omp scan exclusive(r)
16       r += a[i];
17     }
18 }
19 
20 __attribute__((noipa)) int
bar(void)21 bar (void)
22 {
23   int &s = q;
24   q = 0;
25   #pragma omp parallel
26   #pragma omp for reduction (inscan, foo:s) nowait
27   for (int i = 0; i < 1024; i++)
28     {
29       b[i] = s;
30       #pragma omp scan exclusive(s)
31       s += 2 * a[i];
32     }
33   return s;
34 }
35 
36 __attribute__((noipa)) void
baz(int * a,int * b,int & r)37 baz (int *a, int *b, int &r)
38 {
39   #pragma omp parallel for reduction (inscan, foo:r)
40   for (int i = 0; i < 1024; i++)
41     {
42       b[i] = r;
43       #pragma omp scan exclusive(r)
44       r += a[i];
45     }
46 }
47 
48 __attribute__((noipa)) int
qux(void)49 qux (void)
50 {
51   int &s = q;
52   q = 0;
53   #pragma omp parallel for reduction (inscan, foo:s)
54   for (int i = 0; i < 1024; i++)
55     {
56       b[i] = s;
57       #pragma omp scan exclusive(s)
58       s += 2 * a[i];
59     }
60   return s;
61 }
62 
63 int
main()64 main ()
65 {
66   int s = 0;
67   for (int i = 0; i < 1024; ++i)
68     {
69       a[i] = i;
70       b[i] = -1;
71       asm ("" : "+g" (i));
72     }
73   #pragma omp parallel
74   foo (a, b, r);
75   if (r != 1024 * 1023 / 2)
76     abort ();
77   for (int i = 0; i < 1024; ++i)
78     {
79       if (b[i] != s)
80 	abort ();
81       else
82 	b[i] = 25;
83       s += i;
84     }
85   if (bar () != 1024 * 1023)
86     abort ();
87   s = 0;
88   for (int i = 0; i < 1024; ++i)
89     {
90       if (b[i] != s)
91 	abort ();
92       else
93 	b[i] = -1;
94       s += 2 * i;
95     }
96   r = 0;
97   baz (a, b, r);
98   if (r != 1024 * 1023 / 2)
99     abort ();
100   s = 0;
101   for (int i = 0; i < 1024; ++i)
102     {
103       if (b[i] != s)
104 	abort ();
105       else
106 	b[i] = -25;
107       s += i;
108     }
109   if (qux () != 1024 * 1023)
110     abort ();
111   s = 0;
112   for (int i = 0; i < 1024; ++i)
113     {
114       if (b[i] != s)
115 	abort ();
116       s += 2 * i;
117     }
118 }
119