This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[committed] Recognize #pragma omp ordered simd with -fopenmp-simd (PR c/81887)


Hi!

#pragma omp ordered simd is significant even for -fopenmp-simd mode,
if it is ignored, then some valid code might be miscompiled,
therefore this patch parses it with that option too.
#pragma omp ordered threads simd
or
#pragma omp ordered simd threads
is treated like #pragma omp ordered simd, while
#pragma omp ordered
#pragma omp ordered threads
or
#pragma omp ordered depend(...)
is ignored.  Bootstrapped/regtested on x86_64-linux and i686-linux,
committed to trunk so far.

2017-09-01  Jakub Jelinek  <jakub@redhat.com>

	PR c/81887
c-family/
	* c-pragma.c (omp_pragmas): Move "ordered" entry from here to ...
	(omp_pragmas_simd): ... here.
	* c-omp.c (c_finish_omp_ordered): If clauses isn't simd clause alone,
	create new clauses list containing just simd clause.
c/
	* c-parser.c (c_parser_omp_ordered): Handle -fopenmp-simd.
cp/
	* parser.c (cp_parser_omp_ordered): Handle -fopenmp-simd.
fortran/
	* parse.c (decode_omp_directive): Use matchs instead of matcho for
	end ordered and ordered directives, except for ordered depend.  For
	-fopenmp-simd and ordered depend, reject the stmt.
	* trans-openmp.c (gfc_trans_omp_ordered): For -fopenmp-simd ignore
	threads clause and if simd clause isn't present, just translate the
	body.
testsuite/
	* c-c++-common/gomp/pr81887.c: New test.
	* gfortran.dg/gomp/pr81887.f90: New test.

--- gcc/c-family/c-pragma.c.jj	2017-08-29 19:03:08.000000000 +0200
+++ gcc/c-family/c-pragma.c	2017-08-29 21:04:22.140967018 +0200
@@ -1277,7 +1277,6 @@ static const struct omp_pragma_def omp_p
   { "end", PRAGMA_OMP_END_DECLARE_TARGET },
   { "flush", PRAGMA_OMP_FLUSH },
   { "master", PRAGMA_OMP_MASTER },
-  { "ordered", PRAGMA_OMP_ORDERED },
   { "section", PRAGMA_OMP_SECTION },
   { "sections", PRAGMA_OMP_SECTIONS },
   { "single", PRAGMA_OMP_SINGLE },
@@ -1291,6 +1290,7 @@ static const struct omp_pragma_def omp_p
   { "declare", PRAGMA_OMP_DECLARE },
   { "distribute", PRAGMA_OMP_DISTRIBUTE },
   { "for", PRAGMA_OMP_FOR },
+  { "ordered", PRAGMA_OMP_ORDERED },
   { "parallel", PRAGMA_OMP_PARALLEL },
   { "simd", PRAGMA_OMP_SIMD },
   { "target", PRAGMA_OMP_TARGET },
