2017-05-22 Jakub Jelinek <jakub@redhat.com>
+ PR middle-end/80809
+ * omp-low.c (finish_taskreg_remap): New function.
+ (finish_taskreg_scan): If unit size of ctx->record_type
+ is non-constant, unshare the size expression and replace
+ decls in it with possible outer var refs.
+
PR middle-end/80809
* gimplify.c (omp_add_variable): For GOVD_DEBUG_PRIVATE use
GOVD_SHARED rather than GOVD_PRIVATE with it.
}
}
+/* Helper function for finish_taskreg_scan, called through walk_tree.
+ If maybe_lookup_decl_in_outer_context returns non-NULL for some
+ tree, replace it in the expression. */
+
+static tree
+finish_taskreg_remap (tree *tp, int *walk_subtrees, void *data)
+{
+ if (VAR_P (*tp))
+ {
+ omp_context *ctx = (omp_context *) data;
+ tree t = maybe_lookup_decl_in_outer_ctx (*tp, ctx);
+ if (t != *tp)
+ {
+ if (DECL_HAS_VALUE_EXPR_P (t))
+ t = unshare_expr (DECL_VALUE_EXPR (t));
+ *tp = t;
+ }
+ *walk_subtrees = 0;
+ }
+ else if (IS_TYPE_OR_DECL_P (*tp))
+ *walk_subtrees = 0;
+ return NULL_TREE;
+}
/* If any decls have been made addressable during scan_omp,
adjust their fields if needed, and layout record types
layout_type (ctx->srecord_type);
tree t = fold_convert_loc (loc, long_integer_type_node,
TYPE_SIZE_UNIT (ctx->record_type));
+ if (TREE_CODE (t) != INTEGER_CST)
+ {
+ t = unshare_expr (t);
+ walk_tree (&t, finish_taskreg_remap, ctx, NULL);
+ }
gimple_omp_task_set_arg_size (ctx->stmt, t);
t = build_int_cst (long_integer_type_node,
TYPE_ALIGN_UNIT (ctx->record_type));
2017-05-22 Jakub Jelinek <jakub@redhat.com>
+ PR middle-end/80809
+ * testsuite/libgomp.c/pr80809-2.c: New test.
+ * testsuite/libgomp.c/pr80809-3.c: New test.
+
PR middle-end/80809
* testsuite/libgomp.c/pr80809-1.c: New test.
--- /dev/null
+/* PR middle-end/80809 */
+/* { dg-do run } */
+
+__attribute__((noinline, noclone)) void
+foo (int x)
+{
+ int i, v[x], w[16];
+ for (i = 0; i < x; i++)
+ v[i] = i;
+ for (i = 0; i < 16; i++)
+ w[i] = 0;
+#pragma omp parallel
+#pragma omp single
+ for (i = 0; i < 16; i++)
+#pragma omp task firstprivate (v)
+ {
+ int j;
+ for (j = 0; j < x; j++)
+ v[j] += i;
+ for (j = 0; j < x; j++)
+ w[i] += v[j];
+ }
+ for (i = 0; i < 16; i++)
+ if (w[i] != (x - 1) * x / 2 + x * i)
+ __builtin_abort ();
+}
+
+int
+main ()
+{
+ foo (4);
+ foo (27);
+ foo (196);
+ return 0;
+}
--- /dev/null
+/* PR middle-end/80809 */
+/* { dg-do run } */
+
+__attribute__((noinline, noclone)) void
+foo (int x)
+{
+ int i, v[x], w[16];
+ for (i = 0; i < x; i++)
+ v[i] = i;
+ for (i = 0; i < 16; i++)
+ w[i] = 0;
+#pragma omp parallel
+#pragma omp single
+ {
+ int z[x];
+ for (i = 0; i < x; i++)
+ z[0] = 0;
+ for (i = 0; i < 16; i++)
+#pragma omp task firstprivate (z) firstprivate (v)
+ {
+ int j;
+ for (j = 0; j < x; j++)
+ z[j] = i;
+ for (j = 0; j < x; j++)
+ v[j] += z[j];
+ for (j = 0; j < x; j++)
+ w[i] += v[j];
+ }
+ }
+ for (i = 0; i < 16; i++)
+ if (w[i] != (x - 1) * x / 2 + x * i)
+ __builtin_abort ();
+}
+
+int
+main ()
+{
+ foo (4);
+ foo (27);
+ foo (196);
+ return 0;
+}