@@ -1436,14 +1436,22 @@ gimplify_decl_expr (tree *stmt_p, gimple
if ((TREE_CODE (decl) == TYPE_DECL
|| TREE_CODE (decl) == VAR_DECL)
&& !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
- gimplify_type_sizes (TREE_TYPE (decl), seq_p);
+ {
+ gimplify_type_sizes (TREE_TYPE (decl), seq_p);
+ if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
+ gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
+ }
/* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
in case its size expressions contain problematic nodes like CALL_EXPR. */
if (TREE_CODE (decl) == TYPE_DECL
&& DECL_ORIGINAL_TYPE (decl)
&& !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
- gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
+ {
+ gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
+ if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
+ gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
+ }
if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
{
@@ -6264,16 +6272,30 @@ omp_notice_variable (struct gimplify_omp
if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
&& (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
- && DECL_SIZE (decl)
- && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
+ && DECL_SIZE (decl))
{
- splay_tree_node n2;
- tree t = DECL_VALUE_EXPR (decl);
- gcc_assert (TREE_CODE (t) == INDIRECT_REF);
- t = TREE_OPERAND (t, 0);
- gcc_assert (DECL_P (t));
- n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
- n2->value |= GOVD_SEEN;
+ if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
+ {
+ splay_tree_node n2;
+ tree t = DECL_VALUE_EXPR (decl);
+ gcc_assert (TREE_CODE (t) == INDIRECT_REF);
+ t = TREE_OPERAND (t, 0);
+ gcc_assert (DECL_P (t));
+ n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
+ n2->value |= GOVD_SEEN;
+ }
+ else if (lang_hooks.decls.omp_privatize_by_reference (decl)
+ && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
+ && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
+ != INTEGER_CST))
+ {
+ splay_tree_node n2;
+ tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
+ gcc_assert (DECL_P (t));
+ n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
+ if (n2)
+ n2->value |= GOVD_SEEN;
+ }
}
shared = ((flags | n->value) & GOVD_SHARED) != 0;
@@ -16472,13 +16472,7 @@ lower_omp_target (gimple_stmt_iterator *
x = build_fold_addr_expr_loc (clause_loc, x);
}
else
- {
- tree atmp
- = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
- tree rtype = TREE_TYPE (TREE_TYPE (new_var));
- tree al = size_int (TYPE_ALIGN (rtype));
- x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
- }
+ break;
x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
@@ -16545,7 +16539,8 @@ lower_omp_target (gimple_stmt_iterator *
}
/* Handle GOMP_MAP_FIRSTPRIVATE_{POINTER,REFERENCE} in second pass,
so that firstprivate vars holding OMP_CLAUSE_SIZE if needed
- are already handled. */
+ are already handled. Similarly OMP_CLAUSE_PRIVATE for VLAs
+ or references to VLAs. */
for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
switch (OMP_CLAUSE_CODE (c))
{
@@ -16687,6 +16682,27 @@ lower_omp_target (gimple_stmt_iterator *
gimple_seq_add_stmt (&new_body,
gimple_build_assign (new_pvar, x));
}
+ else if (is_reference (var) && !is_gimple_omp_oacc (ctx->stmt))
+ {
+ location_t clause_loc = OMP_CLAUSE_LOCATION (c);
+ tree new_var = lookup_decl (var, ctx);
+ tree x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
+ if (TREE_CONSTANT (x))
+ break;
+ else
+ {
+ tree atmp
+ = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
+ tree rtype = TREE_TYPE (TREE_TYPE (new_var));
+ tree al = size_int (TYPE_ALIGN (rtype));
+ x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
+ }
+
+ x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
+ gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
+ gimple_seq_add_stmt (&new_body,
+ gimple_build_assign (new_var, x));
+ }
break;
}
@@ -0,0 +1,114 @@
+// PR libgomp/69555
+// { dg-do run }
+
+#include <omp.h>
+
+__attribute__((noinline, noclone)) void
+f1 (int y)
+{
+ int a[y - 2];
+ int (&c)[y - 2] = a;
+ c[0] = 111;
+ int e = 0;
+
+ #pragma omp parallel private (c) num_threads (4) reduction (+:e)
+ {
+ int v = omp_get_thread_num ();
+ for (int i = 0; i < y - 2; i++)
+ c[i] = i + v;
+ #pragma omp barrier
+ for (int i = 0; i < y - 2; i++)
+ if (c[i] != i + v)
+ e++;
+ }
+ if (c[0] != 111 || e)
+ __builtin_abort ();
+}
+
+__attribute__((noinline, noclone)) void
+f2 (int y)
+{
+ int a[y - 2];
+ int (&c)[y - 2] = a;
+ c[0] = 111;
+
+ #pragma omp task private (c)
+ {
+ int v = omp_get_thread_num ();
+ for (int i = 0; i < y - 2; i++)
+ c[i] = i + v;
+ asm volatile ("" : : "r" (&c[0]) : "memory");
+ for (int i = 0; i < y - 2; i++)
+ if (c[i] != i + v)
+ __builtin_abort ();
+ }
+ if (c[0] != 111)
+ __builtin_abort ();
+}
+
+__attribute__((noinline, noclone)) void
+f3 (int y)
+{
+ int a[y - 2];
+ int (&c)[y - 2] = a;
+ for (int i = 0; i < y - 2; i++)
+ c[i] = i + 4;
+
+ #pragma omp parallel firstprivate (c) num_threads (4)
+ {
+ int v = omp_get_thread_num ();
+ for (int i = 0; i < y - 2; i++)
+ {
+ if (c[i] != i + 4)
+ __builtin_abort ();
+ c[i] = i + v;
+ }
+ #pragma omp barrier
+ for (int i = 0; i < y - 2; i++)
+ if (c[i] != i + v)
+ __builtin_abort ();
+ }
+ for (int i = 0; i < y - 2; i++)
+ if (c[i] != i + 4)
+ __builtin_abort ();
+}
+
+__attribute__((noinline, noclone)) void
+f4 (int y)
+{
+ int a[y - 2];
+ int (&c)[y - 2] = a;
+ for (int i = 0; i < y - 2; i++)
+ c[i] = i + 4;
+
+ #pragma omp task firstprivate (c)
+ {
+ int v = omp_get_thread_num ();
+ for (int i = 0; i < y - 2; i++)
+ {
+ if (c[i] != i + 4)
+ __builtin_abort ();
+ c[i] = i + v;
+ }
+ asm volatile ("" : : "r" (&c[0]) : "memory");
+ for (int i = 0; i < y - 2; i++)
+ if (c[i] != i + v)
+ __builtin_abort ();
+ }
+ for (int i = 0; i < y - 2; i++)
+ if (c[i] != i + 4)
+ __builtin_abort ();
+}
+
+int
+main ()
+{
+ f1 (6);
+ f3 (6);
+ #pragma omp parallel num_threads (4)
+ {
+ f2 (6);
+ f4 (6);
+ }
+ return 0;
+}
@@ -0,0 +1,58 @@
+// PR libgomp/69555
+// { dg-do run }
+
+__attribute__((noinline, noclone)) void
+f1 (int y)
+{
+ int a[y - 2];
+ int (&c)[y - 2] = a;
+ for (int i = 0; i < y - 2; i++)
+ c[i] = i + 4;
+
+ #pragma omp target firstprivate (c)
+ {
+ for (int i = 0; i < y - 2; i++)
+ {
+ if (c[i] != i + 4)
+ __builtin_abort ();
+ c[i] = i + 9;
+ }
+ asm volatile ("" : : "r" (&c[0]) : "memory");
+ for (int i = 0; i < y - 2; i++)
+ if (c[i] != i + 9)
+ __builtin_abort ();
+ }
+ for (int i = 0; i < y - 2; i++)
+ if (c[i] != i + 4)
+ __builtin_abort ();
+}
+
+__attribute__((noinline, noclone)) void
+f2 (int y)
+{
+ int a[y - 2];
+ int (&c)[y - 2] = a;
+ for (int i = 0; i < y - 2; i++)
+ c[i] = i + 4;
+
+ #pragma omp target private (c)
+ {
+ for (int i = 0; i < y - 2; i++)
+ c[i] = i + 9;
+ asm volatile ("" : : "r" (&c[0]) : "memory");
+ for (int i = 0; i < y - 2; i++)
+ if (c[i] != i + 9)
+ __builtin_abort ();
+ }
+ for (int i = 0; i < y - 2; i++)
+ if (c[i] != i + 4)
+ __builtin_abort ();
+}
+
+int
+main ()
+{
+ f1 (6);
+ f2 (6);
+ return 0;
+}