--- gcc/c-family/c-omp.c.jj	2017-08-10 02:31:19.000000000 +0200
+++ gcc/c-family/c-omp.c	2017-08-29 21:28:34.030112023 +0200
@@ -116,6 +116,10 @@ c_finish_omp_ordered (location_t loc, tr
   tree t = make_node (OMP_ORDERED);
   TREE_TYPE (t) = void_type_node;
   OMP_ORDERED_BODY (t) = stmt;
+  if (!flag_openmp	/* flag_openmp_simd */
+      && (OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_SIMD
+	  || OMP_CLAUSE_CHAIN (clauses)))
+    clauses = build_omp_clause (loc, OMP_CLAUSE_SIMD);
   OMP_ORDERED_CLAUSES (t) = clauses;
   SET_EXPR_LOCATION (t, loc);
   return add_stmt (t);
--- gcc/c/c-parser.c.jj	2017-08-29 19:03:08.000000000 +0200
+++ gcc/c/c-parser.c	2017-08-29 21:08:48.749059955 +0200
@@ -15647,6 +15647,11 @@ c_parser_omp_ordered (c_parser *parser,
 
       if (!strcmp ("depend", p))
 	{
+	  if (!flag_openmp)	/* flag_openmp_simd  */
+	    {
+	      c_parser_skip_to_pragma_eol (parser, false);
+	      return false;
+	    }
 	  if (context == pragma_stmt)
 	    {
 	      error_at (loc,
@@ -15667,6 +15672,11 @@ c_parser_omp_ordered (c_parser *parser,
 
   tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
 					   "#pragma omp ordered");
+
+  if (!flag_openmp	/* flag_openmp_simd  */
+      && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
+    return false;
+
   c_finish_omp_ordered (loc, clauses,
 			c_parser_omp_structured_block (parser, if_p));
   return true;
--- gcc/cp/parser.c.jj	2017-08-29 19:03:09.000000000 +0200
+++ gcc/cp/parser.c	2017-08-29 21:19:36.816368363 +0200
@@ -35406,6 +35406,11 @@ cp_parser_omp_ordered (cp_parser *parser
 
       if (strcmp (p, "depend") == 0)
 	{
+	  if (!flag_openmp)	/* flag_openmp_simd */
+	    {
+	      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+	      return false;
+	    }
 	  if (context == pragma_stmt)
 	    {
 	      error_at (pragma_tok->location, "%<#pragma omp ordered%> with "
@@ -35426,6 +35431,11 @@ cp_parser_omp_ordered (cp_parser *parser
   tree clauses
     = cp_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
 				 "#pragma omp ordered", pragma_tok);
+
+  if (!flag_openmp     /* flag_openmp_simd  */
+      && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
+    return false;
+
   c_finish_omp_ordered (loc, clauses,
 			cp_parser_omp_structured_block (parser, if_p));
   return true;
--- gcc/fortran/parse.c.jj	2017-08-07 18:50:09.000000000 +0200
+++ gcc/fortran/parse.c	2017-08-30 00:29:00.795203626 +0200
@@ -875,7 +875,7 @@ decode_omp_directive (void)
       matcho ("end do", gfc_match_omp_end_nowait, ST_OMP_END_DO);
       matchs ("end simd", gfc_match_omp_eos, ST_OMP_END_SIMD);
       matcho ("end master", gfc_match_omp_eos, ST_OMP_END_MASTER);
-      matcho ("end ordered", gfc_match_omp_eos, ST_OMP_END_ORDERED);
+      matchs ("end ordered", gfc_match_omp_eos, ST_OMP_END_ORDERED);
       matchs ("end parallel do simd", gfc_match_omp_eos,
 	      ST_OMP_END_PARALLEL_DO_SIMD);
       matcho ("end parallel do", gfc_match_omp_eos, ST_OMP_END_PARALLEL_DO);
@@ -929,14 +929,16 @@ decode_omp_directive (void)
       matcho ("master", gfc_match_omp_master, ST_OMP_MASTER);
       break;
     case 'o':
-      if (flag_openmp && gfc_match ("ordered depend (") == MATCH_YES)
+      if (gfc_match ("ordered depend (") == MATCH_YES)
 	{
 	  gfc_current_locus = old_locus;
+	  if (!flag_openmp)
+	    break;
 	  matcho ("ordered", gfc_match_omp_ordered_depend,
 		  ST_OMP_ORDERED_DEPEND);
 	}
       else
-	matcho ("ordered", gfc_match_omp_ordered, ST_OMP_ORDERED);
+	matchs ("ordered", gfc_match_omp_ordered, ST_OMP_ORDERED);
       break;
     case 'p':
       matchs ("parallel do simd", gfc_match_omp_parallel_do_simd,
--- gcc/fortran/trans-openmp.c.jj	2017-06-12 09:49:51.000000000 +0200
+++ gcc/fortran/trans-openmp.c	2017-08-29 21:59:09.733541297 +0200
@@ -3925,6 +3925,12 @@ gfc_trans_omp_master (gfc_code *code)
 static tree
 gfc_trans_omp_ordered (gfc_code *code)
 {
+  if (!flag_openmp)
+    {
+      if (!code->ext.omp_clauses->simd)
+	return gfc_trans_code (code->block ? code->block->next : NULL);
+      code->ext.omp_clauses->threads = 0;
+    }
   tree omp_clauses = gfc_trans_omp_clauses (NULL, code->ext.omp_clauses,
 					    code->loc);
   return build2_loc (input_location, OMP_ORDERED, void_type_node,
--- gcc/testsuite/c-c++-common/gomp/pr81887.c.jj	2017-08-29 23:53:28.738961489 +0200
+++ gcc/testsuite/c-c++-common/gomp/pr81887.c	2017-08-29 23:56:26.040142148 +0200
@@ -0,0 +1,61 @@
+/* PR c/81887 */
+/* { dg-do compile } */
+/* { dg-options "-fno-openmp -fopenmp-simd -fdump-tree-gimple" } */
+/* { dg-final { scan-tree-dump-times "#pragma omp simd" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp ordered simd\[ \t]*\[\n\r]" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp" 4 "gimple" } } */
+
+void
+f1 (int *x)
+{
+  int i;
+#pragma omp simd
+  for (i = 0; i < 100; i++)
+  #pragma omp ordered simd
+    x[i / 2] = i;
+}
+
+void
+f2 (int *x)
+{
+  int i;
+#pragma omp parallel for simd ordered
+  for (i = 0; i < 100; i++)
+    #pragma omp ordered threads simd
+      x[i / 2] = i;
+}
+
+void
+f3 (int *x)
+{
+  int i;
+#pragma omp parallel for ordered
+  for (i = 0; i < 100; i++)
+    #pragma omp ordered
+      x[i / 2] = i;
+}
+
+void
+f4 (int *x)
+{
+  int i;
+#pragma omp parallel for ordered
+  for (i = 0; i < 100; i++)
+    #pragma omp ordered threads
+      x[i / 2] = i;
+}
+
+void
+f5 (int n, int ***x)
+{
+  int i, j, k;
+#pragma omp parallel for ordered(3)
+  for (i=0; i < n; i++)
+    for (j=0; j < n; ++j)
+      for (k=0; k < n; ++k)
+	{
+#pragma omp ordered depend(sink:i-8,j-2,k+2) depend(sink:i, j-1,k) depend(sink:i-4,j-3,k+6) depend(sink:i-6,j-4,k-6)
+	  x[i][j][k] = i + j + k;
+#pragma omp ordered depend(source)
+	}
+}
--- gcc/testsuite/gfortran.dg/gomp/pr81887.f90.jj	2017-08-30 00:29:21.213994159 +0200
+++ gcc/testsuite/gfortran.dg/gomp/pr81887.f90	2017-08-30 00:25:31.000000000 +0200
@@ -0,0 +1,61 @@
+! PR c/81887
+! { dg-do compile }
+! { dg-options "-fno-openmp -fopenmp-simd -fdump-tree-gimple" }
+! { dg-final { scan-tree-dump-times "#pragma omp simd" 2 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp ordered simd\[ \t]*\[\n\r]" 2 "gimple" } }
+! { dg-final { scan-tree-dump-times "#pragma omp" 4 "gimple" } }
+
+subroutine f1 (x)
+  integer :: i, x(100)
+  !$omp simd
+  do i = 2, 101
+    !$omp ordered simd
+    x(i / 2) = i
+    !$omp end ordered
+  end do
+end subroutine
+
+subroutine f2 (x)
+  integer :: i, x(100)
+  !$omp parallel do simd ordered
+  do i = 2, 101
+    !$omp ordered threads simd
+    x(i / 2) = i
+    !$omp end ordered
+  end do
+end subroutine
+
+subroutine f3 (x)
+  integer :: i, x(100)
+  !$omp parallel do ordered
+  do i = 2, 101
+    !$omp ordered
+    x(i / 2) = i
+    !$omp end ordered
+  end do
+end subroutine
+
+subroutine f4 (x)
+  integer :: i, x(100)
+  !$omp parallel do ordered
+  do i = 2, 101
+    !$omp ordered threads
+    x(i / 2) = i
+    !$omp end ordered
+  end do
+end subroutine
+
+subroutine f5(x, n)
+  integer :: i, j, k, n, x(100,100,100)
+  !$omp parallel do ordered(3)
+  do i = 1, n
+    do j = 1, n
+      do k = 1, n
+	!$omp ordered depend(sink:i-8,j-2,k+2) depend(sink:i, j-1,k) depend(sink:i-4,j-3,k+6) depend(sink:i-6,j-4,k-6)
+	x(i, j, k) = i + j + k
+	!$omp ordered depend(source)
+      end do
+    end do
+  end do
+  !$omp end parallel do
+end subroutine

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]