OpenMP: Support complex/float in && and || reduction
C/C++ permit logical AND and logical OR also with floating-point or complex arguments by doing an unequal zero comparison; the result is an 'int' with value one or zero. Hence, those are also permitted as reduction variable, even though it is not the most sensible thing to do. gcc/c/ChangeLog: * c-typeck.c (c_finish_omp_clauses): Accept float + complex for || and && reductions. gcc/cp/ChangeLog: * semantics.c (finish_omp_reduction_clause): Accept float + complex for || and && reductions. gcc/ChangeLog: * omp-low.c (lower_rec_input_clauses, lower_reduction_clauses): Handle && and || with floating-point and complex arguments. gcc/testsuite/ChangeLog: * gcc.dg/gomp/clause-1.c: Use 'reduction(&:..)' instead of '...(&&:..)'. libgomp/ChangeLog: * testsuite/libgomp.c-c++-common/reduction-1.c: New test. * testsuite/libgomp.c-c++-common/reduction-2.c: New test. * testsuite/libgomp.c-c++-common/reduction-3.c: New test. (cherry picked from commit 1580fc764423bf89e9b853aaa8c65999e37ccb8b)
This commit is contained in:
parent
2f49122aec
commit
d2904de2cf
@ -14119,6 +14119,8 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
|
||||
case PLUS_EXPR:
|
||||
case MULT_EXPR:
|
||||
case MINUS_EXPR:
|
||||
case TRUTH_ANDIF_EXPR:
|
||||
case TRUTH_ORIF_EXPR:
|
||||
break;
|
||||
case MIN_EXPR:
|
||||
if (TREE_CODE (type) == COMPLEX_TYPE)
|
||||
@ -14137,14 +14139,6 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
|
||||
case BIT_IOR_EXPR:
|
||||
r_name = "|";
|
||||
break;
|
||||
case TRUTH_ANDIF_EXPR:
|
||||
if (FLOAT_TYPE_P (type))
|
||||
r_name = "&&";
|
||||
break;
|
||||
case TRUTH_ORIF_EXPR:
|
||||
if (FLOAT_TYPE_P (type))
|
||||
r_name = "||";
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
@ -6030,6 +6030,8 @@ finish_omp_reduction_clause (tree c, bool *need_default_ctor, bool *need_dtor)
|
||||
case PLUS_EXPR:
|
||||
case MULT_EXPR:
|
||||
case MINUS_EXPR:
|
||||
case TRUTH_ANDIF_EXPR:
|
||||
case TRUTH_ORIF_EXPR:
|
||||
predefined = true;
|
||||
break;
|
||||
case MIN_EXPR:
|
||||
@ -6045,12 +6047,6 @@ finish_omp_reduction_clause (tree c, bool *need_default_ctor, bool *need_dtor)
|
||||
break;
|
||||
predefined = true;
|
||||
break;
|
||||
case TRUTH_ANDIF_EXPR:
|
||||
case TRUTH_ORIF_EXPR:
|
||||
if (FLOAT_TYPE_P (type))
|
||||
break;
|
||||
predefined = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -6376,6 +6376,11 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
|
||||
if (code == MINUS_EXPR)
|
||||
code = PLUS_EXPR;
|
||||
|
||||
/* C/C++ permits FP/complex with || and &&. */
|
||||
bool is_fp_and_or
|
||||
= ((code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
|
||||
&& (FLOAT_TYPE_P (TREE_TYPE (new_var))
|
||||
|| TREE_CODE (TREE_TYPE (new_var)) == COMPLEX_TYPE));
|
||||
tree new_vard = new_var;
|
||||
if (is_simd && omp_is_reference (var))
|
||||
{
|
||||
@ -6424,7 +6429,20 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
|
||||
x = build2 (code, TREE_TYPE (ivar), ivar, x);
|
||||
gimplify_assign (ivar, x, &llist[2]);
|
||||
}
|
||||
x = build2 (code, TREE_TYPE (ref), ref, ivar);
|
||||
tree ivar2 = ivar;
|
||||
tree ref2 = ref;
|
||||
if (is_fp_and_or)
|
||||
{
|
||||
tree zero = build_zero_cst (TREE_TYPE (ivar));
|
||||
ivar2 = fold_build2_loc (clause_loc, NE_EXPR,
|
||||
integer_type_node, ivar,
|
||||
zero);
|
||||
ref2 = fold_build2_loc (clause_loc, NE_EXPR,
|
||||
integer_type_node, ref, zero);
|
||||
}
|
||||
x = build2 (code, TREE_TYPE (ref), ref2, ivar2);
|
||||
if (is_fp_and_or)
|
||||
x = fold_convert (TREE_TYPE (ref), x);
|
||||
ref = build_outer_var_ref (var, ctx);
|
||||
gimplify_assign (ref, x, &llist[1]);
|
||||
|
||||
@ -6443,8 +6461,22 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
|
||||
if (is_simd)
|
||||
{
|
||||
tree ref = build_outer_var_ref (var, ctx);
|
||||
|
||||
x = build2 (code, TREE_TYPE (ref), ref, new_var);
|
||||
tree new_var2 = new_var;
|
||||
tree ref2 = ref;
|
||||
if (is_fp_and_or)
|
||||
{
|
||||
tree zero = build_zero_cst (TREE_TYPE (new_var));
|
||||
new_var2
|
||||
= fold_build2_loc (clause_loc, NE_EXPR,
|
||||
integer_type_node, new_var,
|
||||
zero);
|
||||
ref2 = fold_build2_loc (clause_loc, NE_EXPR,
|
||||
integer_type_node, ref,
|
||||
zero);
|
||||
}
|
||||
x = build2 (code, TREE_TYPE (ref2), ref2, new_var2);
|
||||
if (is_fp_and_or)
|
||||
x = fold_convert (TREE_TYPE (new_var), x);
|
||||
ref = build_outer_var_ref (var, ctx);
|
||||
gimplify_assign (ref, x, dlist);
|
||||
}
|
||||
@ -7384,13 +7416,32 @@ lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp,
|
||||
if (code == MINUS_EXPR)
|
||||
code = PLUS_EXPR;
|
||||
|
||||
/* C/C++ permits FP/complex with || and &&. */
|
||||
bool is_fp_and_or = ((code == TRUTH_ANDIF_EXPR
|
||||
|| code == TRUTH_ORIF_EXPR)
|
||||
&& (FLOAT_TYPE_P (TREE_TYPE (new_var))
|
||||
|| (TREE_CODE (TREE_TYPE (new_var))
|
||||
== COMPLEX_TYPE)));
|
||||
if (count == 1)
|
||||
{
|
||||
tree addr = build_fold_addr_expr_loc (clause_loc, ref);
|
||||
|
||||
addr = save_expr (addr);
|
||||
ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
|
||||
x = fold_build2_loc (clause_loc, code, TREE_TYPE (ref), ref, new_var);
|
||||
tree new_var2 = new_var;
|
||||
tree ref2 = ref;
|
||||
if (is_fp_and_or)
|
||||
{
|
||||
tree zero = build_zero_cst (TREE_TYPE (new_var));
|
||||
new_var2 = fold_build2_loc (clause_loc, NE_EXPR,
|
||||
integer_type_node, new_var, zero);
|
||||
ref2 = fold_build2_loc (clause_loc, NE_EXPR, integer_type_node,
|
||||
ref, zero);
|
||||
}
|
||||
x = fold_build2_loc (clause_loc, code, TREE_TYPE (new_var2), ref2,
|
||||
new_var2);
|
||||
if (is_fp_and_or)
|
||||
x = fold_convert (TREE_TYPE (new_var), x);
|
||||
x = build2 (OMP_ATOMIC, void_type_node, addr, x);
|
||||
OMP_ATOMIC_MEMORY_ORDER (x) = OMP_MEMORY_ORDER_RELAXED;
|
||||
gimplify_and_add (x, stmt_seqp);
|
||||
@ -7495,7 +7546,19 @@ lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp,
|
||||
}
|
||||
else
|
||||
{
|
||||
x = build2 (code, TREE_TYPE (out), out, priv);
|
||||
tree out2 = out;
|
||||
tree priv2 = priv;
|
||||
if (is_fp_and_or)
|
||||
{
|
||||
tree zero = build_zero_cst (TREE_TYPE (out));
|
||||
out2 = fold_build2_loc (clause_loc, NE_EXPR,
|
||||
integer_type_node, out, zero);
|
||||
priv2 = fold_build2_loc (clause_loc, NE_EXPR,
|
||||
integer_type_node, priv, zero);
|
||||
}
|
||||
x = build2 (code, TREE_TYPE (out2), out2, priv2);
|
||||
if (is_fp_and_or)
|
||||
x = fold_convert (TREE_TYPE (out), x);
|
||||
out = unshare_expr (out);
|
||||
gimplify_assign (out, x, &sub_seq);
|
||||
}
|
||||
@ -7529,7 +7592,19 @@ lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp,
|
||||
}
|
||||
else
|
||||
{
|
||||
x = build2 (code, TREE_TYPE (ref), ref, new_var);
|
||||
tree new_var2 = new_var;
|
||||
tree ref2 = ref;
|
||||
if (is_fp_and_or)
|
||||
{
|
||||
tree zero = build_zero_cst (TREE_TYPE (new_var));
|
||||
new_var2 = fold_build2_loc (clause_loc, NE_EXPR,
|
||||
integer_type_node, new_var, zero);
|
||||
ref2 = fold_build2_loc (clause_loc, NE_EXPR, integer_type_node,
|
||||
ref, zero);
|
||||
}
|
||||
x = build2 (code, TREE_TYPE (ref), ref2, new_var2);
|
||||
if (is_fp_and_or)
|
||||
x = fold_convert (TREE_TYPE (new_var), x);
|
||||
ref = build_outer_var_ref (var, ctx);
|
||||
gimplify_assign (ref, x, &sub_seq);
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ foo (int x)
|
||||
;
|
||||
#pragma omp p reduction (|:d) /* { dg-error "has invalid type for" } */
|
||||
;
|
||||
#pragma omp p reduction (&&:d) /* { dg-error "has invalid type for" } */
|
||||
#pragma omp p reduction (&:d) /* { dg-error "has invalid type for" } */
|
||||
;
|
||||
#pragma omp p copyin (d) /* { dg-error "must be 'threadprivate'" } */
|
||||
;
|
||||
|
192
libgomp/testsuite/libgomp.c-c++-common/reduction-1.c
Normal file
192
libgomp/testsuite/libgomp.c-c++-common/reduction-1.c
Normal file
@ -0,0 +1,192 @@
|
||||
/* 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 a floating-poing
|
||||
or complex type.
|
||||
|
||||
While having a floating-point/complex array element with || and && can make
|
||||
sense, having a non-integer/non-bool reduction variable is odd but valid.
|
||||
|
||||
Test: FP reduction variable + FP array. */
|
||||
|
||||
#define N 1024
|
||||
_Complex float rcf[N];
|
||||
_Complex double rcd[N];
|
||||
float rf[N];
|
||||
double rd[N];
|
||||
|
||||
int
|
||||
reduction_or ()
|
||||
{
|
||||
float orf = 0;
|
||||
double ord = 0;
|
||||
_Complex float orfc = 0;
|
||||
_Complex double ordc = 0;
|
||||
|
||||
#pragma omp parallel reduction(||: orf)
|
||||
for (int i=0; i < N; ++i)
|
||||
orf = orf || rf[i];
|
||||
|
||||
#pragma omp parallel for reduction(||: ord)
|
||||
for (int i=0; i < N; ++i)
|
||||
ord = ord || rcd[i];
|
||||
|
||||
#pragma omp parallel for simd reduction(||: orfc)
|
||||
for (int i=0; i < N; ++i)
|
||||
orfc = orfc || rcf[i];
|
||||
|
||||
#pragma omp parallel loop reduction(||: ordc)
|
||||
for (int i=0; i < N; ++i)
|
||||
ordc = ordc || rcd[i];
|
||||
|
||||
return orf + ord + __real__ orfc + __real__ ordc;
|
||||
}
|
||||
|
||||
int
|
||||
reduction_or_teams ()
|
||||
{
|
||||
float orf = 0;
|
||||
double ord = 0;
|
||||
_Complex float orfc = 0;
|
||||
_Complex double ordc = 0;
|
||||
|
||||
#pragma omp teams distribute parallel for reduction(||: orf)
|
||||
for (int i=0; i < N; ++i)
|
||||
orf = orf || rf[i];
|
||||
|
||||
#pragma omp teams distribute parallel for simd reduction(||: ord)
|
||||
for (int i=0; i < N; ++i)
|
||||
ord = ord || rcd[i];
|
||||
|
||||
#pragma omp teams distribute parallel for reduction(||: orfc)
|
||||
for (int i=0; i < N; ++i)
|
||||
orfc = orfc || rcf[i];
|
||||
|
||||
#pragma omp teams distribute parallel for simd reduction(||: ordc)
|
||||
for (int i=0; i < N; ++i)
|
||||
ordc = ordc || rcd[i];
|
||||
|
||||
return orf + ord + __real__ orfc + __real__ ordc;
|
||||
}
|
||||
|
||||
int
|
||||
reduction_and ()
|
||||
{
|
||||
float andf = 1;
|
||||
double andd = 1;
|
||||
_Complex float andfc = 1;
|
||||
_Complex double anddc = 1;
|
||||
|
||||
#pragma omp parallel reduction(&&: andf)
|
||||
for (int i=0; i < N; ++i)
|
||||
andf = andf && rf[i];
|
||||
|
||||
#pragma omp parallel for reduction(&&: andd)
|
||||
for (int i=0; i < N; ++i)
|
||||
andd = andd && rcd[i];
|
||||
|
||||
#pragma omp parallel for simd reduction(&&: andfc)
|
||||
for (int i=0; i < N; ++i)
|
||||
andfc = andfc && rcf[i];
|
||||
|
||||
#pragma omp parallel loop reduction(&&: anddc)
|
||||
for (int i=0; i < N; ++i)
|
||||
anddc = anddc && rcd[i];
|
||||
|
||||
return andf + andd + __real__ andfc + __real__ anddc;
|
||||
}
|
||||
|
||||
int
|
||||
reduction_and_teams ()
|
||||
{
|
||||
float andf = 1;
|
||||
double andd = 1;
|
||||
_Complex float andfc = 1;
|
||||
_Complex double anddc = 1;
|
||||
|
||||
#pragma omp teams distribute parallel for reduction(&&: andf)
|
||||
for (int i=0; i < N; ++i)
|
||||
andf = andf && rf[i];
|
||||
|
||||
#pragma omp teams distribute parallel for simd reduction(&&: andd)
|
||||
for (int i=0; i < N; ++i)
|
||||
andd = andd && rcd[i];
|
||||
|
||||
#pragma omp teams distribute parallel for reduction(&&: andfc)
|
||||
for (int i=0; i < N; ++i)
|
||||
andfc = andfc && rcf[i];
|
||||
|
||||
#pragma omp teams distribute parallel for simd reduction(&&: anddc)
|
||||
for (int i=0; i < N; ++i)
|
||||
anddc = anddc && rcd[i];
|
||||
|
||||
return andf + andd + __real__ andfc + __real__ anddc;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
rf[i] = 0;
|
||||
rd[i] = 0;
|
||||
rcf[i] = 0;
|
||||
rcd[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 ();
|
||||
|
||||
rf[10] = 1.0;
|
||||
rd[15] = 1.0;
|
||||
rcf[10] = 1.0;
|
||||
rcd[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)
|
||||
{
|
||||
rf[i] = 1;
|
||||
rd[i] = 1;
|
||||
rcf[i] = 1;
|
||||
rcd[i] = 1;
|
||||
}
|
||||
|
||||
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 ();
|
||||
|
||||
rf[10] = 0.0;
|
||||
rd[15] = 0.0;
|
||||
rcf[10] = 0.0;
|
||||
rcd[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;
|
||||
}
|
192
libgomp/testsuite/libgomp.c-c++-common/reduction-2.c
Normal file
192
libgomp/testsuite/libgomp.c-c++-common/reduction-2.c
Normal file
@ -0,0 +1,192 @@
|
||||
/* 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 a floating-poing
|
||||
or complex type.
|
||||
|
||||
While having a floating-point/complex array element with || and && can make
|
||||
sense, having a non-integer/non-bool reduction variable is odd but valid.
|
||||
|
||||
Test: FP reduction variable + integer array. */
|
||||
|
||||
#define N 1024
|
||||
char rcf[N];
|
||||
short rcd[N];
|
||||
int rf[N];
|
||||
long rd[N];
|
||||
|
||||
int
|
||||
reduction_or ()
|
||||
{
|
||||
float orf = 0;
|
||||
double ord = 0;
|
||||
_Complex float orfc = 0;
|
||||
_Complex double ordc = 0;
|
||||
|
||||
#pragma omp parallel reduction(||: orf)
|
||||
for (int i=0; i < N; ++i)
|
||||
orf = orf || rf[i];
|
||||
|
||||
#pragma omp parallel for reduction(||: ord)
|
||||
for (int i=0; i < N; ++i)
|
||||
ord = ord || rcd[i];
|
||||
|
||||
#pragma omp parallel for simd reduction(||: orfc)
|
||||
for (int i=0; i < N; ++i)
|
||||
orfc = orfc || rcf[i];
|
||||
|
||||
#pragma omp parallel loop reduction(||: ordc)
|
||||
for (int i=0; i < N; ++i)
|
||||
ordc = ordc || rcd[i];
|
||||
|
||||
return orf + ord + __real__ orfc + __real__ ordc;
|
||||
}
|
||||
|
||||
int
|
||||
reduction_or_teams ()
|
||||
{
|
||||
float orf = 0;
|
||||
double ord = 0;
|
||||
_Complex float orfc = 0;
|
||||
_Complex double ordc = 0;
|
||||
|
||||
#pragma omp teams distribute parallel for reduction(||: orf)
|
||||
for (int i=0; i < N; ++i)
|
||||
orf = orf || rf[i];
|
||||
|
||||
#pragma omp teams distribute parallel for simd reduction(||: ord)
|
||||
for (int i=0; i < N; ++i)
|
||||
ord = ord || rcd[i];
|
||||
|
||||
#pragma omp teams distribute parallel for reduction(||: orfc)
|
||||
for (int i=0; i < N; ++i)
|
||||
orfc = orfc || rcf[i];
|
||||
|
||||
#pragma omp teams distribute parallel for simd reduction(||: ordc)
|
||||
for (int i=0; i < N; ++i)
|
||||
ordc = ordc || rcd[i];
|
||||
|
||||
return orf + ord + __real__ orfc + __real__ ordc;
|
||||
}
|
||||
|
||||
int
|
||||
reduction_and ()
|
||||
{
|
||||
float andf = 1;
|
||||
double andd = 1;
|
||||
_Complex float andfc = 1;
|
||||
_Complex double anddc = 1;
|
||||
|
||||
#pragma omp parallel reduction(&&: andf)
|
||||
for (int i=0; i < N; ++i)
|
||||
andf = andf && rf[i];
|
||||
|
||||
#pragma omp parallel for reduction(&&: andd)
|
||||
for (int i=0; i < N; ++i)
|
||||
andd = andd && rcd[i];
|
||||
|
||||
#pragma omp parallel for simd reduction(&&: andfc)
|
||||
for (int i=0; i < N; ++i)
|
||||
andfc = andfc && rcf[i];
|
||||
|
||||
#pragma omp parallel loop reduction(&&: anddc)
|
||||
for (int i=0; i < N; ++i)
|
||||
anddc = anddc && rcd[i];
|
||||
|
||||
return andf + andd + __real__ andfc + __real__ anddc;
|
||||
}
|
||||
|
||||
int
|
||||
reduction_and_teams ()
|
||||
{
|
||||
float andf = 1;
|
||||
double andd = 1;
|
||||
_Complex float andfc = 1;
|
||||
_Complex double anddc = 1;
|
||||
|
||||
#pragma omp teams distribute parallel for reduction(&&: andf)
|
||||
for (int i=0; i < N; ++i)
|
||||
andf = andf && rf[i];
|
||||
|
||||
#pragma omp teams distribute parallel for simd reduction(&&: andd)
|
||||
for (int i=0; i < N; ++i)
|
||||
andd = andd && rcd[i];
|
||||
|
||||
#pragma omp teams distribute parallel for reduction(&&: andfc)
|
||||
for (int i=0; i < N; ++i)
|
||||
andfc = andfc && rcf[i];
|
||||
|
||||
#pragma omp teams distribute parallel for simd reduction(&&: anddc)
|
||||
for (int i=0; i < N; ++i)
|
||||
anddc = anddc && rcd[i];
|
||||
|
||||
return andf + andd + __real__ andfc + __real__ anddc;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
rf[i] = 0;
|
||||
rd[i] = 0;
|
||||
rcf[i] = 0;
|
||||
rcd[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 ();
|
||||
|
||||
rf[10] = 1;
|
||||
rd[15] = 1;
|
||||
rcf[10] = 1;
|
||||
rcd[15] = 1;
|
||||
|
||||
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)
|
||||
{
|
||||
rf[i] = 1;
|
||||
rd[i] = 1;
|
||||
rcf[i] = 1;
|
||||
rcd[i] = 1;
|
||||
}
|
||||
|
||||
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 ();
|
||||
|
||||
rf[10] = 0;
|
||||
rd[15] = 0;
|
||||
rcf[10] = 0;
|
||||
rcd[15] = 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;
|
||||
}
|
192
libgomp/testsuite/libgomp.c-c++-common/reduction-3.c
Normal file
192
libgomp/testsuite/libgomp.c-c++-common/reduction-3.c
Normal file
@ -0,0 +1,192 @@
|
||||
/* 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 a floating-poing
|
||||
or complex type.
|
||||
|
||||
While having a floating-point/complex array element with || and && can make
|
||||
sense, having a non-integer/non-bool reduction variable is odd but valid.
|
||||
|
||||
Test: integer reduction variable + FP array. */
|
||||
|
||||
#define N 1024
|
||||
_Complex float rcf[N];
|
||||
_Complex double rcd[N];
|
||||
float rf[N];
|
||||
double rd[N];
|
||||
|
||||
int
|
||||
reduction_or ()
|
||||
{
|
||||
char orf = 0;
|
||||
short ord = 0;
|
||||
int orfc = 0;
|
||||
long ordc = 0;
|
||||
|
||||
#pragma omp parallel reduction(||: orf)
|
||||
for (int i=0; i < N; ++i)
|
||||
orf = orf || rf[i];
|
||||
|
||||
#pragma omp parallel for reduction(||: ord)
|
||||
for (int i=0; i < N; ++i)
|
||||
ord = ord || rcd[i];
|
||||
|
||||
#pragma omp parallel for simd reduction(||: orfc)
|
||||
for (int i=0; i < N; ++i)
|
||||
orfc = orfc || rcf[i];
|
||||
|
||||
#pragma omp parallel loop reduction(||: ordc)
|
||||
for (int i=0; i < N; ++i)
|
||||
ordc = ordc || rcd[i];
|
||||
|
||||
return orf + ord + __real__ orfc + __real__ ordc;
|
||||
}
|
||||
|
||||
int
|
||||
reduction_or_teams ()
|
||||
{
|
||||
char orf = 0;
|
||||
short ord = 0;
|
||||
int orfc = 0;
|
||||
long ordc = 0;
|
||||
|
||||
#pragma omp teams distribute parallel for reduction(||: orf)
|
||||
for (int i=0; i < N; ++i)
|
||||
orf = orf || rf[i];
|
||||
|
||||
#pragma omp teams distribute parallel for simd reduction(||: ord)
|
||||
for (int i=0; i < N; ++i)
|
||||
ord = ord || rcd[i];
|
||||
|
||||
#pragma omp teams distribute parallel for reduction(||: orfc)
|
||||
for (int i=0; i < N; ++i)
|
||||
orfc = orfc || rcf[i];
|
||||
|
||||
#pragma omp teams distribute parallel for simd reduction(||: ordc)
|
||||
for (int i=0; i < N; ++i)
|
||||
ordc = ordc || rcd[i];
|
||||
|
||||
return orf + ord + __real__ orfc + __real__ ordc;
|
||||
}
|
||||
|
||||
int
|
||||
reduction_and ()
|
||||
{
|
||||
unsigned char andf = 1;
|
||||
unsigned short andd = 1;
|
||||
unsigned int andfc = 1;
|
||||
unsigned long anddc = 1;
|
||||
|
||||
#pragma omp parallel reduction(&&: andf)
|
||||
for (int i=0; i < N; ++i)
|
||||
andf = andf && rf[i];
|
||||
|
||||
#pragma omp parallel for reduction(&&: andd)
|
||||
for (int i=0; i < N; ++i)
|
||||
andd = andd && rcd[i];
|
||||
|
||||
#pragma omp parallel for simd reduction(&&: andfc)
|
||||
for (int i=0; i < N; ++i)
|
||||
andfc = andfc && rcf[i];
|
||||
|
||||
#pragma omp parallel loop reduction(&&: anddc)
|
||||
for (int i=0; i < N; ++i)
|
||||
anddc = anddc && rcd[i];
|
||||
|
||||
return andf + andd + __real__ andfc + __real__ anddc;
|
||||
}
|
||||
|
||||
int
|
||||
reduction_and_teams ()
|
||||
{
|
||||
unsigned char andf = 1;
|
||||
unsigned short andd = 1;
|
||||
unsigned int andfc = 1;
|
||||
unsigned long anddc = 1;
|
||||
|
||||
#pragma omp teams distribute parallel for reduction(&&: andf)
|
||||
for (int i=0; i < N; ++i)
|
||||
andf = andf && rf[i];
|
||||
|
||||
#pragma omp teams distribute parallel for simd reduction(&&: andd)
|
||||
for (int i=0; i < N; ++i)
|
||||
andd = andd && rcd[i];
|
||||
|
||||
#pragma omp teams distribute parallel for reduction(&&: andfc)
|
||||
for (int i=0; i < N; ++i)
|
||||
andfc = andfc && rcf[i];
|
||||
|
||||
#pragma omp teams distribute parallel for simd reduction(&&: anddc)
|
||||
for (int i=0; i < N; ++i)
|
||||
anddc = anddc && rcd[i];
|
||||
|
||||
return andf + andd + __real__ andfc + __real__ anddc;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
rf[i] = 0;
|
||||
rd[i] = 0;
|
||||
rcf[i] = 0;
|
||||
rcd[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 ();
|
||||
|
||||
rf[10] = 1.0;
|
||||
rd[15] = 1.0;
|
||||
rcf[10] = 1.0;
|
||||
rcd[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)
|
||||
{
|
||||
rf[i] = 1;
|
||||
rd[i] = 1;
|
||||
rcf[i] = 1;
|
||||
rcd[i] = 1;
|
||||
}
|
||||
|
||||
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 ();
|
||||
|
||||
rf[10] = 0.0;
|
||||
rd[15] = 0.0;
|
||||
rcf[10] = 0.0;
|
||||
rcd[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;
|
||||
}
|
194
libgomp/testsuite/libgomp.c-c++-common/reduction-4.c
Normal file
194
libgomp/testsuite/libgomp.c-c++-common/reduction-4.c
Normal file
@ -0,0 +1,194 @@
|
||||
/* 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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user