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