/* C / C++'s logical AND and OR operators take any scalar argument which compares (un)equal to 0 - the result 1 or 0 and of type int. In this testcase, the int result is again converted to an integer complex type. While having a floating-point/complex array element with || and && can make sense, having a complex reduction variable is odd but valid. Test: int complex reduction variable + int complex array. */ #define N 1024 _Complex char rcc[N]; _Complex short rcs[N]; _Complex int rci[N]; _Complex long long rcl[N]; int reduction_or () { _Complex char orc = 0; _Complex short ors = 0; _Complex int ori = 0; _Complex long orl = 0; #pragma omp parallel reduction(||: orc) for (int i=0; i < N; ++i) orc = orc || rcl[i]; #pragma omp parallel for reduction(||: ors) for (int i=0; i < N; ++i) ors = ors || rci[i]; #pragma omp parallel for simd reduction(||: ori) for (int i=0; i < N; ++i) ori = ori || rcs[i]; #pragma omp parallel loop reduction(||: orl) for (int i=0; i < N; ++i) orl = orl || rcc[i]; return __real__ (orc + ors + ori + orl) + __imag__ (orc + ors + ori + orl); } int reduction_or_teams () { _Complex char orc = 0; _Complex short ors = 0; _Complex int ori = 0; _Complex long orl = 0; #pragma omp teams distribute parallel for reduction(||: orc) for (int i=0; i < N; ++i) orc = orc || rcc[i]; #pragma omp teams distribute parallel for simd reduction(||: ors) for (int i=0; i < N; ++i) ors = ors || rcs[i]; #pragma omp teams distribute parallel for reduction(||: ori) for (int i=0; i < N; ++i) ori = ori || rci[i]; #pragma omp teams distribute parallel for simd reduction(||: orl) for (int i=0; i < N; ++i) orl = orl || rcl[i]; return __real__ (orc + ors + ori + orl) + __imag__ (orc + ors + ori + orl); } int reduction_and () { _Complex char andc = 1; _Complex short ands = 1; _Complex int andi = 1; _Complex long andl = 1; #pragma omp parallel reduction(&&: andc) for (int i=0; i < N; ++i) andc = andc && rcc[i]; #pragma omp parallel for reduction(&&: ands) for (int i=0; i < N; ++i) ands = ands && rcs[i]; #pragma omp parallel for simd reduction(&&: andi) for (int i=0; i < N; ++i) andi = andi && rci[i]; #pragma omp parallel loop reduction(&&: andl) for (int i=0; i < N; ++i) andl = andl && rcl[i]; return __real__ (andc + ands + andi + andl) + __imag__ (andc + ands + andi + andl); } int reduction_and_teams () { _Complex char andc = 1; _Complex short ands = 1; _Complex int andi = 1; _Complex long andl = 1; #pragma omp teams distribute parallel for reduction(&&: andc) for (int i=0; i < N; ++i) andc = andc && rcl[i]; #pragma omp teams distribute parallel for simd reduction(&&: ands) for (int i=0; i < N; ++i) ands = ands && rci[i]; #pragma omp teams distribute parallel for reduction(&&: andi) for (int i=0; i < N; ++i) andi = andi && rcs[i]; #pragma omp teams distribute parallel for simd reduction(&&: andl) for (int i=0; i < N; ++i) andl = andl && rcc[i]; return __real__ (andc + ands + andi + andl) + __imag__ (andc + ands + andi + andl); } int main () { for (int i = 0; i < N; ++i) { rcc[i] = 0; rcs[i] = 0; rci[i] = 0; rcl[i] = 0; } if (reduction_or () != 0) __builtin_abort (); if (reduction_or_teams () != 0) __builtin_abort (); if (reduction_and () != 0) __builtin_abort (); if (reduction_and_teams () != 0) __builtin_abort (); rcc[10] = 1.0; rcs[15] = 1.0i; rci[10] = 1.0; rcl[15] = 1.0i; if (reduction_or () != 4) __builtin_abort (); if (reduction_or_teams () != 4) __builtin_abort (); if (reduction_and () != 0) __builtin_abort (); if (reduction_and_teams () != 0) __builtin_abort (); for (int i = 0; i < N; ++i) { rcc[i] = 1; rcs[i] = 1i; rci[i] = 1; rcl[i] = 1 + 1i; } if (reduction_or () != 4) __builtin_abort (); if (reduction_or_teams () != 4) __builtin_abort (); if (reduction_and () != 4) __builtin_abort (); if (reduction_and_teams () != 4) __builtin_abort (); rcc[10] = 0.0; rcs[15] = 0.0; rci[10] = 0.0; rcl[15] = 0.0; if (reduction_or () != 4) __builtin_abort (); if (reduction_or_teams () != 4) __builtin_abort (); if (reduction_and () != 0) __builtin_abort (); if (reduction_and_teams () != 0) __builtin_abort (); return 0; }