]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR middle-end/86539 (OpenMP wrong-code with taskloop and references)
authorJakub Jelinek <jakub@redhat.com>
Fri, 12 Oct 2018 14:49:32 +0000 (16:49 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 12 Oct 2018 14:49:32 +0000 (16:49 +0200)
Backported from mainline
2018-07-17  Jakub Jelinek  <jakub@redhat.com>

PR middle-end/86539
* gimplify.c (gimplify_omp_for): Ensure taskloop firstprivatized init
and cond temporaries don't have reference type if iterator has
pointer type.  For init use &for_pre_body instead of pre_p if
for_pre_body is non-empty.

* testsuite/libgomp.c++/pr86539.C: New test.

From-SVN: r265107

gcc/ChangeLog
gcc/gimplify.c
libgomp/ChangeLog
libgomp/testsuite/libgomp.c++/pr86539.C [new file with mode: 0644]

index 4a0f25a9d0c155b6f8094495eda89556f1d8017b..234e67972b7e8583ce948823c278e0a658247a65 100644 (file)
@@ -1,6 +1,14 @@
 2018-10-12  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2018-07-17  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/86539
+       * gimplify.c (gimplify_omp_for): Ensure taskloop firstprivatized init
+       and cond temporaries don't have reference type if iterator has
+       pointer type.  For init use &for_pre_body instead of pre_p if
+       for_pre_body is non-empty.
+
        2018-07-26  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/86660
index 2a7951f16b3a0b80596d8875c35620b2c3b54693..b6732e7a2a1af71e8c754dcd8bdf6b67b22db2f3 100644 (file)
@@ -9547,9 +9547,26 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
          t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
          if (!is_gimple_constant (TREE_OPERAND (t, 1)))
            {
+             tree type = TREE_TYPE (TREE_OPERAND (t, 0));
              TREE_OPERAND (t, 1)
                = get_initialized_tmp_var (TREE_OPERAND (t, 1),
-                                          pre_p, NULL, false);
+                                          gimple_seq_empty_p (for_pre_body)
+                                          ? pre_p : &for_pre_body, NULL,
+                                          false);
+             /* Reference to pointer conversion is considered useless,
+                but is significant for firstprivate clause.  Force it
+                here.  */
+             if (TREE_CODE (type) == POINTER_TYPE
+                 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 1)))
+                     == REFERENCE_TYPE))
+               {
+                 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
+                 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v,
+                                  TREE_OPERAND (t, 1));
+                 gimplify_and_add (m, gimple_seq_empty_p (for_pre_body)
+                                      ? pre_p : &for_pre_body);
+                 TREE_OPERAND (t, 1) = v;
+               }
              tree c = build_omp_clause (input_location,
                                         OMP_CLAUSE_FIRSTPRIVATE);
              OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
@@ -9561,11 +9578,26 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
          t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
          if (!is_gimple_constant (TREE_OPERAND (t, 1)))
            {
+             tree type = TREE_TYPE (TREE_OPERAND (t, 0));
              TREE_OPERAND (t, 1)
                = get_initialized_tmp_var (TREE_OPERAND (t, 1),
                                           gimple_seq_empty_p (for_pre_body)
                                           ? pre_p : &for_pre_body, NULL,
                                           false);
+             /* Reference to pointer conversion is considered useless,
+                but is significant for firstprivate clause.  Force it
+                here.  */
+             if (TREE_CODE (type) == POINTER_TYPE
+                 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 1)))
+                     == REFERENCE_TYPE))
+               {
+                 tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
+                 tree m = build2 (INIT_EXPR, TREE_TYPE (v), v,
+                                  TREE_OPERAND (t, 1));
+                 gimplify_and_add (m, gimple_seq_empty_p (for_pre_body)
+                                      ? pre_p : &for_pre_body);
+                 TREE_OPERAND (t, 1) = v;
+               }
              tree c = build_omp_clause (input_location,
                                         OMP_CLAUSE_FIRSTPRIVATE);
              OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
index 9b7b86e3e69589da68451924db271656e4cf6f0b..c3fd72c018f4495ddab4ea47e75672197036c033 100644 (file)
@@ -1,6 +1,11 @@
 2018-10-12  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2018-07-17  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/86539
+       * testsuite/libgomp.c++/pr86539.C: New test.
+
        2018-07-26  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/86660
diff --git a/libgomp/testsuite/libgomp.c++/pr86539.C b/libgomp/testsuite/libgomp.c++/pr86539.C
new file mode 100644 (file)
index 0000000..ed0d63e
--- /dev/null
@@ -0,0 +1,28 @@
+// PR middle-end/86539
+
+int a[384];
+
+__attribute__((noinline, noclone)) void
+foo (int &b, int &c)
+{
+  #pragma omp taskloop shared (a) collapse(3)
+  for (int i = 0; i < 1; i++)
+    for (int *p = &b; p < &c; p++)
+      for (int j = 0; j < 1; j++)
+       if (p < &a[128] || p >= &a[256])
+         __builtin_abort ();
+       else
+         p[0]++;
+}
+
+int
+main ()
+{
+  #pragma omp parallel
+  #pragma omp single
+    foo (a[128], a[256]);
+  for (int i = 0; i < 384; i++)
+    if (a[i] != (i >= 128 && i < 256))
+      __builtin_abort ();
+  return 0;
+}