tree-core.h (enum omp_clause_code): Add OMP_CLAUSE__SCANTEMP_ clause.
* tree-core.h (enum omp_clause_code): Add OMP_CLAUSE__SCANTEMP_ clause. * tree.h (OMP_CLAUSE_DECL): Use OMP_CLAUSE__SCANTEMP_ instead of OMP_CLAUSE__CONDTEMP_ as range's upper bound. (OMP_CLAUSE__SCANTEMP__ALLOC, OMP_CLAUSE__SCANTEMP__CONTROL): Define. * tree.c (omp_clause_num_ops, omp_clause_code_name): Add OMP_CLAUSE__SCANTEMP_ entry. (walk_tree_1): Handle OMP_CLAUSE__SCANTEMP_. * tree-pretty-print.c (dump_omp_clause): Likewise. * tree-nested.c (convert_nonlocal_omp_clauses, convert_local_omp_clauses): Likewise. * omp-general.h (struct omp_for_data): Add have_scantemp and have_nonctrl_scantemp members. * omp-general.c (omp_extract_for_data): Initialize them. * omp-low.c (struct omp_context): Add scan_exclusive member. (scan_omp_1_stmt): Don't unnecessarily mask gimple_omp_for_kind result again with GF_OMP_FOR_KIND_MASK. Initialize also ctx->scan_exclusive. (lower_rec_simd_input_clauses): Use ctx->scan_exclusive instead of !ctx->scan_inclusive. (lower_rec_input_clauses): Simplify gimplification of dtors using gimplify_and_add. For non-is_simd test OMP_CLAUSE_REDUCTION_INSCAN rather than rvarp. Handle OMP_CLAUSE_REDUCTION_INSCAN in worksharing loops. Don't add barrier for reduction_omp_orig_ref if ctx->scan_??xclusive. (lower_reduction_clauses): Don't do anything for ctx->scan_??xclusive. (lower_omp_scan): Use ctx->scan_exclusive instead of !ctx->scan_inclusive. Handle worksharing loops with inscan reductions. Use new_vard != new_var instead of repeated omp_is_reference calls. (omp_find_scan, lower_omp_for_scan): New functions. (lower_omp_for): Call lower_omp_for_scan for worksharing loops with inscan reductions. * omp-expand.c (expand_omp_scantemp_alloc): New function. (expand_omp_for_static_nochunk): Handle fd->have_nonctrl_scantemp and fd->have_scantemp. * c-c++-common/gomp/scan-3.c (f1): Don't expect a sorry message. * c-c++-common/gomp/scan-5.c (foo): Likewise. * testsuite/libgomp.c++/scan-1.C: New test. * testsuite/libgomp.c++/scan-2.C: New test. * testsuite/libgomp.c++/scan-3.C: New test. * testsuite/libgomp.c++/scan-4.C: New test. * testsuite/libgomp.c++/scan-5.C: New test. * testsuite/libgomp.c++/scan-6.C: New test. * testsuite/libgomp.c++/scan-7.C: New test. * testsuite/libgomp.c++/scan-8.C: New test. * testsuite/libgomp.c/scan-1.c: New test. * testsuite/libgomp.c/scan-2.c: New test. * testsuite/libgomp.c/scan-3.c: New test. * testsuite/libgomp.c/scan-4.c: New test. * testsuite/libgomp.c/scan-5.c: New test. * testsuite/libgomp.c/scan-6.c: New test. * testsuite/libgomp.c/scan-7.c: New test. * testsuite/libgomp.c/scan-8.c: New test. From-SVN: r272958
This commit is contained in:
parent
83eb952208
commit
2f6bb511d1
30 changed files with 3264 additions and 142 deletions
|
@ -1,5 +1,42 @@
|
|||
2019-07-03 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* tree-core.h (enum omp_clause_code): Add OMP_CLAUSE__SCANTEMP_
|
||||
clause.
|
||||
* tree.h (OMP_CLAUSE_DECL): Use OMP_CLAUSE__SCANTEMP_ instead of
|
||||
OMP_CLAUSE__CONDTEMP_ as range's upper bound.
|
||||
(OMP_CLAUSE__SCANTEMP__ALLOC, OMP_CLAUSE__SCANTEMP__CONTROL): Define.
|
||||
* tree.c (omp_clause_num_ops, omp_clause_code_name): Add
|
||||
OMP_CLAUSE__SCANTEMP_ entry.
|
||||
(walk_tree_1): Handle OMP_CLAUSE__SCANTEMP_.
|
||||
* tree-pretty-print.c (dump_omp_clause): Likewise.
|
||||
* tree-nested.c (convert_nonlocal_omp_clauses,
|
||||
convert_local_omp_clauses): Likewise.
|
||||
* omp-general.h (struct omp_for_data): Add have_scantemp and
|
||||
have_nonctrl_scantemp members.
|
||||
* omp-general.c (omp_extract_for_data): Initialize them.
|
||||
* omp-low.c (struct omp_context): Add scan_exclusive member.
|
||||
(scan_omp_1_stmt): Don't unnecessarily mask gimple_omp_for_kind
|
||||
result again with GF_OMP_FOR_KIND_MASK. Initialize also
|
||||
ctx->scan_exclusive.
|
||||
(lower_rec_simd_input_clauses): Use ctx->scan_exclusive instead
|
||||
of !ctx->scan_inclusive.
|
||||
(lower_rec_input_clauses): Simplify gimplification of dtors using
|
||||
gimplify_and_add. For non-is_simd test OMP_CLAUSE_REDUCTION_INSCAN
|
||||
rather than rvarp. Handle OMP_CLAUSE_REDUCTION_INSCAN in worksharing
|
||||
loops. Don't add barrier for reduction_omp_orig_ref if
|
||||
ctx->scan_??xclusive.
|
||||
(lower_reduction_clauses): Don't do anything for ctx->scan_??xclusive.
|
||||
(lower_omp_scan): Use ctx->scan_exclusive instead
|
||||
of !ctx->scan_inclusive. Handle worksharing loops with inscan
|
||||
reductions. Use new_vard != new_var instead of repeated
|
||||
omp_is_reference calls.
|
||||
(omp_find_scan, lower_omp_for_scan): New functions.
|
||||
(lower_omp_for): Call lower_omp_for_scan for worksharing loops with
|
||||
inscan reductions.
|
||||
* omp-expand.c (expand_omp_scantemp_alloc): New function.
|
||||
(expand_omp_for_static_nochunk): Handle fd->have_nonctrl_scantemp
|
||||
and fd->have_scantemp.
|
||||
|
||||
* gimplify.c (gimplify_scan_omp_clauses): For inscan reductions
|
||||
on worksharing loop propagate it as shared clause to containing
|
||||
combined parallel.
|
||||
|
|
292
gcc/omp-expand.c
292
gcc/omp-expand.c
|
@ -3502,6 +3502,98 @@ expand_omp_for_generic (struct omp_region *region,
|
|||
}
|
||||
}
|
||||
|
||||
/* Helper function for expand_omp_for_static_nochunk. If PTR is NULL,
|
||||
compute needed allocation size. If !ALLOC of team allocations,
|
||||
if ALLOC of thread allocation. SZ is the initial needed size for
|
||||
other purposes, ALLOC_ALIGN guaranteed alignment of allocation in bytes,
|
||||
CNT number of elements of each array, for !ALLOC this is
|
||||
omp_get_num_threads (), for ALLOC number of iterations handled by the
|
||||
current thread. If PTR is non-NULL, it is the start of the allocation
|
||||
and this routine shall assign to OMP_CLAUSE_DECL (c) of those _scantemp_
|
||||
clauses pointers to the corresponding arrays. */
|
||||
|
||||
static tree
|
||||
expand_omp_scantemp_alloc (tree clauses, tree ptr, unsigned HOST_WIDE_INT sz,
|
||||
unsigned HOST_WIDE_INT alloc_align, tree cnt,
|
||||
gimple_stmt_iterator *gsi, bool alloc)
|
||||
{
|
||||
tree eltsz = NULL_TREE;
|
||||
unsigned HOST_WIDE_INT preval = 0;
|
||||
if (ptr && sz)
|
||||
ptr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr),
|
||||
ptr, size_int (sz));
|
||||
for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
|
||||
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE__SCANTEMP_
|
||||
&& !OMP_CLAUSE__SCANTEMP__CONTROL (c)
|
||||
&& (!OMP_CLAUSE__SCANTEMP__ALLOC (c)) != alloc)
|
||||
{
|
||||
tree pointee_type = TREE_TYPE (TREE_TYPE (OMP_CLAUSE_DECL (c)));
|
||||
unsigned HOST_WIDE_INT al = TYPE_ALIGN_UNIT (pointee_type);
|
||||
if (tree_fits_uhwi_p (TYPE_SIZE_UNIT (pointee_type)))
|
||||
{
|
||||
unsigned HOST_WIDE_INT szl
|
||||
= tree_to_uhwi (TYPE_SIZE_UNIT (pointee_type));
|
||||
szl = least_bit_hwi (szl);
|
||||
if (szl)
|
||||
al = MIN (al, szl);
|
||||
}
|
||||
if (ptr == NULL_TREE)
|
||||
{
|
||||
if (eltsz == NULL_TREE)
|
||||
eltsz = TYPE_SIZE_UNIT (pointee_type);
|
||||
else
|
||||
eltsz = size_binop (PLUS_EXPR, eltsz,
|
||||
TYPE_SIZE_UNIT (pointee_type));
|
||||
}
|
||||
if (preval == 0 && al <= alloc_align)
|
||||
{
|
||||
unsigned HOST_WIDE_INT diff = ROUND_UP (sz, al) - sz;
|
||||
sz += diff;
|
||||
if (diff && ptr)
|
||||
ptr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr),
|
||||
ptr, size_int (diff));
|
||||
}
|
||||
else if (al > preval)
|
||||
{
|
||||
if (ptr)
|
||||
{
|
||||
ptr = fold_convert (pointer_sized_int_node, ptr);
|
||||
ptr = fold_build2 (PLUS_EXPR, pointer_sized_int_node, ptr,
|
||||
build_int_cst (pointer_sized_int_node,
|
||||
al - 1));
|
||||
ptr = fold_build2 (BIT_AND_EXPR, pointer_sized_int_node, ptr,
|
||||
build_int_cst (pointer_sized_int_node,
|
||||
-(HOST_WIDE_INT) al));
|
||||
ptr = fold_convert (ptr_type_node, ptr);
|
||||
}
|
||||
else
|
||||
sz += al - 1;
|
||||
}
|
||||
if (tree_fits_uhwi_p (TYPE_SIZE_UNIT (pointee_type)))
|
||||
preval = al;
|
||||
else
|
||||
preval = 1;
|
||||
if (ptr)
|
||||
{
|
||||
expand_omp_build_assign (gsi, OMP_CLAUSE_DECL (c), ptr, false);
|
||||
ptr = OMP_CLAUSE_DECL (c);
|
||||
ptr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr,
|
||||
size_binop (MULT_EXPR, cnt,
|
||||
TYPE_SIZE_UNIT (pointee_type)));
|
||||
}
|
||||
}
|
||||
|
||||
if (ptr == NULL_TREE)
|
||||
{
|
||||
eltsz = size_binop (MULT_EXPR, eltsz, cnt);
|
||||
if (sz)
|
||||
eltsz = size_binop (PLUS_EXPR, eltsz, size_int (sz));
|
||||
return eltsz;
|
||||
}
|
||||
else
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* A subroutine of expand_omp_for. Generate code for a parallel
|
||||
loop with static schedule and no specified chunk size. Given
|
||||
parameters:
|
||||
|
@ -3544,11 +3636,12 @@ expand_omp_for_static_nochunk (struct omp_region *region,
|
|||
struct omp_for_data *fd,
|
||||
gimple *inner_stmt)
|
||||
{
|
||||
tree n, q, s0, e0, e, t, tt, nthreads, threadid;
|
||||
tree n, q, s0, e0, e, t, tt, nthreads = NULL_TREE, threadid;
|
||||
tree type, itype, vmain, vback;
|
||||
basic_block entry_bb, second_bb, third_bb, exit_bb, seq_start_bb;
|
||||
basic_block body_bb, cont_bb, collapse_bb = NULL;
|
||||
basic_block fin_bb;
|
||||
basic_block fin_bb, fourth_bb = NULL, fifth_bb = NULL, sixth_bb = NULL;
|
||||
basic_block exit1_bb = NULL, exit2_bb = NULL, exit3_bb = NULL;
|
||||
gimple_stmt_iterator gsi, gsip;
|
||||
edge ep;
|
||||
bool broken_loop = region->cont == NULL;
|
||||
|
@ -3650,7 +3743,9 @@ expand_omp_for_static_nochunk (struct omp_region *region,
|
|||
c = omp_find_clause (OMP_CLAUSE_CHAIN (c), OMP_CLAUSE__CONDTEMP_);
|
||||
cond_var = OMP_CLAUSE_DECL (c);
|
||||
}
|
||||
if (fd->have_reductemp || fd->have_pointer_condtemp)
|
||||
if (fd->have_reductemp
|
||||
|| fd->have_pointer_condtemp
|
||||
|| fd->have_nonctrl_scantemp)
|
||||
{
|
||||
tree t1 = build_int_cst (long_integer_type_node, 0);
|
||||
tree t2 = build_int_cst (long_integer_type_node, 1);
|
||||
|
@ -3660,8 +3755,11 @@ expand_omp_for_static_nochunk (struct omp_region *region,
|
|||
gimple_stmt_iterator gsi2 = gsi_none ();
|
||||
gimple *g = NULL;
|
||||
tree mem = null_pointer_node, memv = NULL_TREE;
|
||||
unsigned HOST_WIDE_INT condtemp_sz = 0;
|
||||
unsigned HOST_WIDE_INT alloc_align = 0;
|
||||
if (fd->have_reductemp)
|
||||
{
|
||||
gcc_assert (!fd->have_nonctrl_scantemp);
|
||||
tree c = omp_find_clause (clauses, OMP_CLAUSE__REDUCTEMP_);
|
||||
reductions = OMP_CLAUSE_DECL (c);
|
||||
gcc_assert (TREE_CODE (reductions) == SSA_NAME);
|
||||
|
@ -3678,16 +3776,40 @@ expand_omp_for_static_nochunk (struct omp_region *region,
|
|||
gsi2 = gsip;
|
||||
reductions = null_pointer_node;
|
||||
}
|
||||
if (fd->have_pointer_condtemp)
|
||||
if (fd->have_pointer_condtemp || fd->have_nonctrl_scantemp)
|
||||
{
|
||||
tree type = TREE_TYPE (condtemp);
|
||||
tree type;
|
||||
if (fd->have_pointer_condtemp)
|
||||
type = TREE_TYPE (condtemp);
|
||||
else
|
||||
type = ptr_type_node;
|
||||
memv = create_tmp_var (type);
|
||||
TREE_ADDRESSABLE (memv) = 1;
|
||||
unsigned HOST_WIDE_INT sz
|
||||
= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type)));
|
||||
sz *= fd->lastprivate_conditional;
|
||||
expand_omp_build_assign (&gsi2, memv, build_int_cst (type, sz),
|
||||
false);
|
||||
unsigned HOST_WIDE_INT sz = 0;
|
||||
tree size = NULL_TREE;
|
||||
if (fd->have_pointer_condtemp)
|
||||
{
|
||||
sz = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type)));
|
||||
sz *= fd->lastprivate_conditional;
|
||||
condtemp_sz = sz;
|
||||
}
|
||||
if (fd->have_nonctrl_scantemp)
|
||||
{
|
||||
nthreads = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
|
||||
gimple *g = gimple_build_call (nthreads, 0);
|
||||
nthreads = create_tmp_var (integer_type_node);
|
||||
gimple_call_set_lhs (g, nthreads);
|
||||
gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
|
||||
nthreads = fold_convert (sizetype, nthreads);
|
||||
alloc_align = TYPE_ALIGN_UNIT (long_long_integer_type_node);
|
||||
size = expand_omp_scantemp_alloc (clauses, NULL_TREE, sz,
|
||||
alloc_align, nthreads, NULL,
|
||||
false);
|
||||
size = fold_convert (type, size);
|
||||
}
|
||||
else
|
||||
size = build_int_cst (type, sz);
|
||||
expand_omp_build_assign (&gsi2, memv, size, false);
|
||||
mem = build_fold_addr_expr (memv);
|
||||
}
|
||||
tree t
|
||||
|
@ -3698,6 +3820,12 @@ expand_omp_for_static_nochunk (struct omp_region *region,
|
|||
true, GSI_SAME_STMT);
|
||||
if (fd->have_pointer_condtemp)
|
||||
expand_omp_build_assign (&gsi2, condtemp, memv, false);
|
||||
if (fd->have_nonctrl_scantemp)
|
||||
{
|
||||
tree ptr = fd->have_pointer_condtemp ? condtemp : memv;
|
||||
expand_omp_scantemp_alloc (clauses, ptr, condtemp_sz,
|
||||
alloc_align, nthreads, &gsi2, false);
|
||||
}
|
||||
if (fd->have_reductemp)
|
||||
{
|
||||
gsi_remove (&gsi2, true);
|
||||
|
@ -3788,6 +3916,72 @@ expand_omp_for_static_nochunk (struct omp_region *region,
|
|||
gsi = gsi_last_nondebug_bb (third_bb);
|
||||
gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
|
||||
|
||||
if (fd->have_nonctrl_scantemp)
|
||||
{
|
||||
tree clauses = gimple_omp_for_clauses (fd->for_stmt);
|
||||
tree controlp = NULL_TREE, controlb = NULL_TREE;
|
||||
for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
|
||||
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE__SCANTEMP_
|
||||
&& OMP_CLAUSE__SCANTEMP__CONTROL (c))
|
||||
{
|
||||
if (TREE_TYPE (OMP_CLAUSE_DECL (c)) == boolean_type_node)
|
||||
controlb = OMP_CLAUSE_DECL (c);
|
||||
else
|
||||
controlp = OMP_CLAUSE_DECL (c);
|
||||
if (controlb && controlp)
|
||||
break;
|
||||
}
|
||||
gcc_assert (controlp && controlb);
|
||||
tree cnt = create_tmp_var (sizetype);
|
||||
gimple *g = gimple_build_assign (cnt, NOP_EXPR, q);
|
||||
gsi_insert_before (&gsi, g, GSI_SAME_STMT);
|
||||
unsigned HOST_WIDE_INT alloc_align = TYPE_ALIGN_UNIT (ptr_type_node);
|
||||
tree sz = expand_omp_scantemp_alloc (clauses, NULL_TREE, 0,
|
||||
alloc_align, cnt, NULL, true);
|
||||
tree size = create_tmp_var (sizetype);
|
||||
expand_omp_build_assign (&gsi, size, sz, false);
|
||||
tree cmp = fold_build2 (GT_EXPR, boolean_type_node,
|
||||
size, size_int (16384));
|
||||
expand_omp_build_assign (&gsi, controlb, cmp);
|
||||
g = gimple_build_cond (NE_EXPR, controlb, boolean_false_node,
|
||||
NULL_TREE, NULL_TREE);
|
||||
gsi_insert_before (&gsi, g, GSI_SAME_STMT);
|
||||
fourth_bb = split_block (third_bb, g)->dest;
|
||||
gsi = gsi_last_nondebug_bb (fourth_bb);
|
||||
/* FIXME: Once we have allocators, this should use allocator. */
|
||||
g = gimple_build_call (builtin_decl_explicit (BUILT_IN_MALLOC), 1, size);
|
||||
gimple_call_set_lhs (g, controlp);
|
||||
gsi_insert_before (&gsi, g, GSI_SAME_STMT);
|
||||
expand_omp_scantemp_alloc (clauses, controlp, 0, alloc_align, cnt,
|
||||
&gsi, true);
|
||||
gsi_prev (&gsi);
|
||||
g = gsi_stmt (gsi);
|
||||
fifth_bb = split_block (fourth_bb, g)->dest;
|
||||
gsi = gsi_last_nondebug_bb (fifth_bb);
|
||||
|
||||
g = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
|
||||
gimple_call_set_lhs (g, controlp);
|
||||
gsi_insert_before (&gsi, g, GSI_SAME_STMT);
|
||||
tree alloca_decl = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
|
||||
for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
|
||||
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE__SCANTEMP_
|
||||
&& OMP_CLAUSE__SCANTEMP__ALLOC (c))
|
||||
{
|
||||
tree tmp = create_tmp_var (sizetype);
|
||||
tree pointee_type = TREE_TYPE (TREE_TYPE (OMP_CLAUSE_DECL (c)));
|
||||
g = gimple_build_assign (tmp, MULT_EXPR, cnt,
|
||||
TYPE_SIZE_UNIT (pointee_type));
|
||||
gsi_insert_before (&gsi, g, GSI_SAME_STMT);
|
||||
g = gimple_build_call (alloca_decl, 2, tmp,
|
||||
size_int (TYPE_ALIGN (pointee_type)));
|
||||
gimple_call_set_lhs (g, OMP_CLAUSE_DECL (c));
|
||||
gsi_insert_before (&gsi, g, GSI_SAME_STMT);
|
||||
}
|
||||
|
||||
sixth_bb = split_block (fifth_bb, g)->dest;
|
||||
gsi = gsi_last_nondebug_bb (sixth_bb);
|
||||
}
|
||||
|
||||
t = build2 (MULT_EXPR, itype, q, threadid);
|
||||
t = build2 (PLUS_EXPR, itype, t, tt);
|
||||
s0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
|
||||
|
@ -4018,7 +4212,9 @@ expand_omp_for_static_nochunk (struct omp_region *region,
|
|||
if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
|
||||
{
|
||||
t = gimple_omp_return_lhs (gsi_stmt (gsi));
|
||||
if (fd->have_reductemp || fd->have_pointer_condtemp)
|
||||
if (fd->have_reductemp
|
||||
|| ((fd->have_pointer_condtemp || fd->have_scantemp)
|
||||
&& !fd->have_nonctrl_scantemp))
|
||||
{
|
||||
tree fn;
|
||||
if (t)
|
||||
|
@ -4045,6 +4241,38 @@ expand_omp_for_static_nochunk (struct omp_region *region,
|
|||
gcall *g = gimple_build_call (fn, 0);
|
||||
gsi_insert_after (&gsi, g, GSI_SAME_STMT);
|
||||
}
|
||||
if (fd->have_scantemp && !fd->have_nonctrl_scantemp)
|
||||
{
|
||||
tree clauses = gimple_omp_for_clauses (fd->for_stmt);
|
||||
tree controlp = NULL_TREE, controlb = NULL_TREE;
|
||||
for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
|
||||
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE__SCANTEMP_
|
||||
&& OMP_CLAUSE__SCANTEMP__CONTROL (c))
|
||||
{
|
||||
if (TREE_TYPE (OMP_CLAUSE_DECL (c)) == boolean_type_node)
|
||||
controlb = OMP_CLAUSE_DECL (c);
|
||||
else
|
||||
controlp = OMP_CLAUSE_DECL (c);
|
||||
if (controlb && controlp)
|
||||
break;
|
||||
}
|
||||
gcc_assert (controlp && controlb);
|
||||
gimple *g = gimple_build_cond (NE_EXPR, controlb, boolean_false_node,
|
||||
NULL_TREE, NULL_TREE);
|
||||
gsi_insert_before (&gsi, g, GSI_SAME_STMT);
|
||||
exit1_bb = split_block (exit_bb, g)->dest;
|
||||
gsi = gsi_after_labels (exit1_bb);
|
||||
g = gimple_build_call (builtin_decl_explicit (BUILT_IN_FREE), 1,
|
||||
controlp);
|
||||
gsi_insert_before (&gsi, g, GSI_SAME_STMT);
|
||||
exit2_bb = split_block (exit1_bb, g)->dest;
|
||||
gsi = gsi_after_labels (exit2_bb);
|
||||
g = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE), 1,
|
||||
controlp);
|
||||
gsi_insert_before (&gsi, g, GSI_SAME_STMT);
|
||||
exit3_bb = split_block (exit2_bb, g)->dest;
|
||||
gsi = gsi_after_labels (exit3_bb);
|
||||
}
|
||||
gsi_remove (&gsi, true);
|
||||
|
||||
/* Connect all the blocks. */
|
||||
|
@ -4053,8 +4281,34 @@ expand_omp_for_static_nochunk (struct omp_region *region,
|
|||
ep = find_edge (entry_bb, second_bb);
|
||||
ep->flags = EDGE_TRUE_VALUE;
|
||||
ep->probability = profile_probability::guessed_always ().apply_scale (1, 4);
|
||||
find_edge (third_bb, seq_start_bb)->flags = EDGE_FALSE_VALUE;
|
||||
find_edge (third_bb, fin_bb)->flags = EDGE_TRUE_VALUE;
|
||||
if (fourth_bb)
|
||||
{
|
||||
ep = make_edge (third_bb, fifth_bb, EDGE_FALSE_VALUE);
|
||||
ep->probability
|
||||
= profile_probability::guessed_always ().apply_scale (1, 2);
|
||||
ep = find_edge (third_bb, fourth_bb);
|
||||
ep->flags = EDGE_TRUE_VALUE;
|
||||
ep->probability
|
||||
= profile_probability::guessed_always ().apply_scale (1, 2);
|
||||
ep = find_edge (fourth_bb, fifth_bb);
|
||||
redirect_edge_and_branch (ep, sixth_bb);
|
||||
}
|
||||
else
|
||||
sixth_bb = third_bb;
|
||||
find_edge (sixth_bb, seq_start_bb)->flags = EDGE_FALSE_VALUE;
|
||||
find_edge (sixth_bb, fin_bb)->flags = EDGE_TRUE_VALUE;
|
||||
if (exit1_bb)
|
||||
{
|
||||
ep = make_edge (exit_bb, exit2_bb, EDGE_FALSE_VALUE);
|
||||
ep->probability
|
||||
= profile_probability::guessed_always ().apply_scale (1, 2);
|
||||
ep = find_edge (exit_bb, exit1_bb);
|
||||
ep->flags = EDGE_TRUE_VALUE;
|
||||
ep->probability
|
||||
= profile_probability::guessed_always ().apply_scale (1, 2);
|
||||
ep = find_edge (exit1_bb, exit2_bb);
|
||||
redirect_edge_and_branch (ep, exit3_bb);
|
||||
}
|
||||
|
||||
if (!broken_loop)
|
||||
{
|
||||
|
@ -4082,12 +4336,22 @@ expand_omp_for_static_nochunk (struct omp_region *region,
|
|||
|
||||
set_immediate_dominator (CDI_DOMINATORS, second_bb, entry_bb);
|
||||
set_immediate_dominator (CDI_DOMINATORS, third_bb, entry_bb);
|
||||
set_immediate_dominator (CDI_DOMINATORS, seq_start_bb, third_bb);
|
||||
if (fourth_bb)
|
||||
{
|
||||
set_immediate_dominator (CDI_DOMINATORS, fifth_bb, third_bb);
|
||||
set_immediate_dominator (CDI_DOMINATORS, sixth_bb, third_bb);
|
||||
}
|
||||
set_immediate_dominator (CDI_DOMINATORS, seq_start_bb, sixth_bb);
|
||||
|
||||
set_immediate_dominator (CDI_DOMINATORS, body_bb,
|
||||
recompute_dominator (CDI_DOMINATORS, body_bb));
|
||||
set_immediate_dominator (CDI_DOMINATORS, fin_bb,
|
||||
recompute_dominator (CDI_DOMINATORS, fin_bb));
|
||||
if (exit1_bb)
|
||||
{
|
||||
set_immediate_dominator (CDI_DOMINATORS, exit2_bb, exit_bb);
|
||||
set_immediate_dominator (CDI_DOMINATORS, exit3_bb, exit_bb);
|
||||
}
|
||||
|
||||
struct loop *loop = body_bb->loop_father;
|
||||
if (loop != entry_bb->loop_father)
|
||||
|
|
|
@ -169,6 +169,8 @@ omp_extract_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
|
|||
fd->have_ordered = false;
|
||||
fd->have_reductemp = false;
|
||||
fd->have_pointer_condtemp = false;
|
||||
fd->have_scantemp = false;
|
||||
fd->have_nonctrl_scantemp = false;
|
||||
fd->lastprivate_conditional = 0;
|
||||
fd->tiling = NULL_TREE;
|
||||
fd->collapse = 1;
|
||||
|
@ -231,6 +233,12 @@ omp_extract_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
|
|||
if (POINTER_TYPE_P (TREE_TYPE (OMP_CLAUSE_DECL (t))))
|
||||
fd->have_pointer_condtemp = true;
|
||||
break;
|
||||
case OMP_CLAUSE__SCANTEMP_:
|
||||
fd->have_scantemp = true;
|
||||
if (!OMP_CLAUSE__SCANTEMP__ALLOC (t)
|
||||
&& !OMP_CLAUSE__SCANTEMP__CONTROL (t))
|
||||
fd->have_nonctrl_scantemp = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ struct omp_for_data
|
|||
int collapse; /* Collapsed loops, 1 for a non-collapsed loop. */
|
||||
int ordered;
|
||||
bool have_nowait, have_ordered, simd_schedule, have_reductemp;
|
||||
bool have_pointer_condtemp;
|
||||
bool have_pointer_condtemp, have_scantemp, have_nonctrl_scantemp;
|
||||
int lastprivate_conditional;
|
||||
unsigned char sched_modifiers;
|
||||
enum omp_clause_schedule_kind sched_kind;
|
||||
|
|
939
gcc/omp-low.c
939
gcc/omp-low.c
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,8 @@
|
|||
2019-07-03 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* c-c++-common/gomp/scan-3.c (f1): Don't expect a sorry message.
|
||||
* c-c++-common/gomp/scan-5.c (foo): Likewise.
|
||||
|
||||
* c-c++-common/gomp/scan-5.c: New test.
|
||||
|
||||
* c-c++-common/gomp/lastprivate-conditional-5.c: New test.
|
||||
|
|
|
@ -8,7 +8,7 @@ f1 (int *c, int *d)
|
|||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
d[i] = a;
|
||||
#pragma omp scan inclusive (a) /* { dg-message "sorry, unimplemented: '#pragma omp scan' not supported yet" } */
|
||||
#pragma omp scan inclusive (a)
|
||||
a += c[i];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ foo (int *a, int *b)
|
|||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
r += a[i];
|
||||
#pragma omp scan inclusive (r) /* { dg-message "sorry, unimplemented: '#pragma omp scan' not supported yet" } */
|
||||
#pragma omp scan inclusive (r)
|
||||
b[i] = r;
|
||||
}
|
||||
return r;
|
||||
|
|
|
@ -352,6 +352,9 @@ enum omp_clause_code {
|
|||
/* Internal clause: temporary for lastprivate(conditional:). */
|
||||
OMP_CLAUSE__CONDTEMP_,
|
||||
|
||||
/* Internal clause: temporary for inscan reductions. */
|
||||
OMP_CLAUSE__SCANTEMP_,
|
||||
|
||||
/* OpenACC/OpenMP clause: if (scalar-expression). */
|
||||
OMP_CLAUSE_IF,
|
||||
|
||||
|
|
|
@ -1349,6 +1349,7 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
|
|||
case OMP_CLAUSE_IF_PRESENT:
|
||||
case OMP_CLAUSE_FINALIZE:
|
||||
case OMP_CLAUSE__CONDTEMP_:
|
||||
case OMP_CLAUSE__SCANTEMP_:
|
||||
break;
|
||||
|
||||
/* The following clause belongs to the OpenACC cache directive, which
|
||||
|
@ -2078,6 +2079,7 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
|
|||
case OMP_CLAUSE_IF_PRESENT:
|
||||
case OMP_CLAUSE_FINALIZE:
|
||||
case OMP_CLAUSE__CONDTEMP_:
|
||||
case OMP_CLAUSE__SCANTEMP_:
|
||||
break;
|
||||
|
||||
/* The following clause belongs to the OpenACC cache directive, which
|
||||
|
|
|
@ -483,6 +483,9 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
|
|||
case OMP_CLAUSE__CONDTEMP_:
|
||||
name = "_condtemp_";
|
||||
goto print_remap;
|
||||
case OMP_CLAUSE__SCANTEMP_:
|
||||
name = "_scantemp_";
|
||||
goto print_remap;
|
||||
case OMP_CLAUSE_TO_DECLARE:
|
||||
name = "to";
|
||||
goto print_remap;
|
||||
|
|
|
@ -311,6 +311,7 @@ unsigned const char omp_clause_num_ops[] =
|
|||
1, /* OMP_CLAUSE__LOOPTEMP_ */
|
||||
1, /* OMP_CLAUSE__REDUCTEMP_ */
|
||||
1, /* OMP_CLAUSE__CONDTEMP_ */
|
||||
1, /* OMP_CLAUSE__SCANTEMP_ */
|
||||
1, /* OMP_CLAUSE_IF */
|
||||
1, /* OMP_CLAUSE_NUM_THREADS */
|
||||
1, /* OMP_CLAUSE_SCHEDULE */
|
||||
|
@ -391,6 +392,7 @@ const char * const omp_clause_code_name[] =
|
|||
"_looptemp_",
|
||||
"_reductemp_",
|
||||
"_condtemp_",
|
||||
"_scantemp_",
|
||||
"if",
|
||||
"num_threads",
|
||||
"schedule",
|
||||
|
@ -12316,6 +12318,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
|
|||
case OMP_CLAUSE__LOOPTEMP_:
|
||||
case OMP_CLAUSE__REDUCTEMP_:
|
||||
case OMP_CLAUSE__CONDTEMP_:
|
||||
case OMP_CLAUSE__SCANTEMP_:
|
||||
case OMP_CLAUSE__SIMDUID_:
|
||||
WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 0));
|
||||
/* FALLTHRU */
|
||||
|
|
13
gcc/tree.h
13
gcc/tree.h
|
@ -1449,7 +1449,7 @@ class auto_suppress_location_wrappers
|
|||
#define OMP_CLAUSE_DECL(NODE) \
|
||||
OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (OMP_CLAUSE_CHECK (NODE), \
|
||||
OMP_CLAUSE_PRIVATE, \
|
||||
OMP_CLAUSE__CONDTEMP_), 0)
|
||||
OMP_CLAUSE__SCANTEMP_), 0)
|
||||
#define OMP_CLAUSE_HAS_LOCATION(NODE) \
|
||||
(LOCATION_LOCUS ((OMP_CLAUSE_CHECK (NODE))->omp_clause.locus) \
|
||||
!= UNKNOWN_LOCATION)
|
||||
|
@ -1761,6 +1761,17 @@ class auto_suppress_location_wrappers
|
|||
#define OMP_CLAUSE__CONDTEMP__ITER(NODE) \
|
||||
(OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE__CONDTEMP_)->base.public_flag)
|
||||
|
||||
/* _SCANTEMP_ holding temporary with pointer to thread's local array;
|
||||
allocation. */
|
||||
#define OMP_CLAUSE__SCANTEMP__ALLOC(NODE) \
|
||||
(OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE__SCANTEMP_)->base.public_flag)
|
||||
|
||||
/* _SCANTEMP_ holding temporary with a control variable for deallocation;
|
||||
one boolean_type_node for test whether alloca was used, another one
|
||||
to pass to __builtin_stack_restore or free. */
|
||||
#define OMP_CLAUSE__SCANTEMP__CONTROL(NODE) \
|
||||
TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE__SCANTEMP_))
|
||||
|
||||
/* SSA_NAME accessors. */
|
||||
|
||||
/* Whether SSA_NAME NODE is a virtual operand. This simply caches the
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
2019-07-03 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* testsuite/libgomp.c++/scan-1.C: New test.
|
||||
* testsuite/libgomp.c++/scan-2.C: New test.
|
||||
* testsuite/libgomp.c++/scan-3.C: New test.
|
||||
* testsuite/libgomp.c++/scan-4.C: New test.
|
||||
* testsuite/libgomp.c++/scan-5.C: New test.
|
||||
* testsuite/libgomp.c++/scan-6.C: New test.
|
||||
* testsuite/libgomp.c++/scan-7.C: New test.
|
||||
* testsuite/libgomp.c++/scan-8.C: New test.
|
||||
* testsuite/libgomp.c/scan-1.c: New test.
|
||||
* testsuite/libgomp.c/scan-2.c: New test.
|
||||
* testsuite/libgomp.c/scan-3.c: New test.
|
||||
* testsuite/libgomp.c/scan-4.c: New test.
|
||||
* testsuite/libgomp.c/scan-5.c: New test.
|
||||
* testsuite/libgomp.c/scan-6.c: New test.
|
||||
* testsuite/libgomp.c/scan-7.c: New test.
|
||||
* testsuite/libgomp.c/scan-8.c: New test.
|
||||
|
||||
2019-06-18 Thomas Schwinge <thomas@codesourcery.com>
|
||||
|
||||
* testsuite/libgomp.oacc-c++/firstprivate-mappings-1.C: New file.
|
||||
|
|
151
libgomp/testsuite/libgomp.c++/scan-1.C
Normal file
151
libgomp/testsuite/libgomp.c++/scan-1.C
Normal file
|
@ -0,0 +1,151 @@
|
|||
// { dg-require-effective-target size32plus }
|
||||
|
||||
extern "C" void abort ();
|
||||
|
||||
struct S {
|
||||
inline S ();
|
||||
inline ~S ();
|
||||
inline S (const S &);
|
||||
inline S & operator= (const S &);
|
||||
int s;
|
||||
};
|
||||
|
||||
S::S () : s (0)
|
||||
{
|
||||
}
|
||||
|
||||
S::~S ()
|
||||
{
|
||||
}
|
||||
|
||||
S::S (const S &x)
|
||||
{
|
||||
s = x.s;
|
||||
}
|
||||
|
||||
S &
|
||||
S::operator= (const S &x)
|
||||
{
|
||||
s = x.s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
static inline void
|
||||
ini (S &x)
|
||||
{
|
||||
x.s = 0;
|
||||
}
|
||||
|
||||
S r, a[1024], b[1024];
|
||||
|
||||
#pragma omp declare reduction (+: S: omp_out.s += omp_in.s)
|
||||
#pragma omp declare reduction (plus: S: omp_out.s += omp_in.s) initializer (ini (omp_priv))
|
||||
|
||||
__attribute__((noipa)) void
|
||||
foo (S *a, S *b)
|
||||
{
|
||||
#pragma omp for reduction (inscan, +:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
r.s += a[i].s;
|
||||
#pragma omp scan inclusive(r)
|
||||
b[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) S
|
||||
bar (void)
|
||||
{
|
||||
S s;
|
||||
#pragma omp parallel
|
||||
#pragma omp for reduction (inscan, plus:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
s.s += 2 * a[i].s;
|
||||
#pragma omp scan inclusive(s)
|
||||
b[i] = s;
|
||||
}
|
||||
return S (s);
|
||||
}
|
||||
|
||||
__attribute__((noipa)) void
|
||||
baz (S *a, S *b)
|
||||
{
|
||||
#pragma omp parallel for reduction (inscan, +:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
r.s += a[i].s;
|
||||
#pragma omp scan inclusive(r)
|
||||
b[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) S
|
||||
qux (void)
|
||||
{
|
||||
S s;
|
||||
#pragma omp parallel for reduction (inscan, plus:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
s.s += 2 * a[i].s;
|
||||
#pragma omp scan inclusive(s)
|
||||
b[i] = s;
|
||||
}
|
||||
return S (s);
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
S s;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
a[i].s = i;
|
||||
b[i].s = -1;
|
||||
asm ("" : "+g" (i));
|
||||
}
|
||||
#pragma omp parallel
|
||||
foo (a, b);
|
||||
if (r.s != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s.s += i;
|
||||
if (b[i].s != s.s)
|
||||
abort ();
|
||||
else
|
||||
b[i].s = 25;
|
||||
}
|
||||
if (bar ().s != 1024 * 1023)
|
||||
abort ();
|
||||
s.s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s.s += 2 * i;
|
||||
if (b[i].s != s.s)
|
||||
abort ();
|
||||
}
|
||||
r.s = 0;
|
||||
baz (a, b);
|
||||
if (r.s != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
s.s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s.s += i;
|
||||
if (b[i].s != s.s)
|
||||
abort ();
|
||||
else
|
||||
b[i].s = 25;
|
||||
}
|
||||
if (qux ().s != 1024 * 1023)
|
||||
abort ();
|
||||
s.s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s.s += 2 * i;
|
||||
if (b[i].s != s.s)
|
||||
abort ();
|
||||
}
|
||||
return 0;
|
||||
}
|
116
libgomp/testsuite/libgomp.c++/scan-2.C
Normal file
116
libgomp/testsuite/libgomp.c++/scan-2.C
Normal file
|
@ -0,0 +1,116 @@
|
|||
// { dg-require-effective-target size32plus }
|
||||
|
||||
extern "C" void abort ();
|
||||
int r, a[1024], b[1024], q;
|
||||
|
||||
__attribute__((noipa)) void
|
||||
foo (int *a, int *b, int &r)
|
||||
{
|
||||
#pragma omp for reduction (inscan, +:r) nowait
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
r += a[i];
|
||||
#pragma omp scan inclusive(r)
|
||||
b[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) int
|
||||
bar (void)
|
||||
{
|
||||
int &s = q;
|
||||
q = 0;
|
||||
#pragma omp parallel
|
||||
#pragma omp for reduction (inscan, +:s) nowait
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
s += 2 * a[i];
|
||||
#pragma omp scan inclusive(s)
|
||||
b[i] = s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
__attribute__((noipa)) void
|
||||
baz (int *a, int *b, int &r)
|
||||
{
|
||||
#pragma omp parallel for reduction (inscan, +:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
r += a[i];
|
||||
#pragma omp scan inclusive(r)
|
||||
b[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) int
|
||||
qux (void)
|
||||
{
|
||||
int &s = q;
|
||||
q = 0;
|
||||
#pragma omp parallel for reduction (inscan, +:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
s += 2 * a[i];
|
||||
#pragma omp scan inclusive(s)
|
||||
b[i] = s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
a[i] = i;
|
||||
b[i] = -1;
|
||||
asm ("" : "+g" (i));
|
||||
}
|
||||
#pragma omp parallel
|
||||
foo (a, b, r);
|
||||
if (r != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s += i;
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = 25;
|
||||
}
|
||||
if (bar () != 1024 * 1023)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s += 2 * i;
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = -1;
|
||||
}
|
||||
r = 0;
|
||||
baz (a, b, r);
|
||||
if (r != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s += i;
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = -25;
|
||||
}
|
||||
if (qux () != 1024 * 1023)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s += 2 * i;
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
}
|
||||
}
|
119
libgomp/testsuite/libgomp.c++/scan-3.C
Normal file
119
libgomp/testsuite/libgomp.c++/scan-3.C
Normal file
|
@ -0,0 +1,119 @@
|
|||
// { dg-require-effective-target size32plus }
|
||||
|
||||
extern "C" void abort ();
|
||||
int r, a[1024], b[1024], q;
|
||||
|
||||
#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
|
||||
|
||||
__attribute__((noipa)) void
|
||||
foo (int *a, int *b, int &r)
|
||||
{
|
||||
#pragma omp for reduction (inscan, foo:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
r += a[i];
|
||||
#pragma omp scan inclusive(r)
|
||||
b[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) int
|
||||
bar (void)
|
||||
{
|
||||
int &s = q;
|
||||
q = 0;
|
||||
#pragma omp parallel
|
||||
#pragma omp for reduction (inscan, foo:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
s += 2 * a[i];
|
||||
#pragma omp scan inclusive(s)
|
||||
b[i] = s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
__attribute__((noipa)) void
|
||||
baz (int *a, int *b, int &r)
|
||||
{
|
||||
#pragma omp parallel for reduction (inscan, foo:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
r += a[i];
|
||||
#pragma omp scan inclusive(r)
|
||||
b[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) int
|
||||
qux (void)
|
||||
{
|
||||
int &s = q;
|
||||
q = 0;
|
||||
#pragma omp parallel for reduction (inscan, foo:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
s += 2 * a[i];
|
||||
#pragma omp scan inclusive(s)
|
||||
b[i] = s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
a[i] = i;
|
||||
b[i] = -1;
|
||||
asm ("" : "+g" (i));
|
||||
}
|
||||
#pragma omp parallel
|
||||
foo (a, b, r);
|
||||
if (r != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s += i;
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = 25;
|
||||
}
|
||||
if (bar () != 1024 * 1023)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s += 2 * i;
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = -1;
|
||||
}
|
||||
r = 0;
|
||||
baz (a, b, r);
|
||||
if (r != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s += i;
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = -25;
|
||||
}
|
||||
if (qux () != 1024 * 1023)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s += 2 * i;
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
}
|
||||
return 0;
|
||||
}
|
150
libgomp/testsuite/libgomp.c++/scan-4.C
Normal file
150
libgomp/testsuite/libgomp.c++/scan-4.C
Normal file
|
@ -0,0 +1,150 @@
|
|||
// { dg-require-effective-target size32plus }
|
||||
|
||||
extern "C" void abort ();
|
||||
|
||||
struct S {
|
||||
inline S ();
|
||||
inline ~S ();
|
||||
inline S (const S &);
|
||||
inline S & operator= (const S &);
|
||||
int s;
|
||||
};
|
||||
|
||||
S::S () : s (0)
|
||||
{
|
||||
}
|
||||
|
||||
S::~S ()
|
||||
{
|
||||
}
|
||||
|
||||
S::S (const S &x)
|
||||
{
|
||||
s = x.s;
|
||||
}
|
||||
|
||||
S &
|
||||
S::operator= (const S &x)
|
||||
{
|
||||
s = x.s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
static inline void
|
||||
ini (S &x)
|
||||
{
|
||||
x.s = 0;
|
||||
}
|
||||
|
||||
S r, a[1024], b[1024];
|
||||
|
||||
#pragma omp declare reduction (+: S: omp_out.s += omp_in.s)
|
||||
#pragma omp declare reduction (plus: S: omp_out.s += omp_in.s) initializer (ini (omp_priv))
|
||||
|
||||
__attribute__((noipa)) void
|
||||
foo (S *a, S *b, S &r)
|
||||
{
|
||||
#pragma omp for reduction (inscan, +:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
r.s += a[i].s;
|
||||
#pragma omp scan inclusive(r)
|
||||
b[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) S
|
||||
bar ()
|
||||
{
|
||||
S s;
|
||||
#pragma omp parallel
|
||||
#pragma omp for reduction (inscan, plus:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
s.s += 2 * a[i].s;
|
||||
#pragma omp scan inclusive(s)
|
||||
b[i] = s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
__attribute__((noipa)) void
|
||||
baz (S *a, S *b, S &r)
|
||||
{
|
||||
#pragma omp parallel for reduction (inscan, +:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
r.s += a[i].s;
|
||||
#pragma omp scan inclusive(r)
|
||||
b[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) S
|
||||
qux ()
|
||||
{
|
||||
S s;
|
||||
#pragma omp parallel for reduction (inscan, plus:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
s.s += 2 * a[i].s;
|
||||
#pragma omp scan inclusive(s)
|
||||
b[i] = s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
S s;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
a[i].s = i;
|
||||
b[i].s = -1;
|
||||
asm ("" : "+g" (i));
|
||||
}
|
||||
#pragma omp parallel
|
||||
foo (a, b, r);
|
||||
if (r.s != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s.s += i;
|
||||
if (b[i].s != s.s)
|
||||
abort ();
|
||||
else
|
||||
b[i].s = 25;
|
||||
}
|
||||
if (bar ().s != 1024 * 1023)
|
||||
abort ();
|
||||
s.s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s.s += 2 * i;
|
||||
if (b[i].s != s.s)
|
||||
abort ();
|
||||
}
|
||||
r.s = 0;
|
||||
baz (a, b, r);
|
||||
if (r.s != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
s.s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s.s += i;
|
||||
if (b[i].s != s.s)
|
||||
abort ();
|
||||
else
|
||||
b[i].s = 25;
|
||||
}
|
||||
if (qux ().s != 1024 * 1023)
|
||||
abort ();
|
||||
s.s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s.s += 2 * i;
|
||||
if (b[i].s != s.s)
|
||||
abort ();
|
||||
}
|
||||
}
|
158
libgomp/testsuite/libgomp.c++/scan-5.C
Normal file
158
libgomp/testsuite/libgomp.c++/scan-5.C
Normal file
|
@ -0,0 +1,158 @@
|
|||
// { dg-require-effective-target size32plus }
|
||||
|
||||
extern "C" void abort ();
|
||||
|
||||
template <typename T>
|
||||
struct S {
|
||||
inline S ();
|
||||
inline ~S ();
|
||||
inline S (const S &);
|
||||
inline S & operator= (const S &);
|
||||
T s;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
S<T>::S () : s (0)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
S<T>::~S ()
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
S<T>::S (const S &x)
|
||||
{
|
||||
s = x.s;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
S<T> &
|
||||
S<T>::operator= (const S &x)
|
||||
{
|
||||
s = x.s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline void
|
||||
ini (S<T> &x)
|
||||
{
|
||||
x.s = 0;
|
||||
}
|
||||
|
||||
S<int> r, a[1024], b[1024];
|
||||
|
||||
#pragma omp declare reduction (+: S<int>: omp_out.s += omp_in.s)
|
||||
#pragma omp declare reduction (plus: S<int>: omp_out.s += omp_in.s) initializer (ini (omp_priv))
|
||||
|
||||
template <typename T>
|
||||
__attribute__((noipa)) void
|
||||
foo (S<T> *a, S<T> *b)
|
||||
{
|
||||
#pragma omp for reduction (inscan, +:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = r;
|
||||
#pragma omp scan exclusive(r)
|
||||
r.s += a[i].s;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
__attribute__((noipa)) S<T>
|
||||
bar (void)
|
||||
{
|
||||
S<T> s;
|
||||
#pragma omp parallel
|
||||
#pragma omp for reduction (inscan, plus:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = s;
|
||||
#pragma omp scan exclusive(s)
|
||||
s.s += 2 * a[i].s;
|
||||
}
|
||||
return S<T> (s);
|
||||
}
|
||||
|
||||
__attribute__((noipa)) void
|
||||
baz (S<int> *a, S<int> *b)
|
||||
{
|
||||
#pragma omp parallel for reduction (inscan, +:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = r;
|
||||
#pragma omp scan exclusive(r)
|
||||
r.s += a[i].s;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) S<int>
|
||||
qux (void)
|
||||
{
|
||||
S<int> s;
|
||||
#pragma omp parallel for reduction (inscan, plus:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = s;
|
||||
#pragma omp scan exclusive(s)
|
||||
s.s += 2 * a[i].s;
|
||||
}
|
||||
return S<int> (s);
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
S<int> s;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
a[i].s = i;
|
||||
b[i].s = -1;
|
||||
asm ("" : "+g" (i));
|
||||
}
|
||||
#pragma omp parallel
|
||||
foo (a, b);
|
||||
if (r.s != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i].s != s.s)
|
||||
abort ();
|
||||
else
|
||||
b[i].s = 25;
|
||||
s.s += i;
|
||||
}
|
||||
if (bar<int> ().s != 1024 * 1023)
|
||||
abort ();
|
||||
s.s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i].s != s.s)
|
||||
abort ();
|
||||
s.s += 2 * i;
|
||||
}
|
||||
r.s = 0;
|
||||
baz (a, b);
|
||||
if (r.s != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
s.s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i].s != s.s)
|
||||
abort ();
|
||||
else
|
||||
b[i].s = 25;
|
||||
s.s += i;
|
||||
}
|
||||
if (qux ().s != 1024 * 1023)
|
||||
abort ();
|
||||
s.s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i].s != s.s)
|
||||
abort ();
|
||||
s.s += 2 * i;
|
||||
}
|
||||
}
|
120
libgomp/testsuite/libgomp.c++/scan-6.C
Normal file
120
libgomp/testsuite/libgomp.c++/scan-6.C
Normal file
|
@ -0,0 +1,120 @@
|
|||
// { dg-require-effective-target size32plus }
|
||||
|
||||
extern "C" void abort ();
|
||||
int r, a[1024], b[1024], q;
|
||||
|
||||
template <typename T, typename U>
|
||||
__attribute__((noipa)) void
|
||||
foo (T a, T b, U r)
|
||||
{
|
||||
#pragma omp for reduction (inscan, +:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = r;
|
||||
#pragma omp scan exclusive(r)
|
||||
r += a[i];
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
__attribute__((noipa)) T
|
||||
bar ()
|
||||
{
|
||||
T &s = q;
|
||||
q = 0;
|
||||
#pragma omp parallel
|
||||
#pragma omp for reduction (inscan, +:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = s;
|
||||
#pragma omp scan exclusive(s)
|
||||
s += 2 * a[i];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
__attribute__((noipa)) void
|
||||
baz (T *a, T *b, T &r)
|
||||
{
|
||||
#pragma omp parallel for reduction (inscan, +:r)
|
||||
for (T i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = r;
|
||||
#pragma omp scan exclusive(r)
|
||||
r += a[i];
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
__attribute__((noipa)) int
|
||||
qux ()
|
||||
{
|
||||
T s = q;
|
||||
q = 0;
|
||||
#pragma omp parallel for reduction (inscan, +:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = s;
|
||||
#pragma omp scan exclusive(s)
|
||||
s += 2 * a[i];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
a[i] = i;
|
||||
b[i] = -1;
|
||||
asm ("" : "+g" (i));
|
||||
}
|
||||
#pragma omp parallel
|
||||
foo<int *, int &> (a, b, r);
|
||||
if (r != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = 25;
|
||||
s += i;
|
||||
}
|
||||
if (bar<int> () != 1024 * 1023)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = -1;
|
||||
s += 2 * i;
|
||||
}
|
||||
r = 0;
|
||||
baz<int> (a, b, r);
|
||||
if (r != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = -25;
|
||||
s += i;
|
||||
}
|
||||
if (qux<int &> () != 1024 * 1023)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
s += 2 * i;
|
||||
}
|
||||
}
|
118
libgomp/testsuite/libgomp.c++/scan-7.C
Normal file
118
libgomp/testsuite/libgomp.c++/scan-7.C
Normal file
|
@ -0,0 +1,118 @@
|
|||
// { dg-require-effective-target size32plus }
|
||||
|
||||
extern "C" void abort ();
|
||||
int r, a[1024], b[1024], q;
|
||||
|
||||
#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
|
||||
|
||||
__attribute__((noipa)) void
|
||||
foo (int *a, int *b, int &r)
|
||||
{
|
||||
#pragma omp for reduction (inscan, foo:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = r;
|
||||
#pragma omp scan exclusive(r)
|
||||
r += a[i];
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) int
|
||||
bar (void)
|
||||
{
|
||||
int &s = q;
|
||||
q = 0;
|
||||
#pragma omp parallel
|
||||
#pragma omp for reduction (inscan, foo:s) nowait
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = s;
|
||||
#pragma omp scan exclusive(s)
|
||||
s += 2 * a[i];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
__attribute__((noipa)) void
|
||||
baz (int *a, int *b, int &r)
|
||||
{
|
||||
#pragma omp parallel for reduction (inscan, foo:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = r;
|
||||
#pragma omp scan exclusive(r)
|
||||
r += a[i];
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) int
|
||||
qux (void)
|
||||
{
|
||||
int &s = q;
|
||||
q = 0;
|
||||
#pragma omp parallel for reduction (inscan, foo:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = s;
|
||||
#pragma omp scan exclusive(s)
|
||||
s += 2 * a[i];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
a[i] = i;
|
||||
b[i] = -1;
|
||||
asm ("" : "+g" (i));
|
||||
}
|
||||
#pragma omp parallel
|
||||
foo (a, b, r);
|
||||
if (r != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = 25;
|
||||
s += i;
|
||||
}
|
||||
if (bar () != 1024 * 1023)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = -1;
|
||||
s += 2 * i;
|
||||
}
|
||||
r = 0;
|
||||
baz (a, b, r);
|
||||
if (r != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = -25;
|
||||
s += i;
|
||||
}
|
||||
if (qux () != 1024 * 1023)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
s += 2 * i;
|
||||
}
|
||||
}
|
150
libgomp/testsuite/libgomp.c++/scan-8.C
Normal file
150
libgomp/testsuite/libgomp.c++/scan-8.C
Normal file
|
@ -0,0 +1,150 @@
|
|||
// { dg-require-effective-target size32plus }
|
||||
|
||||
extern "C" void abort ();
|
||||
|
||||
struct S {
|
||||
inline S ();
|
||||
inline ~S ();
|
||||
inline S (const S &);
|
||||
inline S & operator= (const S &);
|
||||
int s;
|
||||
};
|
||||
|
||||
S::S () : s (0)
|
||||
{
|
||||
}
|
||||
|
||||
S::~S ()
|
||||
{
|
||||
}
|
||||
|
||||
S::S (const S &x)
|
||||
{
|
||||
s = x.s;
|
||||
}
|
||||
|
||||
S &
|
||||
S::operator= (const S &x)
|
||||
{
|
||||
s = x.s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
static inline void
|
||||
ini (S &x)
|
||||
{
|
||||
x.s = 0;
|
||||
}
|
||||
|
||||
S r, a[1024], b[1024];
|
||||
|
||||
#pragma omp declare reduction (+: S: omp_out.s += omp_in.s)
|
||||
#pragma omp declare reduction (plus: S: omp_out.s += omp_in.s) initializer (ini (omp_priv))
|
||||
|
||||
__attribute__((noipa)) void
|
||||
foo (S *a, S *b, S &r)
|
||||
{
|
||||
#pragma omp for reduction (inscan, +:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = r;
|
||||
#pragma omp scan exclusive(r)
|
||||
r.s += a[i].s;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) S
|
||||
bar (void)
|
||||
{
|
||||
S s;
|
||||
#pragma omp parallel
|
||||
#pragma omp for reduction (inscan, plus:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = s;
|
||||
#pragma omp scan exclusive(s)
|
||||
s.s += 2 * a[i].s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
__attribute__((noipa)) void
|
||||
baz (S *a, S *b, S &r)
|
||||
{
|
||||
#pragma omp parallel for reduction (inscan, +:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = r;
|
||||
#pragma omp scan exclusive(r)
|
||||
r.s += a[i].s;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) S
|
||||
qux (void)
|
||||
{
|
||||
S s;
|
||||
#pragma omp parallel for reduction (inscan, plus:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = s;
|
||||
#pragma omp scan exclusive(s)
|
||||
s.s += 2 * a[i].s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
S s;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
a[i].s = i;
|
||||
b[i].s = -1;
|
||||
asm ("" : "+g" (i));
|
||||
}
|
||||
#pragma omp parallel
|
||||
foo (a, b, r);
|
||||
if (r.s != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i].s != s.s)
|
||||
abort ();
|
||||
else
|
||||
b[i].s = 25;
|
||||
s.s += i;
|
||||
}
|
||||
if (bar ().s != 1024 * 1023)
|
||||
abort ();
|
||||
s.s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i].s != s.s)
|
||||
abort ();
|
||||
s.s += 2 * i;
|
||||
}
|
||||
r.s = 0;
|
||||
baz (a, b, r);
|
||||
if (r.s != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
s.s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i].s != s.s)
|
||||
abort ();
|
||||
else
|
||||
b[i].s = 25;
|
||||
s.s += i;
|
||||
}
|
||||
if (qux ().s != 1024 * 1023)
|
||||
abort ();
|
||||
s.s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i].s != s.s)
|
||||
abort ();
|
||||
s.s += 2 * i;
|
||||
}
|
||||
}
|
115
libgomp/testsuite/libgomp.c/scan-1.c
Normal file
115
libgomp/testsuite/libgomp.c/scan-1.c
Normal file
|
@ -0,0 +1,115 @@
|
|||
/* { dg-require-effective-target size32plus } */
|
||||
|
||||
extern void abort (void);
|
||||
int r, a[1024], b[1024];
|
||||
|
||||
__attribute__((noipa)) void
|
||||
foo (int *a, int *b)
|
||||
{
|
||||
#pragma omp for reduction (inscan, +:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
r += a[i];
|
||||
#pragma omp scan inclusive(r)
|
||||
b[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) int
|
||||
bar (void)
|
||||
{
|
||||
int s = 0;
|
||||
#pragma omp parallel
|
||||
#pragma omp for reduction (inscan, +:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
s += 2 * a[i];
|
||||
#pragma omp scan inclusive(s)
|
||||
b[i] = s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
__attribute__((noipa)) void
|
||||
baz (int *a, int *b)
|
||||
{
|
||||
#pragma omp parallel for reduction (inscan, +:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
r += a[i];
|
||||
#pragma omp scan inclusive(r)
|
||||
b[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) int
|
||||
qux (void)
|
||||
{
|
||||
int s = 0;
|
||||
#pragma omp parallel for reduction (inscan, +:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
s += 2 * a[i];
|
||||
#pragma omp scan inclusive(s)
|
||||
b[i] = s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
a[i] = i;
|
||||
b[i] = -1;
|
||||
asm ("" : "+g" (i));
|
||||
}
|
||||
#pragma omp parallel
|
||||
foo (a, b);
|
||||
if (r != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s += i;
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = 25;
|
||||
}
|
||||
if (bar () != 1024 * 1023)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s += 2 * i;
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = -1;
|
||||
}
|
||||
r = 0;
|
||||
baz (a, b);
|
||||
if (r != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s += i;
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = -25;
|
||||
}
|
||||
if (qux () != 1024 * 1023)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s += 2 * i;
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
}
|
||||
return 0;
|
||||
}
|
117
libgomp/testsuite/libgomp.c/scan-2.c
Normal file
117
libgomp/testsuite/libgomp.c/scan-2.c
Normal file
|
@ -0,0 +1,117 @@
|
|||
/* { dg-require-effective-target size32plus } */
|
||||
|
||||
extern void abort (void);
|
||||
int r, a[1024], b[1024];
|
||||
|
||||
#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
|
||||
|
||||
__attribute__((noipa)) void
|
||||
foo (int *a, int *b)
|
||||
{
|
||||
#pragma omp for reduction (inscan, foo:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
r += a[i];
|
||||
#pragma omp scan inclusive(r)
|
||||
b[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) int
|
||||
bar (void)
|
||||
{
|
||||
int s = 0;
|
||||
#pragma omp parallel
|
||||
#pragma omp for reduction (inscan, foo:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
s += 2 * a[i];
|
||||
#pragma omp scan inclusive(s)
|
||||
b[i] = s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
__attribute__((noipa)) void
|
||||
baz (int *a, int *b)
|
||||
{
|
||||
#pragma omp parallel for reduction (inscan, foo:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
r += a[i];
|
||||
#pragma omp scan inclusive(r)
|
||||
b[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) int
|
||||
qux (void)
|
||||
{
|
||||
int s = 0;
|
||||
#pragma omp parallel for reduction (inscan, foo:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
s += 2 * a[i];
|
||||
#pragma omp scan inclusive(s)
|
||||
b[i] = s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
a[i] = i;
|
||||
b[i] = -1;
|
||||
asm ("" : "+g" (i));
|
||||
}
|
||||
#pragma omp parallel
|
||||
foo (a, b);
|
||||
if (r != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s += i;
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = 25;
|
||||
}
|
||||
if (bar () != 1024 * 1023)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s += 2 * i;
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = -1;
|
||||
}
|
||||
r = 0;
|
||||
baz (a, b);
|
||||
if (r != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s += i;
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = -25;
|
||||
}
|
||||
if (qux () != 1024 * 1023)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s += 2 * i;
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
}
|
||||
return 0;
|
||||
}
|
88
libgomp/testsuite/libgomp.c/scan-3.c
Normal file
88
libgomp/testsuite/libgomp.c/scan-3.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
/* { dg-require-effective-target size32plus } */
|
||||
|
||||
extern void abort (void);
|
||||
float r = 1.0f, a[1024], b[1024];
|
||||
|
||||
__attribute__((noipa)) void
|
||||
foo (float *a, float *b)
|
||||
{
|
||||
#pragma omp for reduction (inscan, *:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
r *= a[i];
|
||||
#pragma omp scan inclusive(r)
|
||||
b[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) float
|
||||
bar (void)
|
||||
{
|
||||
float s = -__builtin_inff ();
|
||||
#pragma omp parallel for reduction (inscan, max:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
s = s > a[i] ? s : a[i];
|
||||
#pragma omp scan inclusive(s)
|
||||
b[i] = s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
float s = 1.0f;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (i < 80)
|
||||
a[i] = (i & 1) ? 0.25f : 0.5f;
|
||||
else if (i < 200)
|
||||
a[i] = (i % 3) == 0 ? 2.0f : (i % 3) == 1 ? 4.0f : 1.0f;
|
||||
else if (i < 280)
|
||||
a[i] = (i & 1) ? 0.25f : 0.5f;
|
||||
else if (i < 380)
|
||||
a[i] = (i % 3) == 0 ? 2.0f : (i % 3) == 1 ? 4.0f : 1.0f;
|
||||
else
|
||||
switch (i % 6)
|
||||
{
|
||||
case 0: a[i] = 0.25f; break;
|
||||
case 1: a[i] = 2.0f; break;
|
||||
case 2: a[i] = -1.0f; break;
|
||||
case 3: a[i] = -4.0f; break;
|
||||
case 4: a[i] = 0.5f; break;
|
||||
case 5: a[i] = 1.0f; break;
|
||||
default: a[i] = 0.0f; break;
|
||||
}
|
||||
b[i] = -19.0f;
|
||||
asm ("" : "+g" (i));
|
||||
}
|
||||
#pragma omp parallel
|
||||
foo (a, b);
|
||||
if (r * 16384.0f != 0.125f)
|
||||
abort ();
|
||||
float m = -175.25f;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s *= a[i];
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
{
|
||||
a[i] = m - ((i % 3) == 1 ? 2.0f : (i % 3) == 2 ? 4.0f : 0.0f);
|
||||
b[i] = -231.75f;
|
||||
m += 0.75f;
|
||||
}
|
||||
}
|
||||
if (bar () != 592.0f)
|
||||
abort ();
|
||||
s = -__builtin_inff ();
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (s < a[i])
|
||||
s = a[i];
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
}
|
||||
return 0;
|
||||
}
|
179
libgomp/testsuite/libgomp.c/scan-4.c
Normal file
179
libgomp/testsuite/libgomp.c/scan-4.c
Normal file
|
@ -0,0 +1,179 @@
|
|||
/* { dg-require-effective-target size32plus } */
|
||||
|
||||
extern void abort (void);
|
||||
int r, a[1024], b[1024];
|
||||
unsigned short r2, b2[1024];
|
||||
unsigned char r3, b3[1024];
|
||||
|
||||
__attribute__((noipa)) void
|
||||
foo (int *a, int *b, unsigned short *b2, unsigned char *b3)
|
||||
{
|
||||
#pragma omp for reduction (inscan, +:r, r2, r3)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
{ r += a[i]; r2 += a[i]; r3 += a[i]; }
|
||||
#pragma omp scan inclusive(r, r2, r3)
|
||||
{
|
||||
b[i] = r;
|
||||
b2[i] = r2;
|
||||
b3[i] = r3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) int
|
||||
bar (unsigned short *s2p, unsigned char *s3p)
|
||||
{
|
||||
int s = 0;
|
||||
unsigned short s2 = 0;
|
||||
unsigned char s3 = 0;
|
||||
#pragma omp parallel
|
||||
#pragma omp for reduction (inscan, +:s, s2, s3)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
{
|
||||
s += 2 * a[i];
|
||||
s2 += 2 * a[i];
|
||||
s3 += 2 * a[i];
|
||||
}
|
||||
#pragma omp scan inclusive(s, s2, s3)
|
||||
{ b[i] = s; b2[i] = s2; b3[i] = s3; }
|
||||
}
|
||||
*s2p = s2;
|
||||
*s3p = s3;
|
||||
return s;
|
||||
}
|
||||
|
||||
__attribute__((noipa)) void
|
||||
baz (int *a, int *b, unsigned short *b2, unsigned char *b3)
|
||||
{
|
||||
#pragma omp parallel for reduction (inscan, +:r, r2, r3)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
{
|
||||
r += a[i];
|
||||
r2 += a[i];
|
||||
r3 += a[i];
|
||||
}
|
||||
#pragma omp scan inclusive(r, r2, r3)
|
||||
{
|
||||
b[i] = r;
|
||||
b2[i] = r2;
|
||||
b3[i] = r3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) int
|
||||
qux (unsigned short *s2p, unsigned char *s3p)
|
||||
{
|
||||
int s = 0;
|
||||
unsigned short s2 = 0;
|
||||
unsigned char s3 = 0;
|
||||
#pragma omp parallel for reduction (inscan, +:s, s2, s3)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
{ s += 2 * a[i]; s2 += 2 * a[i]; s3 += 2 * a[i]; }
|
||||
#pragma omp scan inclusive(s, s2, s3)
|
||||
{ b[i] = s; b2[i] = s2; b3[i] = s3; }
|
||||
}
|
||||
*s2p = s2;
|
||||
*s3p = s3;
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int s = 0;
|
||||
unsigned short s2;
|
||||
unsigned char s3;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
a[i] = i;
|
||||
b[i] = -1;
|
||||
b2[i] = -1;
|
||||
b3[i] = -1;
|
||||
asm ("" : "+g" (i));
|
||||
}
|
||||
#pragma omp parallel
|
||||
foo (a, b, b2, b3);
|
||||
if (r != 1024 * 1023 / 2
|
||||
|| r2 != (unsigned short) r
|
||||
|| r3 != (unsigned char) r)
|
||||
abort ();
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s += i;
|
||||
if (b[i] != s
|
||||
|| b2[i] != (unsigned short) s
|
||||
|| b3[i] != (unsigned char) s)
|
||||
abort ();
|
||||
else
|
||||
{
|
||||
b[i] = 25;
|
||||
b2[i] = 24;
|
||||
b3[i] = 26;
|
||||
}
|
||||
}
|
||||
if (bar (&s2, &s3) != 1024 * 1023)
|
||||
abort ();
|
||||
if (s2 != (unsigned short) (1024 * 1023)
|
||||
|| s3 != (unsigned char) (1024 * 1023))
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s += 2 * i;
|
||||
if (b[i] != s
|
||||
|| b2[i] != (unsigned short) s
|
||||
|| b3[i] != (unsigned char) s)
|
||||
abort ();
|
||||
else
|
||||
{
|
||||
b[i] = -1;
|
||||
b2[i] = -1;
|
||||
b3[i] = -1;
|
||||
}
|
||||
}
|
||||
r = 0;
|
||||
r2 = 0;
|
||||
r3 = 0;
|
||||
baz (a, b, b2, b3);
|
||||
if (r != 1024 * 1023 / 2
|
||||
|| r2 != (unsigned short) r
|
||||
|| r3 != (unsigned char) r)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s += i;
|
||||
if (b[i] != s
|
||||
|| b2[i] != (unsigned short) s
|
||||
|| b3[i] != (unsigned char) s)
|
||||
abort ();
|
||||
else
|
||||
{
|
||||
b[i] = 25;
|
||||
b2[i] = 24;
|
||||
b3[i] = 26;
|
||||
}
|
||||
}
|
||||
s2 = 0;
|
||||
s3 = 0;
|
||||
if (qux (&s2, &s3) != 1024 * 1023)
|
||||
abort ();
|
||||
if (s2 != (unsigned short) (1024 * 1023)
|
||||
|| s3 != (unsigned char) (1024 * 1023))
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
s += 2 * i;
|
||||
if (b[i] != s
|
||||
|| b2[i] != (unsigned short) s
|
||||
|| b3[i] != (unsigned char) s)
|
||||
abort ();
|
||||
}
|
||||
return 0;
|
||||
}
|
115
libgomp/testsuite/libgomp.c/scan-5.c
Normal file
115
libgomp/testsuite/libgomp.c/scan-5.c
Normal file
|
@ -0,0 +1,115 @@
|
|||
/* { dg-require-effective-target size32plus } */
|
||||
|
||||
extern void abort (void);
|
||||
int r, a[1024], b[1024];
|
||||
|
||||
__attribute__((noipa)) void
|
||||
foo (int *a, int *b)
|
||||
{
|
||||
#pragma omp for reduction (inscan, +:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = r;
|
||||
#pragma omp scan exclusive(r)
|
||||
r += a[i];
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) int
|
||||
bar (void)
|
||||
{
|
||||
int s = 0;
|
||||
#pragma omp parallel
|
||||
#pragma omp for reduction (inscan, +:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = s;
|
||||
#pragma omp scan exclusive(s)
|
||||
s += 2 * a[i];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
__attribute__((noipa)) void
|
||||
baz (int *a, int *b)
|
||||
{
|
||||
#pragma omp parallel for reduction (inscan, +:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = r;
|
||||
#pragma omp scan exclusive(r)
|
||||
r += a[i];
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) int
|
||||
qux (void)
|
||||
{
|
||||
int s = 0;
|
||||
#pragma omp parallel for reduction (inscan, +:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = s;
|
||||
#pragma omp scan exclusive(s)
|
||||
s += 2 * a[i];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
a[i] = i;
|
||||
b[i] = -1;
|
||||
asm ("" : "+g" (i));
|
||||
}
|
||||
#pragma omp parallel
|
||||
foo (a, b);
|
||||
if (r != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = 25;
|
||||
s += i;
|
||||
}
|
||||
if (bar () != 1024 * 1023)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = -1;
|
||||
s += 2 * i;
|
||||
}
|
||||
r = 0;
|
||||
baz (a, b);
|
||||
if (r != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = -25;
|
||||
s += i;
|
||||
}
|
||||
if (qux () != 1024 * 1023)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
s += 2 * i;
|
||||
}
|
||||
return 0;
|
||||
}
|
117
libgomp/testsuite/libgomp.c/scan-6.c
Normal file
117
libgomp/testsuite/libgomp.c/scan-6.c
Normal file
|
@ -0,0 +1,117 @@
|
|||
/* { dg-require-effective-target size32plus } */
|
||||
|
||||
extern void abort (void);
|
||||
int r, a[1024], b[1024];
|
||||
|
||||
#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
|
||||
|
||||
__attribute__((noipa)) void
|
||||
foo (int *a, int *b)
|
||||
{
|
||||
#pragma omp for reduction (inscan, foo:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = r;
|
||||
#pragma omp scan exclusive(r)
|
||||
r += a[i];
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) int
|
||||
bar (void)
|
||||
{
|
||||
int s = 0;
|
||||
#pragma omp parallel
|
||||
#pragma omp for reduction (inscan, foo:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = s;
|
||||
#pragma omp scan exclusive(s)
|
||||
s += 2 * a[i];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
__attribute__((noipa)) void
|
||||
baz (int *a, int *b)
|
||||
{
|
||||
#pragma omp parallel for reduction (inscan, foo:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = r;
|
||||
#pragma omp scan exclusive(r)
|
||||
r += a[i];
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) int
|
||||
qux (void)
|
||||
{
|
||||
int s = 0;
|
||||
#pragma omp parallel for reduction (inscan, foo:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = s;
|
||||
#pragma omp scan exclusive(s)
|
||||
s += 2 * a[i];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
a[i] = i;
|
||||
b[i] = -1;
|
||||
asm ("" : "+g" (i));
|
||||
}
|
||||
#pragma omp parallel
|
||||
foo (a, b);
|
||||
if (r != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = 25;
|
||||
s += i;
|
||||
}
|
||||
if (bar () != 1024 * 1023)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = -1;
|
||||
s += 2 * i;
|
||||
}
|
||||
r = 0;
|
||||
baz (a, b);
|
||||
if (r != 1024 * 1023 / 2)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = -25;
|
||||
s += i;
|
||||
}
|
||||
if (qux () != 1024 * 1023)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
s += 2 * i;
|
||||
}
|
||||
return 0;
|
||||
}
|
86
libgomp/testsuite/libgomp.c/scan-7.c
Normal file
86
libgomp/testsuite/libgomp.c/scan-7.c
Normal file
|
@ -0,0 +1,86 @@
|
|||
/* { dg-require-effective-target size32plus } */
|
||||
|
||||
extern void abort (void);
|
||||
float r = 1.0f, a[1024], b[1024];
|
||||
|
||||
__attribute__((noipa)) void
|
||||
foo (float *a, float *b)
|
||||
{
|
||||
#pragma omp for reduction (inscan, *:r)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = r;
|
||||
#pragma omp scan exclusive(r)
|
||||
r *= a[i];
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) float
|
||||
bar (void)
|
||||
{
|
||||
float s = -__builtin_inff ();
|
||||
#pragma omp parallel for reduction (inscan, max:s)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
b[i] = s;
|
||||
#pragma omp scan exclusive(s)
|
||||
s = s > a[i] ? s : a[i];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
float s = 1.0f;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (i < 80)
|
||||
a[i] = (i & 1) ? 0.25f : 0.5f;
|
||||
else if (i < 200)
|
||||
a[i] = (i % 3) == 0 ? 2.0f : (i % 3) == 1 ? 4.0f : 1.0f;
|
||||
else if (i < 280)
|
||||
a[i] = (i & 1) ? 0.25f : 0.5f;
|
||||
else if (i < 380)
|
||||
a[i] = (i % 3) == 0 ? 2.0f : (i % 3) == 1 ? 4.0f : 1.0f;
|
||||
else
|
||||
switch (i % 6)
|
||||
{
|
||||
case 0: a[i] = 0.25f; break;
|
||||
case 1: a[i] = 2.0f; break;
|
||||
case 2: a[i] = -1.0f; break;
|
||||
case 3: a[i] = -4.0f; break;
|
||||
case 4: a[i] = 0.5f; break;
|
||||
case 5: a[i] = 1.0f; break;
|
||||
default: a[i] = 0.0f; break;
|
||||
}
|
||||
b[i] = -19.0f;
|
||||
asm ("" : "+g" (i));
|
||||
}
|
||||
#pragma omp parallel
|
||||
foo (a, b);
|
||||
if (r * 16384.0f != 0.125f)
|
||||
abort ();
|
||||
float m = -175.25f;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
else
|
||||
b[i] = -231.75f;
|
||||
s *= a[i];
|
||||
a[i] = m - ((i % 3) == 1 ? 2.0f : (i % 3) == 2 ? 4.0f : 0.0f);
|
||||
m += 0.75f;
|
||||
}
|
||||
if (bar () != 592.0f)
|
||||
abort ();
|
||||
s = -__builtin_inff ();
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s)
|
||||
abort ();
|
||||
if (s < a[i])
|
||||
s = a[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
179
libgomp/testsuite/libgomp.c/scan-8.c
Normal file
179
libgomp/testsuite/libgomp.c/scan-8.c
Normal file
|
@ -0,0 +1,179 @@
|
|||
/* { dg-require-effective-target size32plus } */
|
||||
|
||||
extern void abort (void);
|
||||
int r, a[1024], b[1024];
|
||||
unsigned short r2, b2[1024];
|
||||
unsigned char r3, b3[1024];
|
||||
|
||||
__attribute__((noipa)) void
|
||||
foo (int *a, int *b, unsigned short *b2, unsigned char *b3)
|
||||
{
|
||||
#pragma omp for reduction (inscan, +:r, r2, r3)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
{
|
||||
b[i] = r;
|
||||
b2[i] = r2;
|
||||
b3[i] = r3;
|
||||
}
|
||||
#pragma omp scan exclusive(r, r2, r3)
|
||||
{ r += a[i]; r2 += a[i]; r3 += a[i]; }
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) int
|
||||
bar (unsigned short *s2p, unsigned char *s3p)
|
||||
{
|
||||
int s = 0;
|
||||
unsigned short s2 = 0;
|
||||
unsigned char s3 = 0;
|
||||
#pragma omp parallel
|
||||
#pragma omp for reduction (inscan, +:s, s2, s3)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
{ b[i] = s; b2[i] = s2; b3[i] = s3; }
|
||||
#pragma omp scan exclusive(s, s2, s3)
|
||||
{
|
||||
s += 2 * a[i];
|
||||
s2 += 2 * a[i];
|
||||
s3 += 2 * a[i];
|
||||
}
|
||||
}
|
||||
*s2p = s2;
|
||||
*s3p = s3;
|
||||
return s;
|
||||
}
|
||||
|
||||
__attribute__((noipa)) void
|
||||
baz (int *a, int *b, unsigned short *b2, unsigned char *b3)
|
||||
{
|
||||
#pragma omp parallel for reduction (inscan, +:r, r2, r3)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
{
|
||||
b[i] = r;
|
||||
b2[i] = r2;
|
||||
b3[i] = r3;
|
||||
}
|
||||
#pragma omp scan exclusive(r, r2, r3)
|
||||
{
|
||||
r += a[i];
|
||||
r2 += a[i];
|
||||
r3 += a[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((noipa)) int
|
||||
qux (unsigned short *s2p, unsigned char *s3p)
|
||||
{
|
||||
int s = 0;
|
||||
unsigned short s2 = 0;
|
||||
unsigned char s3 = 0;
|
||||
#pragma omp parallel for reduction (inscan, +:s, s2, s3)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
{ b[i] = s; b2[i] = s2; b3[i] = s3; }
|
||||
#pragma omp scan exclusive(s, s2, s3)
|
||||
{ s += 2 * a[i]; s2 += 2 * a[i]; s3 += 2 * a[i]; }
|
||||
}
|
||||
*s2p = s2;
|
||||
*s3p = s3;
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int s = 0;
|
||||
unsigned short s2;
|
||||
unsigned char s3;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
a[i] = i;
|
||||
b[i] = -1;
|
||||
b2[i] = -1;
|
||||
b3[i] = -1;
|
||||
asm ("" : "+g" (i));
|
||||
}
|
||||
#pragma omp parallel
|
||||
foo (a, b, b2, b3);
|
||||
if (r != 1024 * 1023 / 2
|
||||
|| r2 != (unsigned short) r
|
||||
|| r3 != (unsigned char) r)
|
||||
abort ();
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s
|
||||
|| b2[i] != (unsigned short) s
|
||||
|| b3[i] != (unsigned char) s)
|
||||
abort ();
|
||||
else
|
||||
{
|
||||
b[i] = 25;
|
||||
b2[i] = 24;
|
||||
b3[i] = 26;
|
||||
}
|
||||
s += i;
|
||||
}
|
||||
if (bar (&s2, &s3) != 1024 * 1023)
|
||||
abort ();
|
||||
if (s2 != (unsigned short) (1024 * 1023)
|
||||
|| s3 != (unsigned char) (1024 * 1023))
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s
|
||||
|| b2[i] != (unsigned short) s
|
||||
|| b3[i] != (unsigned char) s)
|
||||
abort ();
|
||||
else
|
||||
{
|
||||
b[i] = -1;
|
||||
b2[i] = -1;
|
||||
b3[i] = -1;
|
||||
}
|
||||
s += 2 * i;
|
||||
}
|
||||
r = 0;
|
||||
r2 = 0;
|
||||
r3 = 0;
|
||||
baz (a, b, b2, b3);
|
||||
if (r != 1024 * 1023 / 2
|
||||
|| r2 != (unsigned short) r
|
||||
|| r3 != (unsigned char) r)
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s
|
||||
|| b2[i] != (unsigned short) s
|
||||
|| b3[i] != (unsigned char) s)
|
||||
abort ();
|
||||
else
|
||||
{
|
||||
b[i] = 25;
|
||||
b2[i] = 24;
|
||||
b3[i] = 26;
|
||||
}
|
||||
s += i;
|
||||
}
|
||||
s2 = 0;
|
||||
s3 = 0;
|
||||
if (qux (&s2, &s3) != 1024 * 1023)
|
||||
abort ();
|
||||
if (s2 != (unsigned short) (1024 * 1023)
|
||||
|| s3 != (unsigned char) (1024 * 1023))
|
||||
abort ();
|
||||
s = 0;
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
if (b[i] != s
|
||||
|| b2[i] != (unsigned short) s
|
||||
|| b3[i] != (unsigned char) s)
|
||||
abort ();
|
||||
s += 2 * i;
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue