]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
openmp: Don't reject some valid initializers or conditions of non-rectangular loops...
authorJakub Jelinek <jakub@redhat.com>
Wed, 27 Oct 2021 08:37:58 +0000 (10:37 +0200)
committerTobias Burnus <tobias@codesourcery.com>
Wed, 27 Oct 2021 08:43:04 +0000 (10:43 +0200)
In C++, if an iterator has or might have (e.g. dependent type) class type we
remember the original init expressions and check those separately for presence
of iterators, because for class iterators we turn those into expressions that
always do contain reference to the current iterator.  But this resulted in
rejecting valid non-rectangular loop where the dependent type is later instantiated
to an integral type.

Non-rectangular loops with class random access iterators remain broken, that is something
to be fixed incrementally.

2021-10-27  Jakub Jelinek  <jakub@redhat.com>

PR c++/102854
gcc/c-family/
* c-common.h (c_omp_check_loop_iv_exprs): Add enum tree_code argument.
* c-omp.c (c_omp_check_loop_iv_r): For trees other than decls,
TREE_VEC, PLUS_EXPR, MINUS_EXPR, MULT_EXPR, POINTER_PLUS_EXPR or
conversions temporarily clear the 3rd bit from d->kind while walking
subtrees.
(c_omp_check_loop_iv_exprs): Add CODE argument.  Or in 4 into data.kind
if possibly non-rectangular.
gcc/cp/
* semantics.c (handle_omp_for_class_iterator,
finish_omp_for): Adjust c_omp_check_loop_iv_exprs caller.
gcc/testsuite/
* g++.dg/gomp/loop-3.C: Don't expect some errors.
* g++.dg/gomp/loop-7.C: New test.

(cherry picked from commit 6b0f35299bd1468ebc13b900a73b7cac6181a2aa)

gcc/c-family/ChangeLog.omp
gcc/c-family/c-common.h
gcc/c-family/c-omp.c
gcc/cp/ChangeLog.omp
gcc/cp/semantics.c
gcc/testsuite/ChangeLog.omp
gcc/testsuite/g++.dg/gomp/loop-3.C
gcc/testsuite/g++.dg/gomp/loop-7.C [new file with mode: 0644]

index a436e372695d81008deba9f5764c7d5acaabdd27..40ec8cb028447f3d58f2a3cba74a0cd9419c909c 100644 (file)
@@ -1,3 +1,17 @@
+2021-10-27  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backported from master:
+       2021-10-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/102854
+       * c-common.h (c_omp_check_loop_iv_exprs): Add enum tree_code argument.
+       * c-omp.c (c_omp_check_loop_iv_r): For trees other than decls,
+       TREE_VEC, PLUS_EXPR, MINUS_EXPR, MULT_EXPR, POINTER_PLUS_EXPR or
+       conversions temporarily clear the 3rd bit from d->kind while walking
+       subtrees.
+       (c_omp_check_loop_iv_exprs): Add CODE argument.  Or in 4 into data.kind
+       if possibly non-rectangular.
+
 2021-10-15  Tobias Burnus  <tobias@codesourcery.com>
 
        Backported from master:
index 4600ef14d4a2bb69c2657ac42668b1fd3f64e347..919b8740b682a9c43e69b04fc754111ddefea873 100644 (file)
@@ -1230,8 +1230,8 @@ extern void c_finish_omp_taskyield (location_t);
 extern tree c_finish_omp_for (location_t, enum tree_code, tree, tree, tree,
                              tree, tree, tree, tree, bool);
 extern bool c_omp_check_loop_iv (tree, tree, walk_tree_lh);
-extern bool c_omp_check_loop_iv_exprs (location_t, tree, int, tree, tree, tree,
-                                      walk_tree_lh);
+extern bool c_omp_check_loop_iv_exprs (location_t, enum tree_code, tree, int,
+                                      tree, tree, tree, walk_tree_lh);
 extern tree c_finish_oacc_wait (location_t, tree, tree);
 extern tree c_oacc_split_loop_clauses (tree, tree *, bool);
 extern void c_omp_split_clauses (location_t, enum tree_code, omp_clause_mask,
index 184eb6e8dac8a6d9c6f47338ac60790fda0eedd8..26061a62116814f1a2fac91653a6c021066c6ac0 100644 (file)
@@ -1498,6 +1498,19 @@ c_omp_check_loop_iv_r (tree *tp, int *walk_subtrees, void *data)
        }
       d->fail = true;
     }
