1 /* C / C++'s logical AND and OR operators take any scalar argument
2    which compares (un)equal to 0 - the result 1 or 0 and of type int.
3 
4    In this testcase, the int result is again converted to an integer complex
5    type.
6 
7    While having a floating-point/complex array element with || and && can make
8    sense, having a complex reduction variable is odd but valid.
9 
10    Test: int complex reduction variable + int complex array.  */
11 
12 #define N 1024
13 _Complex char rcc[N];
14 _Complex short rcs[N];
15 _Complex int rci[N];
16 _Complex long long rcl[N];
17 
18 int
reduction_or()19 reduction_or ()
20 {
21   _Complex char orc = 0;
22   _Complex short ors = 0;
23   _Complex int ori = 0;
24   _Complex long orl = 0;
25 
26   #pragma omp parallel reduction(||: orc)
27   for (int i=0; i < N; ++i)
28     orc = orc || rcl[i];
29 
30   #pragma omp parallel for reduction(||: ors)
31   for (int i=0; i < N; ++i)
32     ors = ors || rci[i];
33 
34   #pragma omp parallel for simd reduction(||: ori)
35   for (int i=0; i < N; ++i)
36     ori = ori || rcs[i];
37 
38   #pragma omp parallel loop reduction(||: orl)
39   for (int i=0; i < N; ++i)
40     orl = orl || rcc[i];
41 
42   return __real__ (orc + ors + ori + orl) + __imag__ (orc + ors + ori + orl);
43 }
44 
45 int
reduction_or_teams()46 reduction_or_teams ()
47 {
48   _Complex char orc = 0;
49   _Complex short ors = 0;
50   _Complex int ori = 0;
51   _Complex long orl = 0;
52 
53   #pragma omp teams distribute parallel for reduction(||: orc)
54   for (int i=0; i < N; ++i)
55     orc = orc || rcc[i];
56 
57   #pragma omp teams distribute parallel for simd reduction(||: ors)
58   for (int i=0; i < N; ++i)
59     ors = ors || rcs[i];
60 
61   #pragma omp teams distribute parallel for reduction(||: ori)
62   for (int i=0; i < N; ++i)
63     ori = ori || rci[i];
64 
65   #pragma omp teams distribute parallel for simd reduction(||: orl)
66   for (int i=0; i < N; ++i)
67     orl = orl || rcl[i];
68 
69   return __real__ (orc + ors + ori + orl) + __imag__ (orc + ors + ori + orl);
70 }
71 
72 int
reduction_and()73 reduction_and ()
74 {
75   _Complex char andc = 1;
76   _Complex short ands = 1;
77   _Complex int andi = 1;
78   _Complex long andl = 1;
79 
80   #pragma omp parallel reduction(&&: andc)
81   for (int i=0; i < N; ++i)
82     andc = andc && rcc[i];
83 
84   #pragma omp parallel for reduction(&&: ands)
85   for (int i=0; i < N; ++i)
86     ands = ands && rcs[i];
87 
88   #pragma omp parallel for simd reduction(&&: andi)
89   for (int i=0; i < N; ++i)
90     andi = andi && rci[i];
91 
92   #pragma omp parallel loop reduction(&&: andl)
93   for (int i=0; i < N; ++i)
94     andl = andl && rcl[i];
95 
96   return __real__ (andc + ands + andi + andl)
97 	 + __imag__ (andc + ands + andi + andl);
98 }
99 
100 int
reduction_and_teams()101 reduction_and_teams ()
102 {
103   _Complex char andc = 1;
104   _Complex short ands = 1;
105   _Complex int andi = 1;
106   _Complex long andl = 1;
107 
108   #pragma omp teams distribute parallel for reduction(&&: andc)
109   for (int i=0; i < N; ++i)
110     andc = andc && rcl[i];
111 
112   #pragma omp teams distribute parallel for simd reduction(&&: ands)
113   for (int i=0; i < N; ++i)
114     ands = ands && rci[i];
115 
116   #pragma omp teams distribute parallel for reduction(&&: andi)
117   for (int i=0; i < N; ++i)
118     andi = andi && rcs[i];
119 
120   #pragma omp teams distribute parallel for simd reduction(&&: andl)
121   for (int i=0; i < N; ++i)
122     andl = andl && rcc[i];
123 
124   return __real__ (andc + ands + andi + andl)
125 	 + __imag__ (andc + ands + andi + andl);
126 }
127 
128 int
main()129 main ()
130 {
131   for (int i = 0; i < N; ++i)
132     {
133       rcc[i] = 0;
134       rcs[i] = 0;
135       rci[i] = 0;
136       rcl[i] = 0;
137     }
138 
139   if (reduction_or () != 0)
140     __builtin_abort ();
141   if (reduction_or_teams () != 0)
142     __builtin_abort ();
143   if (reduction_and () != 0)
144     __builtin_abort ();
145   if (reduction_and_teams () != 0)
146     __builtin_abort ();
147 
148   rcc[10] = 1.0;
149   rcs[15] = 1.0i;
150   rci[10] = 1.0;
151   rcl[15] = 1.0i;
152 
153   if (reduction_or () != 4)
154     __builtin_abort ();
155   if (reduction_or_teams () != 4)
156     __builtin_abort ();
157   if (reduction_and () != 0)
158     __builtin_abort ();
159   if (reduction_and_teams () != 0)
160     __builtin_abort ();
161 
162   for (int i = 0; i < N; ++i)
163     {
164       rcc[i] = 1;
165       rcs[i] = 1i;
166       rci[i] = 1;
167       rcl[i] = 1 + 1i;
168     }
169 
170   if (reduction_or () != 4)
171     __builtin_abort ();
172   if (reduction_or_teams () != 4)
173     __builtin_abort ();
174   if (reduction_and () != 4)
175     __builtin_abort ();
176   if (reduction_and_teams () != 4)
177     __builtin_abort ();
178 
179   rcc[10] = 0.0;
180   rcs[15] = 0.0;
181   rci[10] = 0.0;
182   rcl[15] = 0.0;
183 
184   if (reduction_or () != 4)
185     __builtin_abort ();
186   if (reduction_or_teams () != 4)
187     __builtin_abort ();
188   if (reduction_and () != 0)
189     __builtin_abort ();
190   if (reduction_and_teams () != 0)
191     __builtin_abort ();
192 
193   return 0;
194 }
195