Hi! As the changes to the testcase show, there were 3 issues: 1) nowait clause has not been allowed on target {teams distribute ,}parallel for{, simd} - while parallel for{, simd} disallows nowait, it is allowed on target, so on these constructs nowait should go to target, and not to the worksharing construct 2) depend clause has been allowed on combined constructs including target, but resulted in ICE, only specifying it on non-combined target worked 3) for C++ only, after fixing 2), target parallel depend(inout: p[0]) resulted in weirdo error, because we were finalizing clauses twice in that case
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk and 6.2. 2016-05-30 Jakub Jelinek <ja...@redhat.com> PR c++/71349 * c-parser.c (c_parser_omp_for): Don't disallow nowait clause when combined with target construct. * parser.c (cp_parser_omp_for): Don't disallow nowait clause when combined with target construct. (cp_parser_omp_parallel): Pass cclauses == NULL as last argument to cp_parser_omp_all_clauses. * c-omp.c (c_omp_split_clauses): Put OMP_CLAUSE_DEPEND to C_OMP_CLAUSE_SPLIT_TARGET. Put OMP_CLAUSE_NOWAIT to C_OMP_CLAUSE_SPLIT_TARGET if combined with target construct, instead of C_OMP_CLAUSE_SPLIT_FOR. * c-c++-common/gomp/clauses-1.c (bar): Add dd argument. Add nowait depend(inout: dd[0]) clauses where permitted. --- gcc/c/c-parser.c.jj 2016-05-26 21:10:52.000000000 +0200 +++ gcc/c/c-parser.c 2016-05-30 20:11:36.522350438 +0200 @@ -15113,7 +15113,9 @@ c_parser_omp_for (location_t loc, c_pars strcat (p_name, " for"); mask |= OMP_FOR_CLAUSE_MASK; - if (cclauses) + /* parallel for{, simd} disallows nowait clause, but for + target {teams distribute ,}parallel for{, simd} it should be accepted. */ + if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0) mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT); /* Composite distribute parallel for{, simd} disallows ordered clause. */ if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0) --- gcc/cp/parser.c.jj 2016-05-26 10:38:01.000000000 +0200 +++ gcc/cp/parser.c 2016-05-30 20:51:40.418637030 +0200 @@ -33917,7 +33917,9 @@ cp_parser_omp_for (cp_parser *parser, cp strcat (p_name, " for"); mask |= OMP_FOR_CLAUSE_MASK; - if (cclauses) + /* parallel for{, simd} disallows nowait clause, but for + target {teams distribute ,}parallel for{, simd} it should be accepted. */ + if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0) mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT); /* Composite distribute parallel for{, simd} disallows ordered clause. */ if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0) @@ -34256,7 +34258,8 @@ cp_parser_omp_parallel (cp_parser *parse } } - clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok); + clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok, + cclauses == NULL); if (cclauses) { cp_omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses); --- gcc/c-family/c-omp.c.jj 2016-05-01 12:21:55.000000000 +0200 +++ gcc/c-family/c-omp.c 2016-05-30 20:21:59.107412705 +0200 @@ -983,6 +983,7 @@ c_omp_split_clauses (location_t loc, enu case OMP_CLAUSE_MAP: case OMP_CLAUSE_IS_DEVICE_PTR: case OMP_CLAUSE_DEFAULTMAP: + case OMP_CLAUSE_DEPEND: s = C_OMP_CLAUSE_SPLIT_TARGET; break; case OMP_CLAUSE_NUM_TEAMS: @@ -998,7 +999,6 @@ c_omp_split_clauses (location_t loc, enu s = C_OMP_CLAUSE_SPLIT_PARALLEL; break; case OMP_CLAUSE_ORDERED: - case OMP_CLAUSE_NOWAIT: s = C_OMP_CLAUSE_SPLIT_FOR; break; case OMP_CLAUSE_SCHEDULE: @@ -1333,6 +1333,18 @@ c_omp_split_clauses (location_t loc, enu else s = C_OMP_CLAUSE_SPLIT_FOR; break; + case OMP_CLAUSE_NOWAIT: + /* Nowait clause is allowed on target, for and sections, but + is not allowed on parallel for or parallel sections. Therefore, + put it on target construct if present, because that can only + be combined with parallel for{, simd} and not with for{, simd}, + otherwise to the worksharing construct. */ + if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) + != 0) + s = C_OMP_CLAUSE_SPLIT_TARGET; + else + s = C_OMP_CLAUSE_SPLIT_FOR; + break; default: gcc_unreachable (); } --- gcc/testsuite/c-c++-common/gomp/clauses-1.c.jj 2016-03-08 09:01:48.000000000 +0100 +++ gcc/testsuite/c-c++-common/gomp/clauses-1.c 2016-05-30 20:18:59.000000000 +0200 @@ -34,7 +34,7 @@ foo (int d, int m, int i1, int i2, int p void bar (int d, int m, int i1, int i2, int p, int *idp, int s, - int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q) + int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q, int *dd) { #pragma omp for simd \ private (p) firstprivate (f) lastprivate (l) linear (ll:1) reduction(+:r) schedule(static, 4) collapse(1) nowait \ @@ -63,29 +63,30 @@ bar (int d, int m, int i1, int i2, int p } #pragma omp target parallel \ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \ - if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) + if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \ + nowait depend(inout: dd[0]) ; #pragma omp target parallel for \ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \ if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \ - lastprivate (l) linear (ll:1) ordered schedule(static, 4) collapse(1) + lastprivate (l) linear (ll:1) ordered schedule(static, 4) collapse(1) nowait depend(inout: dd[0]) for (int i = 0; i < 64; i++) ll++; #pragma omp target parallel for simd \ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \ if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \ lastprivate (l) linear (ll:1) schedule(static, 4) collapse(1) \ - safelen(8) simdlen(4) aligned(q: 32) + safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) for (int i = 0; i < 64; i++) ll++; #pragma omp target teams \ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \ - shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) + shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) nowait depend(inout: dd[0]) ; #pragma omp target teams distribute \ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \ shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \ - collapse(1) dist_schedule(static, 16) + collapse(1) dist_schedule(static, 16) nowait depend(inout: dd[0]) for (int i = 0; i < 64; i++) ; #pragma omp target teams distribute parallel for \ @@ -93,7 +94,7 @@ bar (int d, int m, int i1, int i2, int p shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \ collapse(1) dist_schedule(static, 16) \ if (parallel: i2) num_threads (nth) proc_bind(spread) \ - lastprivate (l) schedule(static, 4) + lastprivate (l) schedule(static, 4) nowait depend(inout: dd[0]) for (int i = 0; i < 64; i++) ll++; #pragma omp target teams distribute parallel for simd \ @@ -102,19 +103,20 @@ bar (int d, int m, int i1, int i2, int p collapse(1) dist_schedule(static, 16) \ if (parallel: i2) num_threads (nth) proc_bind(spread) \ lastprivate (l) schedule(static, 4) \ - safelen(8) simdlen(4) aligned(q: 32) + safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) for (int i = 0; i < 64; i++) ll++; #pragma omp target teams distribute simd \ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \ shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \ collapse(1) dist_schedule(static, 16) \ - safelen(8) simdlen(4) aligned(q: 32) + safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) for (int i = 0; i < 64; i++) ll++; #pragma omp target simd \ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \ - safelen(8) simdlen(4) lastprivate (l) linear(ll: 1) aligned(q: 32) reduction(+:r) + safelen(8) simdlen(4) lastprivate (l) linear(ll: 1) aligned(q: 32) reduction(+:r) \ + nowait depend(inout: dd[0]) for (int i = 0; i < 64; i++) ll++; #pragma omp taskloop simd \ @@ -128,7 +130,7 @@ bar (int d, int m, int i1, int i2, int p safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(+:r) for (int i = 0; i < 64; i++) ll++; - #pragma omp target + #pragma omp target nowait depend(inout: dd[0]) #pragma omp teams distribute \ private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \ collapse(1) dist_schedule(static, 16) Jakub