+  else if ((d->kind & 4)
+          && TREE_CODE (*tp) != TREE_VEC
+          && TREE_CODE (*tp) != PLUS_EXPR
+          && TREE_CODE (*tp) != MINUS_EXPR
+          && TREE_CODE (*tp) != MULT_EXPR
+          && !CONVERT_EXPR_P (*tp))
+    {
+      *walk_subtrees = 0;
+      d->kind &= 3;
+      walk_tree_1 (tp, c_omp_check_loop_iv_r, data, NULL, d->lh);
+      d->kind |= 4;
+      return NULL_TREE;
+    }
   else if (d->ppset->add (*tp))
     *walk_subtrees = 0;
   /* Don't walk dtors added by C++ wrap_cleanups_r.  */
@@ -1796,11 +1809,13 @@ c_omp_check_loop_iv (tree stmt, tree declv, walk_tree_lh lh)
 /* Similar, but allows to check the init or cond expressions individually.  */
 
 bool
-c_omp_check_loop_iv_exprs (location_t stmt_loc, tree declv, int i, tree decl,
-                          tree init, tree cond, walk_tree_lh lh)
+c_omp_check_loop_iv_exprs (location_t stmt_loc, enum tree_code code,
+                          tree declv, int i, tree decl, tree init, tree cond,
+                          walk_tree_lh lh)
 {
   hash_set<tree> pset;
   struct c_omp_check_loop_iv_data data;
+  int kind = (code != OACC_LOOP && i > 0) ? 4 : 0;
 
   data.declv = declv;
   data.fail = false;
@@ -1819,7 +1834,7 @@ c_omp_check_loop_iv_exprs (location_t stmt_loc, tree declv, int i, tree decl,
   if (init)
     {
       data.expr_loc = EXPR_LOCATION (init);
-      data.kind = 0;
+      data.kind = kind;
       walk_tree_1 (&init,
                   c_omp_check_loop_iv_r, &data, NULL, lh);
     }
@@ -1827,7 +1842,7 @@ c_omp_check_loop_iv_exprs (location_t stmt_loc, tree declv, int i, tree decl,
     {
       gcc_assert (COMPARISON_CLASS_P (cond));
       data.expr_loc = EXPR_LOCATION (init);
-      data.kind = 1;
+      data.kind = kind | 1;
       if (TREE_OPERAND (cond, 0) == decl)
        walk_tree_1 (&TREE_OPERAND (cond, 1),
                     c_omp_check_loop_iv_r, &data, NULL, lh);
index dbaa8fff6fce2b2042b70c0c6f0f08fdfee21658..882c09510b7fcd007e2bc0605e7f7341e92ef5fd 100644 (file)
@@ -1,3 +1,12 @@
+2021-10-27  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backported from master:
+       2021-10-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/102854
+       * semantics.c (handle_omp_for_class_iterator,
+       finish_omp_for): Adjust c_omp_check_loop_iv_exprs caller.
+
 2021-10-15  Tobias Burnus  <tobias@codesourcery.com>
 
        Backported from master:
index f494711319aad882d85a11c3186cca663a901db1..ed3ecaa2a139da44290dba8b60dd81c4f30dce9e 100644 (file)
@@ -9827,7 +9827,7 @@ handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code,
                TREE_OPERAND (cond, 1), iter);
       return true;
     }
-  if (!c_omp_check_loop_iv_exprs (locus, orig_declv, i,
+  if (!c_omp_check_loop_iv_exprs (locus, code, orig_declv, i,
                                  TREE_VEC_ELT (declv, i), NULL_TREE,
                                  cond, cp_walk_subtrees))
     return true;
@@ -10213,7 +10213,7 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv,
       tree orig_init;
       FOR_EACH_VEC_ELT (*orig_inits, i, orig_init)
        if (orig_init
-           && !c_omp_check_loop_iv_exprs (locus,
+           && !c_omp_check_loop_iv_exprs (locus, code,
                                           orig_declv ? orig_declv : declv, i,
                                           TREE_VEC_ELT (declv, i), orig_init,
                                           NULL_TREE, cp_walk_subtrees))
index 159227b39f753ba0152c40667be507bb8e54570b..95b5d230ec7d61be308f9a1edd60abea4e6e24c8 100644 (file)
@@ -1,3 +1,12 @@
+2021-10-27  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backported from master:
+       2021-10-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/102854
+       * g++.dg/gomp/loop-3.C: Don't expect some errors.
+       * g++.dg/gomp/loop-7.C: New test.
+
 2021-10-26  Tobias Burnus  <tobias@codesourcery.com>
 
        Backport from master:
index 3806e1f4e0478e9aa023f1ef7497dfde8f2587d3..d9b84653d19e5960fcf3f8a94e0e9ed7a0e6f70c 100644 (file)
@@ -116,7 +116,7 @@ f1 (I<int> &x, I<int> &y, I<int> &u, I<int> &v)
     for (j = x; j < y; j++)
       ;
   #pragma omp for collapse(2)
-  for (i = x; i < y; i = i + 2) /* { dg-error "initializer expression refers to iteration variable" } */
+  for (i = x; i < y; i = i + 2)
     for (j = i; j < v; j += 2)
       ;
   #pragma omp for collapse(2)
@@ -128,11 +128,11 @@ f1 (I<int> &x, I<int> &y, I<int> &u, I<int> &v)
     for (j = baz (&i); j < v; j += 2) /* { dg-error "initializer expression refers to iteration variable" } */
       ;
   #pragma omp for collapse(2)
-  for (i = x; i < y; i++) /* { dg-error "condition expression refers to iteration variable" } */
+  for (i = x; i < y; i++)
     for (j = v; j > i; j--)
       ;
   #pragma omp for collapse(2)
-  for (i = x; i < y; i++) /* { dg-error "condition expression refers to iteration variable" } */
+  for (i = x; i < y; i++)
     for (j = x; j < i; j++)
       ;
   #pragma omp for collapse(2)
@@ -234,7 +234,7 @@ f2 (I<int> &x, I<int> &y, I<int> &u, I<int> &v)
     for (I<int> j = u; j < y; j += 2)
       ;
   #pragma omp for collapse(2)
-  for (I<int> i = x; i < y; i = i + 2) /* { dg-error "initializer expression refers to iteration variable" } */
+  for (I<int> i = x; i < y; i = i + 2)
     for (I<int> j = i; j < v; j += 2)
       ;
   #pragma omp for collapse(2)
@@ -246,11 +246,11 @@ f2 (I<int> &x, I<int> &y, I<int> &u, I<int> &v)
     for (I<int> j = baz (&i); j < v; j += 2) /* { dg-error "initializer expression refers to iteration variable" } */
       ;
   #pragma omp for collapse(2)
-  for (I<int> i = x; i < y; i++) /* { dg-error "condition expression refers to iteration variable" } */
+  for (I<int> i = x; i < y; i++)
     for (I<int> j = v; j > i; j--)
       ;
   #pragma omp for collapse(2)
-  for (I<int> i = x; i < y; i++) /* { dg-error "condition expression refers to iteration variable" } */
+  for (I<int> i = x; i < y; i++)
     for (I<int> j = x; j < i; j++)
       ;
   #pragma omp for collapse(2)
diff --git a/gcc/testsuite/g++.dg/gomp/loop-7.C b/gcc/testsuite/g++.dg/gomp/loop-7.C
new file mode 100644 (file)
index 0000000..9466c1c
--- /dev/null
@@ -0,0 +1,22 @@
+// PR c++/102854
+// { dg-do compile }
+
+template <typename T>
+void
+foo (T N, T M)
+{
+  #pragma omp parallel for collapse(2)
+  for (T i = 0; i < N; ++i)
+    for (T k = i; k < M; ++k)
+      ;
+  #pragma omp parallel for collapse(2)
+  for (T i = 0; i < N; ++i)
+    for (T k = i; k < 2 * i; ++k)
+      ;
+}
+
+void
+bar ()
+{
+  foo (5, 10);
+}