aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/omp-low.c12
-rw-r--r--libgomp/taskloop.c22
-rw-r--r--libgomp/testsuite/libgomp.c/task-reduction-4.c21
3 files changed, 49 insertions, 6 deletions
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 8b31362..c0ce1a4 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -8781,7 +8781,7 @@ lower_omp_task_reductions (omp_context *ctx, enum tree_code code, tree clauses,
tree num_thr_sz = create_tmp_var (size_type_node);
tree lab1 = create_artificial_label (UNKNOWN_LOCATION);
tree lab2 = create_artificial_label (UNKNOWN_LOCATION);
- tree lab3 = NULL_TREE;
+ tree lab3 = NULL_TREE, lab7 = NULL_TREE;
gimple *g;
if (code == OMP_FOR || code == OMP_SECTIONS)
{
@@ -8846,6 +8846,14 @@ lower_omp_task_reductions (omp_context *ctx, enum tree_code code, tree clauses,
NULL_TREE, NULL_TREE);
tree data = create_tmp_var (pointer_sized_int_node);
gimple_seq_add_stmt (end, gimple_build_assign (data, t));
+ if (code == OMP_TASKLOOP)
+ {
+ lab7 = create_artificial_label (UNKNOWN_LOCATION);
+ g = gimple_build_cond (NE_EXPR, data,
+ build_zero_cst (pointer_sized_int_node),
+ lab1, lab7);
+ gimple_seq_add_stmt (end, g);
+ }
gimple_seq_add_stmt (end, gimple_build_label (lab1));
tree ptr;
if (TREE_CODE (TYPE_SIZE_UNIT (record_type)) == INTEGER_CST)
@@ -9209,6 +9217,8 @@ lower_omp_task_reductions (omp_context *ctx, enum tree_code code, tree clauses,
g = gimple_build_call (t, 1, build_fold_addr_expr (avar));
}
gimple_seq_add_stmt (end, g);
+ if (lab7)
+ gimple_seq_add_stmt (end, gimple_build_label (lab7));
t = build_constructor (atype, NULL);
TREE_THIS_VOLATILE (t) = 1;
gimple_seq_add_stmt (end, gimple_build_assign (avar, t));
diff --git a/libgomp/taskloop.c b/libgomp/taskloop.c
index 75697fe..791178a 100644
--- a/libgomp/taskloop.c
+++ b/libgomp/taskloop.c
@@ -51,20 +51,32 @@ GOMP_taskloop (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *),
/* If parallel or taskgroup has been cancelled, don't start new tasks. */
if (team && gomp_team_barrier_cancelled (&team->barrier))
- return;
+ {
+ early_return:
+ if ((flags & (GOMP_TASK_FLAG_NOGROUP | GOMP_TASK_FLAG_REDUCTION))
+ == GOMP_TASK_FLAG_REDUCTION)
+ {
+ struct gomp_data_head { TYPE t1, t2; uintptr_t *ptr; };
+ uintptr_t *ptr = ((struct gomp_data_head *) data)->ptr;
+ /* Tell callers GOMP_taskgroup_reduction_register has not been
+ called. */
+ ptr[2] = 0;
+ }
+ return;
+ }
#ifdef TYPE_is_long
TYPE s = step;
if (step > 0)
{
if (start >= end)
- return;
+ goto early_return;
s--;
}
else
{
if (start <= end)
- return;
+ goto early_return;
s++;
}
UTYPE n = (end - start + s) / step;
@@ -73,13 +85,13 @@ GOMP_taskloop (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *),
if (flags & GOMP_TASK_FLAG_UP)
{
if (start >= end)
- return;
+ goto early_return;
n = (end - start + step - 1) / step;
}
else
{
if (start <= end)
- return;
+ goto early_return;
n = (start - end - step - 1) / -step;
}
#endif
diff --git a/libgomp/testsuite/libgomp.c/task-reduction-4.c b/libgomp/testsuite/libgomp.c/task-reduction-4.c
new file mode 100644
index 0000000..7ca1d02
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/task-reduction-4.c
@@ -0,0 +1,21 @@
+/* PR middle-end/100471 */
+
+extern void abort (void);
+
+int c;
+
+int
+main ()
+{
+#pragma omp parallel
+#pragma omp single
+ {
+ int r = 0, i;
+ #pragma omp taskloop reduction(+:r)
+ for (i = 0; i < c; i++)
+ r++;
+ if (r != 0)
+ abort ();
+ }
+ return 0;
+}