2015-12-01 Cesar Philippidis gcc/fortran/ * dump-parse-tree.c (show_omp_clauses): Handle gang_static_expr and gang_num_expr. * gfortran.h (struct gfc_omp_clauses): Remove gang_expr, num_gangs, num_workers, vector_length and tile. Add gang_static_expr and gang_num_expr. * openmp.c (gfc_free_omp_clauses): Handle gnag_static_expr, gang_num_expr. Eliminate gang_expr. (match_oacc_clause_gang): Update to allow both num and static arguments in the same gang clauses. (gfc_match_omp_clauses): Remove reference to c->{vector_length, num_gangs, num_workers, tile}. (resolve_omp_clauses): Update calls to resolve_oacc_positive_int_expr. (resolve_oacc_params_in_parallel): Add const char arg argument to make the error messages more descriptive. (resolve_oacc_loop_blocks): Update calls to resolve_oacc_params_in_parallel. * trans-openmp.c (gfc_trans_omp_clauses_1): Update how the gang clause is lowered. (gfc_filter_oacc_combined_clauses): Handle gang_num_expr and gang_static_expr. Also remove OMP_LIST_REDUCTION from the outer construct clauses. gcc/testsuite/ * gfortran.dg/goacc/gang-static.f95: Add static num coverage. * gfortran.dg/goacc/loop-2.f95: Likewise. * gfortran.dg/goacc/loop-6.f95: Likewise. * gfortran.dg/goacc/loop-7.f95: New file. diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c index a816cde..4f38a09 100644 --- a/gcc/fortran/dump-parse-tree.c +++ b/gcc/fortran/dump-parse-tree.c @@ -1146,10 +1146,24 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses) if (omp_clauses->gang) { fputs (" GANG", dumpfile); - if (omp_clauses->gang_expr) + if (omp_clauses->gang_num_expr || omp_clauses->gang_static_expr) { fputc ('(', dumpfile); - show_expr (omp_clauses->gang_expr); + if (omp_clauses->gang_num_expr) + { + fprintf (dumpfile, "num:"); + show_expr (omp_clauses->gang_num_expr); + } + if (omp_clauses->gang_num_expr && omp_clauses->gang_static) + fputc (',', dumpfile); + if (omp_clauses->gang_static) + { + fprintf (dumpfile, "static:"); + if (omp_clauses->gang_static_expr) + show_expr (omp_clauses->gang_static_expr); + else + fputc ('*', dumpfile); + } fputc (')', dumpfile); } } diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index dd186b5..26f4c8a 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1229,7 +1229,8 @@ typedef struct gfc_omp_clauses /* OpenACC. */ struct gfc_expr *async_expr; - struct gfc_expr *gang_expr; + struct gfc_expr *gang_static_expr; + struct gfc_expr *gang_num_expr; struct gfc_expr *worker_expr; struct gfc_expr *vector_expr; struct gfc_expr *num_gangs_expr; @@ -1242,7 +1243,6 @@ typedef struct gfc_omp_clauses gfc_expr_list *tile_list; unsigned async:1, gang:1, worker:1, vector:1, seq:1, independent:1; unsigned wait:1, par_auto:1, gang_static:1, nohost:1, acc_collapse:1, bind:1; - unsigned num_gangs:1, num_workers:1, vector_length:1, tile:1; locus loc; } diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index c6db847..b354d70 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -77,7 +77,8 @@ gfc_free_omp_clauses (gfc_omp_clauses *c) gfc_free_expr (c->thread_limit); gfc_free_expr (c->dist_chunk_size); gfc_free_expr (c->async_expr); - gfc_free_expr (c->gang_expr); + gfc_free_expr (c->gang_num_expr); + gfc_free_expr (c->gang_static_expr); gfc_free_expr (c->worker_expr); gfc_free_expr (c->vector_expr); gfc_free_expr (c->num_gangs_expr); @@ -396,21 +397,41 @@ cleanup: static match match_oacc_clause_gang (gfc_omp_clauses *cp) { - if (gfc_match_char ('(') != MATCH_YES) + match ret = MATCH_YES; + + if (gfc_match (" ( ") != MATCH_YES) return MATCH_NO; - if (gfc_match (" num :") == MATCH_YES) - { - cp->gang_static = false; - return gfc_match (" %e )", &cp->gang_expr); - } - if (gfc_match (" static :") == MATCH_YES) + + /* The gang clause accepts two optional arguments, num and static. + The num argument may either be explicit (num: ) or + implicit without ( without num:). */ + + while (ret == MATCH_YES) { - cp->gang_static = true; - if (gfc_match (" * )") != MATCH_YES) - return gfc_match (" %e )", &cp->gang_expr); - return MATCH_YES; + if (gfc_match (" static :") == MATCH_YES) + { + if (cp->gang_static) + return MATCH_ERROR; + else + cp->gang_static = true; + if (gfc_match_char ('*') == MATCH_YES) + cp->gang_static_expr = NULL; + else if (gfc_match (" %e ", &cp->gang_static_expr) != MATCH_YES) + return MATCH_ERROR; + } + else + { + /* This is optional. */ + if (cp->gang_num_expr || gfc_match (" num :") == MATCH_ERROR) + return MATCH_ERROR; + else if (gfc_match (" %e ", &cp->gang_num_expr) != MATCH_YES) + return MATCH_ERROR; + } + + ret = gfc_match (" , "); } - return gfc_match (" %e )", &cp->gang_expr); + + return gfc_match (" ) "); } static match @@ -661,10 +682,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, uint64_t mask, if ((mask & OMP_CLAUSE_VECTOR_LENGTH) && c->vector_length_expr == NULL && gfc_match ("vector_length ( %e )", &c->vector_length_expr) == MATCH_YES) - { - c->vector_length = 1; - continue; - } + continue; if ((mask & OMP_CLAUSE_VECTOR) && !c->vector) if (gfc_match ("vector") == MATCH_YES) { @@ -729,17 +747,11 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, uint64_t mask, } if ((mask & OMP_CLAUSE_NUM_GANGS) && c->num_gangs_expr == NULL && gfc_match ("num_gangs ( %e )", &c->num_gangs_expr) == MATCH_YES) - { - c->num_gangs = 1; - continue; - } + continue; if ((mask & OMP_CLAUSE_NUM_WORKERS) && c->num_workers_expr == NULL && gfc_match ("num_workers ( %e )", &c->num_workers_expr) == MATCH_YES) - { - c->num_workers = 1; - continue; - } + continue; if ((mask & OMP_CLAUSE_COPY) && gfc_match ("copy ( ") == MATCH_YES && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP], @@ -862,10 +874,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, uint64_t mask, if ((mask & OMP_CLAUSE_TILE) && !c->tile_list && match_oacc_expr_list ("tile (", &c->tile_list, true) == MATCH_YES) - { - c->tile = 1; - continue; - } + continue; if ((mask & OMP_CLAUSE_SEQ) && !c->seq && gfc_match ("seq") == MATCH_YES) { @@ -3853,11 +3862,15 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, if (omp_clauses->num_gangs_expr) resolve_oacc_positive_int_expr (omp_clauses->num_gangs_expr, "NUM_GANGS"); if (omp_clauses->num_workers_expr) - resolve_oacc_positive_int_expr (omp_clauses->num_workers_expr, "NUM_WORKERS"); + resolve_oacc_positive_int_expr (omp_clauses->num_workers_expr, + "NUM_WORKERS"); if (omp_clauses->vector_length_expr) - resolve_oacc_positive_int_expr (omp_clauses->vector_length_expr, "VECTOR_LENGTH"); - if (omp_clauses->gang_expr) - resolve_oacc_positive_int_expr (omp_clauses->gang_expr, "GANG"); + resolve_oacc_positive_int_expr (omp_clauses->vector_length_expr, + "VECTOR_LENGTH"); + if (omp_clauses->gang_num_expr) + resolve_oacc_positive_int_expr (omp_clauses->gang_num_expr, "GANG"); + if (omp_clauses->gang_static_expr) + resolve_oacc_positive_int_expr (omp_clauses->gang_static_expr, "GANG"); if (omp_clauses->worker_expr) resolve_oacc_positive_int_expr (omp_clauses->worker_expr, "WORKER"); if (omp_clauses->vector_expr) @@ -4832,20 +4845,21 @@ resolve_oacc_nested_loops (gfc_code *code, gfc_code* do_code, int collapse, static void -resolve_oacc_params_in_parallel (gfc_code *code, const char *clause) +resolve_oacc_params_in_parallel (gfc_code *code, const char *clause, + const char *arg) { fortran_omp_context *c; if (oacc_is_parallel (code)) gfc_error ("!$ACC LOOP %s in PARALLEL region doesn't allow " - "non-static arguments at %L", clause, &code->loc); + "%s arguments at %L", clause, arg, &code->loc); for (c = omp_current_ctx; c; c = c->previous) { if (oacc_is_loop (c->code)) break; if (oacc_is_parallel (c->code)) gfc_error ("!$ACC LOOP %s in PARALLEL region doesn't allow " - "non-static arguments at %L", clause, &code->loc); + "%s arguments at %L", clause, arg, &code->loc); } } @@ -4928,13 +4942,16 @@ resolve_oacc_loop_blocks (gfc_code *code) "vectors at the same time at %L", &code->loc); if (code->ext.omp_clauses->gang - && code->ext.omp_clauses->gang_expr - && !code->ext.omp_clauses->gang_static) - resolve_oacc_params_in_parallel (code, "GANG"); + && code->ext.omp_clauses->gang_num_expr) + resolve_oacc_params_in_parallel (code, "GANG", "num"); if (code->ext.omp_clauses->worker && code->ext.omp_clauses->worker_expr) - resolve_oacc_params_in_parallel (code, "WORKER"); + resolve_oacc_params_in_parallel (code, "WORKER", "num"); + + if (code->ext.omp_clauses->vector + && code->ext.omp_clauses->vector_expr) + resolve_oacc_params_in_parallel (code, "VECTOR", "length"); if (code->ext.omp_clauses->tile_list) { diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index e98a29c..6ed4a57 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -2628,28 +2628,20 @@ gfc_trans_omp_clauses_1 (stmtblock_t *block, gfc_omp_clauses *clauses, } if (clauses->gang) { - if (clauses->gang_expr) + tree arg; + c = build_omp_clause (where.lb->location, OMP_CLAUSE_GANG); + omp_clauses = gfc_trans_add_clause (c, omp_clauses); + if (clauses->gang_num_expr) { - tree gang_var - = gfc_convert_expr_to_tree (block, clauses->gang_expr); - c = build_omp_clause (where.lb->location, OMP_CLAUSE_GANG); - if (clauses->gang_static) - OMP_CLAUSE_GANG_STATIC_EXPR (c) = gang_var; - else - OMP_CLAUSE_GANG_EXPR (c) = gang_var; - omp_clauses = gfc_trans_add_clause (c, omp_clauses); + arg = gfc_convert_expr_to_tree (block, clauses->gang_num_expr); + OMP_CLAUSE_GANG_EXPR (c) = arg; } - else if (clauses->gang_static) + if (clauses->gang_static) { - /* This corresponds to gang (static: *). */ - c = build_omp_clause (where.lb->location, OMP_CLAUSE_GANG); - OMP_CLAUSE_GANG_STATIC_EXPR (c) = integer_minus_one_node; - omp_clauses = gfc_trans_add_clause (c, omp_clauses); - } - else - { - c = build_omp_clause (where.lb->location, OMP_CLAUSE_GANG); - omp_clauses = gfc_trans_add_clause (c, omp_clauses); + arg = clauses->gang_static_expr + ? gfc_convert_expr_to_tree (block, clauses->gang_static_expr) + : integer_minus_one_node; + OMP_CLAUSE_GANG_STATIC_EXPR (c) = arg; } } @@ -3655,10 +3647,12 @@ gfc_filter_oacc_combined_clauses (gfc_omp_clauses **orig_clauses, (*loop_clauses)->gang = (*orig_clauses)->gang; (*orig_clauses)->gang = false; - (*loop_clauses)->gang_expr = (*orig_clauses)->gang_expr; - (*orig_clauses)->gang_expr = NULL; (*loop_clauses)->gang_static = (*orig_clauses)->gang_static; (*orig_clauses)->gang_static = false; + (*loop_clauses)->gang_num_expr = (*orig_clauses)->gang_num_expr; + (*orig_clauses)->gang_num_expr = NULL; + (*loop_clauses)->gang_static_expr = (*orig_clauses)->gang_static_expr; + (*orig_clauses)->gang_static_expr = NULL; (*loop_clauses)->vector = (*orig_clauses)->vector; (*orig_clauses)->vector = false; (*loop_clauses)->vector_expr = (*orig_clauses)->vector_expr; @@ -3679,19 +3673,16 @@ gfc_filter_oacc_combined_clauses (gfc_omp_clauses **orig_clauses, /* Don't reset (*orig_clauses)->collapse. It should be present on both the kernels/parallel and loop constructs, similar to how gfc_split_omp_clauses duplicates it in combined OMP constructs. */ - (*loop_clauses)->tile = (*orig_clauses)->tile; - (*orig_clauses)->tile = false; (*loop_clauses)->tile_list = (*orig_clauses)->tile_list; (*orig_clauses)->tile_list = NULL; -#if 0 /* TODO */ + (*loop_clauses)->lists[OMP_LIST_REDUCTION] + = (*orig_clauses)->lists[OMP_LIST_REDUCTION]; + (*orig_clauses)->lists[OMP_LIST_REDUCTION] = NULL; +#if 0 (*loop_clauses)->lists[OMP_LIST_PRIVATE] = (*orig_clauses)->lists[OMP_LIST_PRIVATE]; (*orig_clauses)->lists[OMP_LIST_PRIVATE] = NULL; - (*loop_clauses)->lists[OMP_LIST_REDUCTION] - = (*orig_clauses)->lists[OMP_LIST_REDUCTION]; - /* Don't reset (*orig_clauses)->lists[OMP_LIST_REDUCTION]. */ #endif - (*loop_clauses)->device_types = (*orig_clauses)->device_types; gfc_filter_oacc_combined_clauses (&(*orig_clauses)->dtype_clauses, diff --git a/gcc/testsuite/gfortran.dg/goacc/gang-static.f95 b/gcc/testsuite/gfortran.dg/goacc/gang-static.f95 index 4e46cf3..3481085 100644 --- a/gcc/testsuite/gfortran.dg/goacc/gang-static.f95 +++ b/gcc/testsuite/gfortran.dg/goacc/gang-static.f95 @@ -47,6 +47,18 @@ program main end do !$acc end parallel loop + !$acc kernels loop gang (num:5, static:*) + do i = 1, n + a(i) = b(i) + 20 + end do + !$acc end kernels loop + + !$acc kernels loop gang (static:20, num:30) + do i = 1, n + a(i) = b(i) + 20 + end do + !$acc end kernels loop + call test (a, b, 20, n) end program main @@ -66,3 +78,5 @@ end subroutine test ! { dg-final { scan-tree-dump-times "gang\\(static:2\\)" 1 "omplower" } } ! { dg-final { scan-tree-dump-times "gang\\(static:5\\)" 1 "omplower" } } ! { dg-final { scan-tree-dump-times "gang\\(static:20\\)" 1 "omplower" } } +! { dg-final { scan-tree-dump-times "gang\\(num: 5 static:\\\*\\)" 1 "omplower" } } +! { dg-final { scan-tree-dump-times "gang\\(num: 30 static:20\\)" 1 "omplower" } } diff --git a/gcc/testsuite/gfortran.dg/goacc/loop-2.f95 b/gcc/testsuite/gfortran.dg/goacc/loop-2.f95 index b5e6368..0c902b2 100644 --- a/gcc/testsuite/gfortran.dg/goacc/loop-2.f95 +++ b/gcc/testsuite/gfortran.dg/goacc/loop-2.f95 @@ -187,10 +187,10 @@ program test !$acc loop gang DO i = 1,10 ENDDO - !$acc loop gang(5) ! { dg-error "non-static" } + !$acc loop gang(5) ! { dg-error "num arguments" } DO i = 1,10 ENDDO - !$acc loop gang(num:5) ! { dg-error "non-static" } + !$acc loop gang(num:5) ! { dg-error "num arguments" } DO i = 1,10 ENDDO !$acc loop gang(static:5) @@ -218,10 +218,10 @@ program test !$acc loop worker DO i = 1,10 ENDDO - !$acc loop worker(5) ! { dg-error "non-static" } + !$acc loop worker(5) ! { dg-error "num arguments" } DO i = 1,10 ENDDO - !$acc loop worker(num:5) ! { dg-error "non-static" } + !$acc loop worker(num:5) ! { dg-error "num arguments" } DO i = 1,10 ENDDO !$acc loop worker @@ -246,10 +246,10 @@ program test !$acc loop vector DO i = 1,10 ENDDO - !$acc loop vector(5) + !$acc loop vector(5) ! { dg-error "length arguments" } DO i = 1,10 ENDDO - !$acc loop vector(length:5) + !$acc loop vector(length:5) ! { dg-error "length arguments" } DO i = 1,10 ENDDO !$acc loop vector @@ -501,10 +501,10 @@ program test !$acc parallel loop gang DO i = 1,10 ENDDO - !$acc parallel loop gang(5) ! { dg-error "non-static" } + !$acc parallel loop gang(5) ! { dg-error "num arguments" } DO i = 1,10 ENDDO - !$acc parallel loop gang(num:5) ! { dg-error "non-static" } + !$acc parallel loop gang(num:5) ! { dg-error "num arguments" } DO i = 1,10 ENDDO !$acc parallel loop gang(static:5) @@ -526,10 +526,10 @@ program test !$acc parallel loop worker DO i = 1,10 ENDDO - !$acc parallel loop worker(5) ! { dg-error "non-static" } + !$acc parallel loop worker(5) ! { dg-error "num arguments" } DO i = 1,10 ENDDO - !$acc parallel loop worker(num:5) ! { dg-error "non-static" } + !$acc parallel loop worker(num:5) ! { dg-error "num arguments" } DO i = 1,10 ENDDO !$acc parallel loop worker @@ -551,10 +551,10 @@ program test !$acc parallel loop vector DO i = 1,10 ENDDO - !$acc parallel loop vector(5) + !$acc parallel loop vector(5) ! { dg-error "length arguments" } DO i = 1,10 ENDDO - !$acc parallel loop vector(length:5) + !$acc parallel loop vector(length:5) ! { dg-error "length arguments" } DO i = 1,10 ENDDO !$acc parallel loop vector diff --git a/gcc/testsuite/gfortran.dg/goacc/loop-6.f95 b/gcc/testsuite/gfortran.dg/goacc/loop-6.f95 index 3e3d35e..e844468 100644 --- a/gcc/testsuite/gfortran.dg/goacc/loop-6.f95 +++ b/gcc/testsuite/gfortran.dg/goacc/loop-6.f95 @@ -1,6 +1,11 @@ ! { dg-do compile } ! { dg-additional-options "-fmax-errors=100" } +! This error is temporary. Remove when support is added for these clauses +! in the middle end. +! { dg-prune-output "sorry, unimplemented" } +! { dg-prune-output "Error: work-sharing region" } + program test implicit none integer :: i, j @@ -44,10 +49,10 @@ program test !$acc loop vector DO i = 1,10 ENDDO - !$acc loop vector(5) ! { dg-error "argument not permitted" } + !$acc loop vector(5) ! { dg-error "length arguments" } DO i = 1,10 ENDDO - !$acc loop vector(length:5) ! { dg-error "argument not permitted" } + !$acc loop vector(length:5) ! { dg-error "length arguments" } DO i = 1,10 ENDDO !$acc loop vector @@ -68,10 +73,10 @@ program test !$acc parallel loop vector DO i = 1,10 ENDDO - !$acc parallel loop vector(5) ! { dg-error "argument not permitted" } + !$acc parallel loop vector(5) ! { dg-error "length arguments" } DO i = 1,10 ENDDO - !$acc parallel loop vector(length:5) ! { dg-error "argument not permitted" } + !$acc parallel loop vector(length:5) ! { dg-error "length arguments" } DO i = 1,10 ENDDO end diff --git a/gcc/testsuite/gfortran.dg/goacc/loop-7.f95 b/gcc/testsuite/gfortran.dg/goacc/loop-7.f95 new file mode 100644 index 0000000..9ca8297 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/goacc/loop-7.f95 @@ -0,0 +1,122 @@ +! { dg-do compile } +! { dg-additional-options "-fmax-errors=100" } + +program test + implicit none + integer :: i, j, static, num, length + + !$acc kernels + !$acc loop gang(static:static) + DO i = 1,10 + ENDDO + !$acc loop gang(static:*) + DO i = 1,10 + ENDDO + !$acc loop gang(static:1) + DO i = 1,10 + ENDDO + !$acc loop gang(,static:1) ! { dg-error "Invalid character" } + DO i = 1,10 + ENDDO + !$acc loop gang(static:1,) ! { dg-error "Invalid character" } + DO i = 1,10 + ENDDO + !$acc loop gang(static:*, num:5) + DO i = 1,10 + ENDDO + !$acc loop gang(static:1, 5) + DO i = 1,10 + ENDDO + !$acc loop gang(num:num, static:1) + DO i = 1,10 + ENDDO + !$acc loop gang(static:*, num:5, static:5) ! { dg-error "Unclassifiable OpenACC directive" } + DO i = 1,10 + ENDDO + !$acc loop gang(1, num:2, static:3) ! { dg-error "Unclassifiable OpenACC directive" } + DO i = 1,10 + ENDDO + !$acc loop gang(num:num static:1) ! { dg-error "Unclassifiable OpenACC directive" } + DO i = 1,10 + ENDDO + !$acc loop gang(num) + DO i = 1,10 + ENDDO + !$acc loop gang(num:num+1, static:1+num) + DO i = 1,10 + ENDDO + !$acc loop gang(length:num) ! { dg-error "Unclassifiable OpenACC directive" } + DO i = 1,10 + ENDDO + + !$acc loop worker + DO i = 1,10 + ENDDO + !$acc loop worker (5) + DO i = 1,10 + ENDDO + !$acc loop worker (num) + DO i = 1,10 + ENDDO + !$acc loop worker (static:num) ! { dg-error "Unclassifiable OpenACC directive" } + DO i = 1,10 + ENDDO + !$acc loop worker (num:,) ! { dg-error "Invalid character" } + DO i = 1,10 + ENDDO + !$acc loop worker (num:num:num) ! { dg-error "Unclassifiable OpenACC directive" } + DO i = 1,10 + ENDDO + !$acc loop worker (num:num*num) + DO i = 1,10 + ENDDO + !$acc loop worker (length:num*num) ! { dg-error "Unclassifiable OpenACC directive" } + DO i = 1,10 + ENDDO + !$acc loop worker (num:*) ! { dg-error "Invalid character" } + DO i = 1,10 + ENDDO + !$acc loop worker (num:5) + DO i = 1,10 + ENDDO + + !$acc loop vector + DO i = 1,10 + ENDDO + !$acc loop vector (32) + DO i = 1,10 + ENDDO + !$acc loop vector (length) + DO i = 1,10 + ENDDO + !$acc loop vrctor (static:num) ! { dg-error "Unclassifiable OpenACC directive" } + DO i = 1,10 + ENDDO + !$acc loop vector (length:,) ! { dg-error "Invalid character" } + DO i = 1,10 + ENDDO + !$acc loop vector (length:num:num) ! { dg-error "Unclassifiable OpenACC directive" } + DO i = 1,10 + ENDDO + !$acc loop vector (length:static*num) + DO i = 1,10 + ENDDO + !$acc loop vector (length:length) + DO i = 1,10 + ENDDO + !$acc loop vector (length:32) + DO i = 1,10 + ENDDO + !$acc loop vector (num:num*num) ! { dg-error "Unclassifiable OpenACC directive" } + DO i = 1,10 + ENDDO + !$acc loop vector (length:*) ! { dg-error "Invalid character" } + DO i = 1,10 + ENDDO + + + !$acc loop auto + DO i = 1,10 + ENDDO + !$acc end kernels +end