public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-4732] openmp: Don't reject some valid initializers or conditions of non-rectangular loops [PR102854]
@ 2021-10-27  7:28 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2021-10-27  7:28 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:6b0f35299bd1468ebc13b900a73b7cac6181a2aa

commit r12-4732-g6b0f35299bd1468ebc13b900a73b7cac6181a2aa
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Wed Oct 27 09:16:48 2021 +0200

    openmp: Don't reject some valid initializers or conditions of non-rectangular loops [PR102854]
    
    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.

Diff:
---
 gcc/c-family/c-common.h            |  4 ++--
 gcc/c-family/c-omp.c               | 23 +++++++++++++++++++----
 gcc/cp/semantics.c                 |  4 ++--
 gcc/testsuite/g++.dg/gomp/loop-3.C | 12 ++++++------
 gcc/testsuite/g++.dg/gomp/loop-7.C | 22 ++++++++++++++++++++++
 5 files changed, 51 insertions(+), 14 deletions(-)

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 078730f1e64..f60714e3416 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1234,8 +1234,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,
diff --git a/gcc/c-family/c-omp.c b/gcc/c-family/c-omp.c
index 5625be7a415..32db2268cee 100644
--- a/gcc/c-family/c-omp.c
+++ b/gcc/c-family/c-omp.c
@@ -1353,6 +1353,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.  */
@@ -1651,11 +1664,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;
@@ -1674,7 +1689,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);
     }
@@ -1682,7 +1697,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);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 0d8e5fde834..3072ecdd29a 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -9211,7 +9211,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;
@@ -9597,7 +9597,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))
diff --git a/gcc/testsuite/g++.dg/gomp/loop-3.C b/gcc/testsuite/g++.dg/gomp/loop-3.C
index 3806e1f4e04..d9b84653d19 100644
--- a/gcc/testsuite/g++.dg/gomp/loop-3.C
+++ b/gcc/testsuite/g++.dg/gomp/loop-3.C
@@ -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
index 00000000000..9466c1c9db3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/loop-7.C
@@ -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);
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-10-27  7:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-27  7:28 [gcc r12-4732] openmp: Don't reject some valid initializers or conditions of non-rectangular loops [PR102854] Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).