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 <ja...@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