Add Fortran support for the 'scaled' modifier to simdlen:
!$omp (declare) simd … simdlen( [ scaled(type [, divisor] ) : ] length )
where 'type' is a numeric type and 'divisor' and 'length' are >= 1 and
known at compile time.
When doing this, I noticed that some of the >= 1 and >= 0 checks in
openmp.cc only checked for this for constants (with a warning) while
for non-constants, those just were accepted. I changed the function
to also have a hard error and requiring constant. Hence:
For, e.g., 'num_threads(n)' - n might be (still) a variable but if
it is constant, there is the >= 0 check. - This one is *unchanged* and
just shows a warning - but I think an error would also be fine and,
actually, make more sense.
However, for the following clauses, *now* a hard error is printed:
* SAFELEN (OpenMP) [fixed a test case]
* SIMDLEN's length expression (OpenMP)
* SIMDLEN >= SIMDLEN (new check, unrelated to that change, but for completeness)
* SIMDLEN's divisor expression (OpenMP; new modifier)
* PRIORITY (OpenMP, no idea why it needs to be constant, but it is;
fixed some testcases)
* SIZES (OpenMP, simplified check; BTW: OpenMP 6 permits it to be non-const)
* TILE (OpenACC, simplified check + changed warning to an error)
Additionally, I fixed a module handling error for 'simd' in 'declare variant'.
Any comments before I push this patch?
Tobias
OpenMP/Fortran: Handle simdlen's 'scaled' modifier; for > / >= checks, enforce const check [PR127723]
Follow up to commit r17-4947-gfbcafeec06a661 by adding support for Fortran.
Namely, the OpenMP simdlen clause to 'simd' and 'declare simd' gained the
'scaled' modifier that accepts a numeric type and an optional divisor
expression:
simdlen( [ scaled(type-name [, divisor_expr ] ) : ] length_expr)
where divisor_expr and length_expr must be >= 1 and constant.
In the module handling, there was a preexisting bug that for module-file
reading: mio_omp_declare_simd_clauses wrote the keyword "simdlen" to the
module file - but did not read it; its caller for 'declare simd' read it
but the caller for the 'declare variant' context selector didn't, leading
to a read error when 'simdlen' appeared in declare-variant 'match' clause.
As resolve_positive_int_expr/resolve_nonnegative_int_expr only warned
when the violated the condition - and didn't enforce the constantness,
a boolean argument was added such that either an error is printed when
not constant or violating the > / >= 0 condition - or non-constant values
are accepteded - with (only) a warning when constant and violating the
the > / >= 0 condition. (The later matches the current behavior.)
Hence, all callers had to be updated, which lead to testcase updates
as well (for OpenMP and OpenACC).
PR middle-end/127723
gcc/fortran/ChangeLog:
* gfortran.h (gfc_omp_clauses): Add simdlen_type and
simdlen_divisor.
* module.cc (mio_omp_declare_simd_clauses): Handle scaled;
consume "simdlen" token on reading.
(mio_omp_declare_simd): Remove the latter.
* openmp.cc (gfc_free_omp_clauses): Free simdlen_divisor.
(gfc_match_omp_clauses): Parse 'scaled' modifier to 'simdlen'.
(resolve_scalar_int_expr): Return boolean.
(resolve_positive_int_expr, resolve_nonnegative_int_expr):
Additional boolean WARN argument, if false, require constant
argument and fail with an error.
(resolve_oacc_loop_blocks): Update positive/nonnegative
const argument checking.
(resolve_omp_clauses): Likewise; handle simdlen_type/divisor.
gcc/testsuite/ChangeLog:
* gfortran.dg/gomp/clauses-1.f90: Fix testcase: priority must be
a constant expression.
* gfortran.dg/gomp/masked-1.f90: Likewise.
* gfortran.dg/gomp/target2.f90: Likewise.
* gfortran.dg/gomp/taskloop-1.f90: Likewise.
* gfortran.dg/gomp/taskloop-2.f90: Add diagnostic check for a
non-const priority.
* gfortran.dg/goacc/loop-2-kernels-tile.f95: Update dg-warn/error.
* gfortran.dg/goacc/loop-2-parallel-tile.f95: Likewise.
* gfortran.dg/goacc/loop-2-serial-tile.f95: Likewise.
* gfortran.dg/goacc/tile-1.f90: Likewise.
* gfortran.dg/gomp/atomic-18.f90: Likewise.
* gfortran.dg/gomp/atomic-2.f90: Likewise.
* gfortran.dg/gomp/pr67500.f90: Likewise.
* gfortran.dg/gomp/pr77516.f90: Likewise.
* gfortran.dg/gomp/tile-7.f90: Likewise.
* gfortran.dg/gomp/simdlen-scaled-1.f90: New test.
* gfortran.dg/gomp/simdlen-scaled-2.f90: New test.
* gfortran.dg/gomp/simdlen-scaled-3.f90: New test.
* gfortran.dg/gomp/simdlen-scaled-4.f90: New test.
* gfortran.dg/gomp/simdlen-scaled-5-1.f90: New test.
* gfortran.dg/gomp/simdlen-scaled-5-2.f90: New test.
libgomp/ChangeLog:
* testsuite/libgomp.fortran/nestedfn5.f90: Fix testcase: safelen
must be constant.
gcc/fortran/gfortran.h | 7 +
gcc/fortran/module.cc | 26 ++-
gcc/fortran/openmp.cc | 184 +++++++++++++++------
gcc/fortran/trans-openmp.cc | 44 ++---
.../gfortran.dg/goacc/loop-2-kernels-tile.f95 | 8 +-
.../gfortran.dg/goacc/loop-2-parallel-tile.f95 | 8 +-
.../gfortran.dg/goacc/loop-2-serial-tile.f95 | 8 +-
gcc/testsuite/gfortran.dg/goacc/tile-1.f90 | 28 ++--
gcc/testsuite/gfortran.dg/gomp/atomic-18.f90 | 3 +-
gcc/testsuite/gfortran.dg/gomp/atomic-2.f90 | 3 +-
gcc/testsuite/gfortran.dg/gomp/clauses-1.f90 | 15 +-
gcc/testsuite/gfortran.dg/gomp/masked-1.f90 | 5 +-
gcc/testsuite/gfortran.dg/gomp/pr67500.f90 | 8 +-
gcc/testsuite/gfortran.dg/gomp/pr77516.f90 | 2 +-
.../gfortran.dg/gomp/simdlen-scaled-1.f90 | 44 +++++
.../gfortran.dg/gomp/simdlen-scaled-2.f90 | 28 ++++
.../gfortran.dg/gomp/simdlen-scaled-3.f90 | 49 ++++++
.../gfortran.dg/gomp/simdlen-scaled-4.f90 | 75 +++++++++
.../gfortran.dg/gomp/simdlen-scaled-5-1.f90 | 75 +++++++++
.../gfortran.dg/gomp/simdlen-scaled-5-2.f90 | 40 +++++
gcc/testsuite/gfortran.dg/gomp/target2.f90 | 5 +-
gcc/testsuite/gfortran.dg/gomp/taskloop-1.f90 | 5 +-
gcc/testsuite/gfortran.dg/gomp/taskloop-2.f90 | 4 +
gcc/testsuite/gfortran.dg/gomp/tile-7.f90 | 2 +-
libgomp/testsuite/libgomp.fortran/nestedfn5.f90 | 6 +-
25 files changed, 560 insertions(+), 122 deletions(-)
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index a1badd0bde8..4e41133d5fc 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1716,6 +1716,13 @@ typedef struct gfc_omp_clauses
struct gfc_expr *chunk_size;
struct gfc_expr *safelen_expr;
struct gfc_expr *simdlen_expr;
+ struct
+ {
+ bt type;
+ int kind;
+ }
+ simdlen_type;
+ struct gfc_expr *simdlen_divisor;
struct gfc_expr_list *num_teams_list;
struct gfc_expr *device;
struct gfc_expr_list *thread_limit_list;
diff --git a/gcc/fortran/module.cc b/gcc/fortran/module.cc
index 798e7d9ca1d..ea86a091f69 100644
--- a/gcc/fortran/module.cc
+++ b/gcc/fortran/module.cc
@@ -4389,6 +4389,8 @@ static const mstring omp_declare_simd_clauses[] =
minit ("UNIFORM", 3),
minit ("LINEAR", 4),
minit ("ALIGNED", 5),
+ minit ("SIMDLEN_TYP", 6),
+ minit ("SIMDLEN_DIV", 7),
minit ("LINEAR_REF", 33),
minit ("LINEAR_VAL", 34),
minit ("LINEAR_UVAL", 35),
@@ -4435,12 +4437,26 @@ mio_omp_declare_simd_clauses (gfc_omp_clauses **clausesp)
mio_symbol_ref (&n->sym);
mio_expr (&n->expr);
}
+ if (clauses->simdlen_type.type != BT_UNKNOWN)
+ {
+ gfc_typespec ts = {};
+ ts.type = clauses->simdlen_type.type;
+ ts.kind = clauses->simdlen_type.kind;
+ mio_name (6, omp_declare_simd_clauses);
+ mio_typespec (&ts);
+ if (clauses->simdlen_divisor)
+ {
+ mio_name (7, omp_declare_simd_clauses);
+ mio_expr (&clauses->simdlen_divisor);
+ }
+ }
}
else
{
if (peek_atom () != ATOM_NAME)
return;
+ require_atom (ATOM_NAME);
gfc_omp_namelist **ptrs[3] = { NULL, NULL, NULL };
gfc_omp_clauses *clauses = *clausesp = gfc_get_omp_clauses ();
ptrs[0] = &clauses->lists[OMP_LIST_UNIFORM];
@@ -4468,6 +4484,15 @@ mio_omp_declare_simd_clauses (gfc_omp_clauses **clausesp)
if (t != 3)
mio_expr (&n->expr);
break;
+ case 6:
+ {
+ gfc_typespec ts;
+ mio_typespec (&ts);
+ clauses->simdlen_type.type = ts.type;
+ clauses->simdlen_type.kind = ts.kind;
+ break;
+ }
+ case 7: mio_expr (&clauses->simdlen_divisor); break;
case 33:
case 34:
case 35:
@@ -4517,7 +4542,6 @@ mio_omp_declare_simd (gfc_namespace *ns, gfc_omp_declare_simd **odsp)
return;
}
- require_atom (ATOM_NAME);
*odsp = ods = gfc_get_omp_declare_simd ();
ods->where = gfc_current_locus;
ods->proc_name = ns->proc_name;
diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index a2c825401e3..0ed83519a64 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -202,6 +202,7 @@ gfc_free_omp_clauses (gfc_omp_clauses *c)
gfc_free_expr (c->chunk_size);
gfc_free_expr (c->safelen_expr);
gfc_free_expr (c->simdlen_expr);
+ gfc_free_expr (c->simdlen_divisor);
gfc_free_expr (c->device);
gfc_free_expr (c->dyn_groupprivate);
gfc_free_expr (c->dist_chunk_size);
@@ -4833,11 +4834,55 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
true) == MATCH_YES)
continue;
if ((mask & OMP_CLAUSE_SIMDLEN)
- && (m = gfc_match_dupl_check (!c->simdlen_expr, "simdlen", true,
- &c->simdlen_expr)) != MATCH_NO)
+ && (m = gfc_match_dupl_check (!c->simdlen_expr, "simdlen",
+ true)) != MATCH_NO)
{
if (m == MATCH_ERROR)
goto error;
+ if (gfc_match ("scaled ( ") == MATCH_YES)
+ {
+ old_loc = gfc_current_locus;
+ gfc_typespec ts;
+ /* This does not match 'type(integer)'; should it? */
+ if (gfc_match_type_spec (&ts) != MATCH_YES
+ || (ts.type != BT_INTEGER && ts.type != BT_UNSIGNED
+ && ts.type != BT_REAL && ts.type != BT_COMPLEX))
+ {
+ gfc_error ("Expected numerical type name at %L",
+ &old_loc);
+ goto error;
+ }
+ c->simdlen_type.type = ts.type;
+ c->simdlen_type.kind = ts.kind;
+ if (gfc_match (" , ") == MATCH_YES)
+ {
+ if (gfc_match_expr (&c->simdlen_divisor) != MATCH_YES)
+ {
+ gfc_error ("Expected divisor expression at %C");
+ goto error;
+ }
+ }
+ if (gfc_match (" ) ") != MATCH_YES)
+ {
+ gfc_error ("Expected %<)%> at %C");
+ goto error;
+ }
+ if (gfc_match (" : ") != MATCH_YES)
+ {
+ gfc_error ("Expected %<:%> at %C");
+ goto error;
+ }
+ }
+ if (gfc_match_expr (&c->simdlen_expr) != MATCH_YES)
+ {
+ gfc_error ("Expected length expression at %C");
+ goto error;
+ }
+ if (gfc_match (" ) ") != MATCH_YES)
+ {
+ gfc_error ("Expected %<)%> at %C");
+ goto error;
+ }
continue;
}
if ((mask & OMP_CLAUSE_SIMD)
@@ -9423,38 +9468,64 @@ oacc_is_loop (gfc_code *code)
|| code->op == EXEC_OACC_LOOP;
}
-static void
+static bool
resolve_scalar_int_expr (gfc_expr *expr, const char *clause)
{
if (!gfc_resolve_expr (expr)
|| expr->ts.type != BT_INTEGER
|| expr->rank != 0)
- gfc_error ("%s clause at %L requires a scalar INTEGER expression",
- clause, &expr->where);
+ {
+ gfc_error ("%s clause at %L requires a scalar INTEGER expression",
+ clause, &expr->where);
+ return false;
+ }
+ return true;
}
+/* Require that EXPR is a scalar constant integer expression; it shall be a
+ positive number: If WARN is true, a warning is printed if constant and
+ not positive. If WARN is false, an error is printed if it is either not
+ constant or not positive. CLAUSE is used in the diagnostic output. */
+
static void
-resolve_positive_int_expr (gfc_expr *expr, const char *clause)
+resolve_positive_int_expr (gfc_expr *expr, const char *clause, bool warn)
{
- resolve_scalar_int_expr (expr, clause);
- if (expr->expr_type == EXPR_CONSTANT
- && expr->ts.type == BT_INTEGER
+ if (!resolve_scalar_int_expr (expr, clause))
+ return;
+ if (warn
+ && expr->expr_type == EXPR_CONSTANT
&& mpz_sgn (expr->value.integer) <= 0)
gfc_warning ((flag_openmp || flag_openmp_simd) ? OPT_Wopenmp : 0,
"INTEGER expression of %s clause at %L must be positive",
clause, &expr->where);
+ else if (!warn
+ && (expr->expr_type != EXPR_CONSTANT
+ || mpz_sgn (expr->value.integer) <= 0))
+ gfc_error ("INTEGER expression of %s clause at %L must be positive and "
+ "constant", clause, &expr->where);
}
+/* Require that EXPR is a scalar constant integer expression; it shall be a
+ nonnegative number: If WARN is true, a warning is printed if constant and
+ negative. If WARN is false, an error is printed if it is either not constant
+ or negative. CLAUSE is used in the diagnostic output. */
+
static void
-resolve_nonnegative_int_expr (gfc_expr *expr, const char *clause)
+resolve_nonnegative_int_expr (gfc_expr *expr, const char *clause, bool warn)
{
- resolve_scalar_int_expr (expr, clause);
- if (expr->expr_type == EXPR_CONSTANT
- && expr->ts.type == BT_INTEGER
+ if (!resolve_scalar_int_expr (expr, clause))
+ return;
+ if (warn
+ && expr->expr_type == EXPR_CONSTANT
&& mpz_sgn (expr->value.integer) < 0)
gfc_warning ((flag_openmp || flag_openmp_simd) ? OPT_Wopenmp : 0,
"INTEGER expression of %s clause at %L must be non-negative",
clause, &expr->where);
+ else if (!warn
+ && (expr->expr_type != EXPR_CONSTANT
+ || mpz_sgn (expr->value.integer) < 0))
+ gfc_error ("INTEGER expression of %s clause at %L must be non-negtive and "
+ "constant", clause, &expr->where);
}
/* Emits error when symbol is pointer, cray pointer or cray pointee
@@ -10868,11 +10939,11 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
}
for (el = omp_clauses->num_threads_list; el; el = el->next)
- resolve_positive_int_expr (el->expr, "NUM_THREADS");
+ resolve_positive_int_expr (el->expr, "NUM_THREADS", true);
if (omp_clauses->dyn_groupprivate)
resolve_nonnegative_int_expr (omp_clauses->dyn_groupprivate,
- "DYN_GROUPPRIVATE");
+ "DYN_GROUPPRIVATE", true);
if (omp_clauses->chunk_size)
{
gfc_expr *expr = omp_clauses->chunk_size;
@@ -11669,11 +11740,35 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
}
}
if (omp_clauses->safelen_expr)
- resolve_positive_int_expr (omp_clauses->safelen_expr, "SAFELEN");
+ resolve_positive_int_expr (omp_clauses->safelen_expr, "SAFELEN", false);
if (omp_clauses->simdlen_expr)
- resolve_positive_int_expr (omp_clauses->simdlen_expr, "SIMDLEN");
+ resolve_positive_int_expr (omp_clauses->simdlen_expr, "SIMDLEN", false);
+ if (omp_clauses->simdlen_divisor
+ && (!gfc_resolve_expr (omp_clauses->simdlen_divisor)
+ || omp_clauses->simdlen_divisor->ts.type != BT_INTEGER
+ || omp_clauses->simdlen_divisor->rank != 0
+ || omp_clauses->simdlen_divisor->expr_type != EXPR_CONSTANT
+ || mpz_sgn (omp_clauses->simdlen_divisor->value.integer) <= 0))
+ gfc_error ("Divisor expression at %L of the SCALED modifier to SIMDLEN must"
+ " be a positive scalar constant integer expression",
+ &omp_clauses->simdlen_divisor->where);
+ /* Check that safelen >= simdlen * scaled; however, scaled is
+ unknown, hence, assume scaled == 1 as conservative estimate.
+ we need to repeat some const check as the program still continues
+ after the error diagnostic above. */
+ if (omp_clauses->safelen_expr && omp_clauses->simdlen_expr
+
+ && omp_clauses->safelen_expr->expr_type == EXPR_CONSTANT
+ && omp_clauses->simdlen_expr->ts.type == BT_INTEGER
+ && omp_clauses->simdlen_expr->expr_type == EXPR_CONSTANT
+ && omp_clauses->simdlen_expr->ts.type == BT_INTEGER
+ && mpz_cmp (omp_clauses->safelen_expr->value.integer,
+ omp_clauses->simdlen_expr->value.integer) < 0)
+ gfc_error ("SIMDLEN at %L must be smaller or equal to SAFELEN at %L",
+ &omp_clauses->simdlen_expr->where,
+ &omp_clauses->safelen_expr->where);
for (el = omp_clauses->num_teams_list; el; el = el->next)
- resolve_positive_int_expr (el->expr, "NUM_TEAMS");
+ resolve_positive_int_expr (el->expr, "NUM_TEAMS", true);
if (omp_clauses->num_teams_list
&& omp_clauses->num_teams_list->next
&& !omp_clauses->num_teams_dims
@@ -11687,18 +11782,19 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
if (omp_clauses->device)
resolve_scalar_int_expr (omp_clauses->device, "DEVICE");
if (omp_clauses->filter)
- resolve_nonnegative_int_expr (omp_clauses->filter, "FILTER");
+ resolve_nonnegative_int_expr (omp_clauses->filter, "FILTER", true);
if (omp_clauses->hint)
{
- resolve_scalar_int_expr (omp_clauses->hint, "HINT");
- if (omp_clauses->hint->ts.type != BT_INTEGER
- || omp_clauses->hint->expr_type != EXPR_CONSTANT
- || mpz_sgn (omp_clauses->hint->value.integer) < 0)
+ if (!gfc_resolve_expr (omp_clauses->hint)
+ || omp_clauses->hint->rank != 0
+ || omp_clauses->hint->ts.type != BT_INTEGER
+ || omp_clauses->hint->expr_type != EXPR_CONSTANT
+ || mpz_sgn (omp_clauses->hint->value.integer) < 0)
gfc_error ("Value of HINT clause at %L shall be a valid "
"constant hint expression", &omp_clauses->hint->where);
}
if (omp_clauses->priority)
- resolve_nonnegative_int_expr (omp_clauses->priority, "PRIORITY");
+ resolve_nonnegative_int_expr (omp_clauses->priority, "PRIORITY", false);
if (omp_clauses->dist_chunk_size)
{
gfc_expr *expr = omp_clauses->dist_chunk_size;
@@ -11708,11 +11804,11 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
"a scalar INTEGER expression", &expr->where);
}
for (el = omp_clauses->thread_limit_list; el; el = el->next)
- resolve_positive_int_expr (el->expr, "THREAD_LIMIT");
+ resolve_positive_int_expr (el->expr, "THREAD_LIMIT", true);
if (omp_clauses->grainsize)
- resolve_positive_int_expr (omp_clauses->grainsize, "GRAINSIZE");
+ resolve_positive_int_expr (omp_clauses->grainsize, "GRAINSIZE", true);
if (omp_clauses->num_tasks)
- resolve_positive_int_expr (omp_clauses->num_tasks, "NUM_TASKS");
+ resolve_positive_int_expr (omp_clauses->num_tasks, "NUM_TASKS", true);
if (omp_clauses->grainsize && omp_clauses->num_tasks)
gfc_error ("%<GRAINSIZE%> clause at %L must not be used together with "
"%<NUM_TASKS%> clause", &omp_clauses->grainsize->where);
@@ -11734,20 +11830,21 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
gfc_error ("At least one of the clauses %<DEVICE_TYPE%> and %<DEVICE_NUM%> "
"should be present in %<SET%> directive at %L", &code->loc);
if (omp_clauses->num_gangs_expr)
- resolve_positive_int_expr (omp_clauses->num_gangs_expr, "NUM_GANGS");
+ resolve_positive_int_expr (omp_clauses->num_gangs_expr, "NUM_GANGS", true);
if (omp_clauses->num_workers_expr)
- resolve_positive_int_expr (omp_clauses->num_workers_expr, "NUM_WORKERS");
+ resolve_positive_int_expr (omp_clauses->num_workers_expr, "NUM_WORKERS",
+ true);
if (omp_clauses->vector_length_expr)
resolve_positive_int_expr (omp_clauses->vector_length_expr,
- "VECTOR_LENGTH");
+ "VECTOR_LENGTH", true);
if (omp_clauses->gang_num_expr)
- resolve_positive_int_expr (omp_clauses->gang_num_expr, "GANG");
+ resolve_positive_int_expr (omp_clauses->gang_num_expr, "GANG", true);
if (omp_clauses->gang_static_expr)
- resolve_positive_int_expr (omp_clauses->gang_static_expr, "GANG");
+ resolve_positive_int_expr (omp_clauses->gang_static_expr, "GANG", true);
if (omp_clauses->worker_expr)
- resolve_positive_int_expr (omp_clauses->worker_expr, "WORKER");
+ resolve_positive_int_expr (omp_clauses->worker_expr, "WORKER", true);
if (omp_clauses->vector_expr)
- resolve_positive_int_expr (omp_clauses->vector_expr, "VECTOR");
+ resolve_positive_int_expr (omp_clauses->vector_expr, "VECTOR", true);
for (el = omp_clauses->wait_list; el; el = el->next)
resolve_scalar_int_expr (el->expr, "WAIT");
if (omp_clauses->collapse && omp_clauses->tile_list)
@@ -11785,17 +11882,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
{
gfc_expr_list *el;
for (el = omp_clauses->sizes_list; el; el = el->next)
- {
- resolve_scalar_int_expr (el->expr, "SIZES");
- if (el->expr->expr_type != EXPR_CONSTANT)
- gfc_error ("SIZES requires constant expression at %L",
- &el->expr->where);
- else if (el->expr->expr_type == EXPR_CONSTANT
- && el->expr->ts.type == BT_INTEGER
- && mpz_sgn (el->expr->value.integer) <= 0)
- gfc_error ("INTEGER expression of %s clause at %L must be "
- "positive", "SIZES", &el->expr->where);
- }
+ resolve_positive_int_expr (el->expr, "SIZES", false);
}
if (!openacc && omp_clauses->detach)
@@ -14128,12 +14215,7 @@ resolve_oacc_loop_blocks (gfc_code *code)
mpz_set_si (el->expr->value.integer, 0);
}
else
- {
- resolve_positive_int_expr (el->expr, "TILE");
- if (el->expr->expr_type != EXPR_CONSTANT)
- gfc_error ("TILE requires constant expression at %L",
- &code->loc);
- }
+ resolve_positive_int_expr (el->expr, "TILE", false);
}
}
}
diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index 3e4375f6d60..b6a9373ab51 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -5985,27 +5985,27 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
if (clauses->simdlen_expr)
{
- if (declare_simd)
- {
- c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_SIMDLEN);
- OMP_CLAUSE_SIMDLEN_EXPR (c)
- = gfc_conv_constant_to_tree (clauses->simdlen_expr);
- omp_clauses = gfc_trans_add_clause (c, omp_clauses);
- }
- else
- {
- tree simdlen_var;
-
- gfc_init_se (&se, NULL);
- gfc_conv_expr (&se, clauses->simdlen_expr);
- gfc_add_block_to_block (block, &se.pre);
- simdlen_var = gfc_evaluate_now (se.expr, block);
- gfc_add_block_to_block (block, &se.post);
+ c = build_omp_clause (gfc_get_location (&clauses->simdlen_expr->where),
+ OMP_CLAUSE_SIMDLEN);
+ OMP_CLAUSE_SIMDLEN_EXPR (c)
+ = gfc_conv_constant_to_tree (clauses->simdlen_expr);
+ if (clauses->simdlen_type.type != BT_UNKNOWN)
+ {
+ gfc_typespec ts = {};
+ ts.type = clauses->simdlen_type.type;
+ ts.kind = clauses->simdlen_type.kind;
+ OMP_CLAUSE_SIMDLEN_TYPE (c)
+ = gfc_typenode_for_spec (&ts, 0);
+ }
+ if (clauses->simdlen_divisor)
+ OMP_CLAUSE_SIMDLEN_DIVISOR (c)
+ = gfc_conv_constant_to_tree (clauses->simdlen_divisor);
+ omp_clauses = gfc_trans_add_clause (c, omp_clauses);
- c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_SIMDLEN);
- OMP_CLAUSE_SIMDLEN_EXPR (c) = simdlen_var;
- omp_clauses = gfc_trans_add_clause (c, omp_clauses);
- }
+ if (declare_simd && OMP_CLAUSE_SIMDLEN_TYPE (c))
+ /* By contrast, for 'simd', the sorry is in the middle end. */
+ sorry_at (OMP_CLAUSE_LOCATION (c),
+ "%<simdlen%> clause with %<scaled%> modifier");
}
if (clauses->num_teams_list)
@@ -8706,6 +8706,10 @@ gfc_split_omp_clauses (gfc_code *code,
= code->ext.omp_clauses->safelen_expr;
clausesa[GFC_OMP_SPLIT_SIMD].simdlen_expr
= code->ext.omp_clauses->simdlen_expr;
+ clausesa[GFC_OMP_SPLIT_SIMD].simdlen_type
+ = code->ext.omp_clauses->simdlen_type;
+ clausesa[GFC_OMP_SPLIT_SIMD].simdlen_divisor
+ = code->ext.omp_clauses->simdlen_divisor;
clausesa[GFC_OMP_SPLIT_SIMD].lists[OMP_LIST_ALIGNED]
= code->ext.omp_clauses->lists[OMP_LIST_ALIGNED];
/* Duplicate collapse. */
diff --git a/gcc/testsuite/gfortran.dg/goacc/loop-2-kernels-tile.f95 b/gcc/testsuite/gfortran.dg/goacc/loop-2-kernels-tile.f95
index afc8a278cac..97ea857afa7 100644
--- a/gcc/testsuite/gfortran.dg/goacc/loop-2-kernels-tile.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/loop-2-kernels-tile.f95
@@ -29,10 +29,10 @@ program test
DO j = 1,10
ENDDO
ENDDO
- !$acc loop tile(-1) ! { dg-warning "must be positive" }
+ !$acc loop tile(-1) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1,10
enddo
- !$acc loop tile(i) ! { dg-error "constant expression" }
+ !$acc loop tile(i) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1,10
enddo
!$acc loop tile(2, 2, 1) ! { dg-error "not enough DO loops for tiled" }
@@ -82,10 +82,10 @@ program test
DO j = 1,10
ENDDO
ENDDO
- !$acc kernels loop tile(-1) ! { dg-warning "must be positive" }
+ !$acc kernels loop tile(-1) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1,10
enddo
- !$acc kernels loop tile(i) ! { dg-error "constant expression" }
+ !$acc kernels loop tile(i) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1,10
enddo
!$acc kernels loop tile(2, 2, 1) ! { dg-error "not enough DO loops for tiled" }
diff --git a/gcc/testsuite/gfortran.dg/goacc/loop-2-parallel-tile.f95 b/gcc/testsuite/gfortran.dg/goacc/loop-2-parallel-tile.f95
index 4bfca748f75..5039c2e7940 100644
--- a/gcc/testsuite/gfortran.dg/goacc/loop-2-parallel-tile.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/loop-2-parallel-tile.f95
@@ -20,10 +20,10 @@ program test
DO j = 1,10
ENDDO
ENDDO
- !$acc loop tile(-1) ! { dg-warning "must be positive" }
+ !$acc loop tile(-1) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1,10
enddo
- !$acc loop tile(i) ! { dg-error "constant expression" }
+ !$acc loop tile(i) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1,10
enddo
!$acc loop tile(2, 2, 1) ! { dg-error "not enough DO loops for tiled" }
@@ -73,10 +73,10 @@ program test
DO j = 1,10
ENDDO
ENDDO
- !$acc parallel loop tile(-1) ! { dg-warning "must be positive" }
+ !$acc parallel loop tile(-1) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1,10
enddo
- !$acc parallel loop tile(i) ! { dg-error "constant expression" }
+ !$acc parallel loop tile(i) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1,10
enddo
!$acc parallel loop tile(2, 2, 1) ! { dg-error "not enough DO loops for tiled" }
diff --git a/gcc/testsuite/gfortran.dg/goacc/loop-2-serial-tile.f95 b/gcc/testsuite/gfortran.dg/goacc/loop-2-serial-tile.f95
index 79d8d1b9d47..25f200881c7 100644
--- a/gcc/testsuite/gfortran.dg/goacc/loop-2-serial-tile.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/loop-2-serial-tile.f95
@@ -20,10 +20,10 @@ program test
DO j = 1,10
ENDDO
ENDDO
- !$acc loop tile(-1) ! { dg-warning "must be positive" }
+ !$acc loop tile(-1) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1,10
enddo
- !$acc loop tile(i) ! { dg-error "constant expression" }
+ !$acc loop tile(i) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1,10
enddo
!$acc loop tile(2, 2, 1) ! { dg-error "not enough DO loops for tiled" }
@@ -73,10 +73,10 @@ program test
DO j = 1,10
ENDDO
ENDDO
- !$acc serial loop tile(-1) ! { dg-warning "must be positive" }
+ !$acc serial loop tile(-1) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1,10
enddo
- !$acc serial loop tile(i) ! { dg-error "constant expression" }
+ !$acc serial loop tile(i) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1,10
enddo
!$acc serial loop tile(2, 2, 1) ! { dg-error "not enough DO loops for tiled" }
diff --git a/gcc/testsuite/gfortran.dg/goacc/tile-1.f90 b/gcc/testsuite/gfortran.dg/goacc/tile-1.f90
index f609b127df9..316ccccbd6c 100644
--- a/gcc/testsuite/gfortran.dg/goacc/tile-1.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/tile-1.f90
@@ -44,17 +44,17 @@ subroutine parloop
do i = 1, n
end do
- !$acc parallel loop tile(-3) ! { dg-warning "must be positive" }
+ !$acc parallel loop tile(-3) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1, n
end do
- !$acc parallel loop tile(10, -3) ! { dg-warning "must be positive" }
+ !$acc parallel loop tile(10, -3) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1, n
do j = 1, n
end do
end do
- !$acc parallel loop tile(-100, 10, 5) ! { dg-warning "must be positive" }
+ !$acc parallel loop tile(-100, 10, 5) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1, n
do j = 1, n
do k = 1, n
@@ -68,13 +68,13 @@ subroutine parloop
end do
end do
- !$acc parallel loop tile(1, a) ! { dg-error "constant expression" }
+ !$acc parallel loop tile(1, a) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1, n
do j = 1, n
end do
end do
- !$acc parallel loop tile(a, 1) ! { dg-error "constant expression" }
+ !$acc parallel loop tile(a, 1) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1, n
do j = 1, n
end do
@@ -114,11 +114,11 @@ subroutine par
end do
end do
- !$acc loop tile(-2) ! { dg-warning "must be positive" }
+ !$acc loop tile(-2) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1, n
end do
- !$acc loop tile(i) ! { dg-error "constant expression" }
+ !$acc loop tile(i) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1, n
end do
@@ -195,11 +195,11 @@ subroutine kern
end do
end do
- !$acc loop tile(-2) ! { dg-warning "must be positive" }
+ !$acc loop tile(-2) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1, n
end do
- !$acc loop tile(i) ! { dg-error "constant expression" }
+ !$acc loop tile(i) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1, n
end do
@@ -295,17 +295,17 @@ subroutine kernsloop
do i = 1, n
end do
- !$acc kernels loop tile(-3) ! { dg-warning "must be positive" }
+ !$acc kernels loop tile(-3) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1, n
end do
- !$acc kernels loop tile(10, -3) ! { dg-warning "must be positive" }
+ !$acc kernels loop tile(10, -3) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1, n
do j = 1, n
end do
end do
- !$acc kernels loop tile(-100, 10, 5) ! { dg-warning "must be positive" }
+ !$acc kernels loop tile(-100, 10, 5) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1, n
do j = 1, n
do k = 1, n
@@ -319,13 +319,13 @@ subroutine kernsloop
end do
end do
- !$acc kernels loop tile(1, a) ! { dg-error "constant expression" }
+ !$acc kernels loop tile(1, a) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1, n
do j = 1, n
end do
end do
- !$acc kernels loop tile(a, 1) ! { dg-error "constant expression" }
+ !$acc kernels loop tile(a, 1) ! { dg-error "INTEGER expression of TILE clause at .1. must be positive and constant" }
do i = 1, n
do j = 1, n
end do
diff --git a/gcc/testsuite/gfortran.dg/gomp/atomic-18.f90 b/gcc/testsuite/gfortran.dg/gomp/atomic-18.f90
index 6c8f44a1e9e..301c7d99524 100644
--- a/gcc/testsuite/gfortran.dg/gomp/atomic-18.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/atomic-18.f90
@@ -18,8 +18,7 @@ integer, value :: j
!$omp atomic hint(j + 2) ! { dg-error "Value of HINT clause at .1. shall be a valid constant hint expression" }
i = i + 1
!$omp atomic hint(f)
- ! { dg-error "HINT clause at .1. requires a scalar INTEGER expression" "" { target *-*-* } .-1 }
- ! { dg-error "Value of HINT clause at .1. shall be a valid constant hint expression" "" { target *-*-* } .-2 }
+ ! { dg-error "Value of HINT clause at .1. shall be a valid constant hint expression" "" { target *-*-* } .-1 }
i = i + 1
!$omp atomic foobar ! { dg-error "Failed to match clause" }
i = i + 1
diff --git a/gcc/testsuite/gfortran.dg/gomp/atomic-2.f90 b/gcc/testsuite/gfortran.dg/gomp/atomic-2.f90
index b6c1b6a519e..a77f407e84f 100644
--- a/gcc/testsuite/gfortran.dg/gomp/atomic-2.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/atomic-2.f90
@@ -4,8 +4,7 @@ subroutine bar
integer :: i, v
real :: f
!$omp atomic update acq_rel hint("abc")
- ! { dg-error "HINT clause at .1. requires a scalar INTEGER expression" "" { target *-*-* } .-1 }
- ! { dg-error "Value of HINT clause at .1. shall be a valid constant hint expression" "" { target *-*-* } .-2 }
+ ! { dg-error "Value of HINT clause at .1. shall be a valid constant hint expression" "" { target *-*-* } .-1 }
i = i + 1
!$omp end atomic
diff --git a/gcc/testsuite/gfortran.dg/gomp/clauses-1.f90 b/gcc/testsuite/gfortran.dg/gomp/clauses-1.f90
index 0c91ae5ff3e..2fdfe7da887 100644
--- a/gcc/testsuite/gfortran.dg/gomp/clauses-1.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/clauses-1.f90
@@ -26,12 +26,13 @@ module m
contains
-subroutine foo (d, m, i1, i2, i3, p, idp, s, nte, tl, nth, g, nta, fi, pp, q, dd, ntm)
+subroutine foo (d, m, i1, i2, i3, p, idp, s, nte, tl, nth, g, nta, fi, q, dd, ntm)
!$omp declare target (foo)
- integer :: d, m, p, idp, s, nte, tl, nth, g, nta, pp, q, dd, ntm
+ integer :: d, m, p, idp, s, nte, tl, nth, g, nta, q, dd, ntm
logical :: i1, i2, i3, fi
pointer :: q
integer :: i
+ integer, parameter :: pp = 3
!$omp distribute parallel do &
!$omp& private (p) firstprivate (f) collapse(1) dist_schedule(static, 16) &
@@ -73,11 +74,12 @@ subroutine qux (p)
end do
end
-subroutine baz (d, m, i1, i2, i3, p, idp, s, nte, tl, nth, g, nta, fi, pp, q, dd, ntm)
- integer :: d, m, p, idp, s, nte, tl, nth, g, nta, pp, q, dd, ntm
+subroutine baz (d, m, i1, i2, i3, p, idp, s, nte, tl, nth, g, nta, fi, q, dd, ntm)
+ integer :: d, m, p, idp, s, nte, tl, nth, g, nta, q, dd, ntm
logical :: i1, i2, i3, fi
pointer :: q
integer :: i
+ integer, parameter :: pp = 3
!$omp distribute parallel do &
!$omp& private (p) firstprivate (f) collapse(1) dist_schedule(static, 16) &
!$omp& if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) &
@@ -132,11 +134,12 @@ subroutine baz (d, m, i1, i2, i3, p, idp, s, nte, tl, nth, g, nta, fi, pp, q, dd
end do
end
-subroutine bar (d, m, i1, i2, i3, p, idp, s, nte, tl, nth, g, nta, fi, pp, q, dd, ntm)
- integer :: d, m, p, idp, s, nte, tl, nth, g, nta, pp, q, dd(0:5), ntm
+subroutine bar (d, m, i1, i2, i3, p, idp, s, nte, tl, nth, g, nta, fi, q, dd, ntm)
+ integer :: d, m, p, idp, s, nte, tl, nth, g, nta, q, dd(0:5), ntm
logical :: i1, i2, i3, fi
pointer :: q
integer :: i
+ integer, parameter :: pp = 3
!$omp do simd &
!$omp& private (p) firstprivate (f) lastprivate (l) linear (ll:1) reduction(+:r) schedule(static, 4) collapse(1) &
diff --git a/gcc/testsuite/gfortran.dg/gomp/masked-1.f90 b/gcc/testsuite/gfortran.dg/gomp/masked-1.f90
index 2b2526ac712..1502e8724af 100644
--- a/gcc/testsuite/gfortran.dg/gomp/masked-1.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/masked-1.f90
@@ -42,13 +42,14 @@ subroutine foo (x, a)
!$omp end masked
end
-subroutine foobar (d, f, fi, p, s, g, i1, i2, l, ll, nth, ntm, pp, q, r, r2)
+subroutine foobar (d, f, fi, p, s, g, i1, i2, l, ll, nth, ntm, q, r, r2)
implicit none (type, external)
logical :: i1, i2, fi
- integer :: i, d, f, p, s, g, l, ll, nth, ntm, pp, q, r, r2
+ integer :: i, d, f, p, s, g, l, ll, nth, ntm, q, r, r2
allocatable :: q
integer, save :: t
!$omp threadprivate (t)
+ integer, parameter :: pp = 3
!$omp parallel masked &
!$omp& private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) reduction(+:r) &
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr67500.f90 b/gcc/testsuite/gfortran.dg/gomp/pr67500.f90
index 1cecdc48578..f1526f0a903 100644
--- a/gcc/testsuite/gfortran.dg/gomp/pr67500.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/pr67500.f90
@@ -10,11 +10,11 @@ subroutine f2
end
subroutine f3 (i)
- !$omp declare simd simdlen(-2) ! { dg-warning "INTEGER expression of SIMDLEN clause at .1. must be positive" }
+ !$omp declare simd simdlen(-2) ! { dg-error "INTEGER expression of SIMDLEN clause at .1. must be positive and constant" }
end subroutine
subroutine f4
- !$omp declare simd simdlen(0) ! { dg-warning "INTEGER expression of SIMDLEN clause at .1. must be positive" }
+ !$omp declare simd simdlen(0) ! { dg-error "INTEGER expression of SIMDLEN clause at .1. must be positive and constant" }
end
subroutine foo(p, d, n)
@@ -31,11 +31,11 @@ subroutine foo(p, d, n)
do i = 1, 16
end do
- !$omp simd safelen(-2) ! { dg-warning "INTEGER expression of SAFELEN clause at .1. must be positive" }
+ !$omp simd safelen(-2) ! { dg-error "INTEGER expression of SAFELEN clause at .1. must be positive and constant" }
do i = 1, 16
end do
- !$omp simd safelen(0) ! { dg-warning "INTEGER expression of SAFELEN clause at .1. must be positive" }
+ !$omp simd safelen(0) ! { dg-error "INTEGER expression of SAFELEN clause at .1. must be positive and constant" }
do i = 1, 16
end do
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr77516.f90 b/gcc/testsuite/gfortran.dg/gomp/pr77516.f90
index 9c0a95b9f79..0c3259797e0 100644
--- a/gcc/testsuite/gfortran.dg/gomp/pr77516.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/pr77516.f90
@@ -4,7 +4,7 @@
program pr77516
integer :: i, x
x = 0
-!$omp simd safelen(0) reduction(+:x) ! { dg-warning "must be positive" }
+!$omp simd safelen(0) reduction(+:x) ! { dg-error "INTEGER expression of SAFELEN clause at .1. must be positive and constant" }
do i = 1, 8
x = x + 1
end do
diff --git a/gcc/testsuite/gfortran.dg/gomp/simdlen-scaled-1.f90 b/gcc/testsuite/gfortran.dg/gomp/simdlen-scaled-1.f90
new file mode 100644
index 00000000000..b5dd987d11a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/simdlen-scaled-1.f90
@@ -0,0 +1,44 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-gimple -w -funsigned" }
+
+! PR middle-end/127723
+
+module m
+ implicit none
+contains
+ subroutine g1(a)
+ integer :: a
+ !$omp declare simd simdlen(scaled(integer, 1): 1)
+! { dg-message "sorry, unimplemented: 'simdlen' clause with 'scaled' modifier" "" { target *-*-* } .-1 }
+ end
+
+ subroutine g1a(a)
+ integer :: a
+ !$omp declare simd simdlen(scaled(integer ( kind = 4 ), 4): 4)
+! { dg-message "sorry, unimplemented: 'simdlen' clause with 'scaled' modifier" "" { target *-*-* } .-1 }
+ end
+
+ subroutine g2(a)
+ integer :: a
+ !$omp declare simd simdlen(scaled(double precision, 2): 2)
+! { dg-message "sorry, unimplemented: 'simdlen' clause with 'scaled' modifier" "" { target *-*-* } .-1 }
+ end
+
+ subroutine g3(a)
+ integer :: a
+ !$omp declare simd simdlen(scaled(complex(8)): 4)
+! { dg-message "sorry, unimplemented: 'simdlen' clause with 'scaled' modifier" "" { target *-*-* } .-1 }
+ end
+
+ subroutine g4 (a)
+ integer :: a
+ !$omp declare simd simdlen(scaled(unsigned(2)): 4)
+! { dg-message "sorry, unimplemented: 'simdlen' clause with 'scaled' modifier" "" { target *-*-* } .-1 }
+ end
+end
+
+! { dg-final { scan-tree-dump "__attribute__\\(\\(omp declare simd \\(simdlen\\(scaled\\(integer\\(kind=4\\),1\\):1\\)\\)\\)\\)" "gimple" } }
+! { dg-final { scan-tree-dump "__attribute__\\(\\(omp declare simd \\(simdlen\\(scaled\\(integer\\(kind=4\\),4\\):4\\)\\)\\)\\)" "gimple" } }
+! { dg-final { scan-tree-dump "__attribute__\\(\\(omp declare simd \\(simdlen\\(scaled\\(real\\(kind=8\\),2\\):2\\)\\)\\)\\)" "gimple" } }
+! { dg-final { scan-tree-dump "__attribute__\\(\\(omp declare simd \\(simdlen\\(scaled\\(complex\\(kind=8\\)\\):4\\)\\)\\)\\)" "gimple" } }
+! { dg-final { scan-tree-dump "__attribute__\\(\\(omp declare simd \\(simdlen\\(scaled\\(unsigned\\(kind=2\\)\\):4\\)\\)\\)\\)" "gimple" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/simdlen-scaled-2.f90 b/gcc/testsuite/gfortran.dg/gomp/simdlen-scaled-2.f90
new file mode 100644
index 00000000000..4bcfff45472
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/simdlen-scaled-2.f90
@@ -0,0 +1,28 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-original -w" }
+
+! PR middle-end/127723
+
+subroutine f(n, a, d)
+ integer :: i, n, a(*)
+ real :: d(*)
+
+ !$omp simd simdlen(scaled(integer,1): 1) ! { dg-message "sorry, unimplemented: 'simdlen' clause with 'scaled' modifier" }
+ do i = 1, 1
+ a(i) = a(i) + 5
+ end do
+
+ !$omp simd simdlen(scaled(integer(8)): 2) ! { dg-message "sorry, unimplemented: 'simdlen' clause with 'scaled' modifier" }
+ do i = 1, 1
+ a(i) = a(i) + 5
+ end do
+
+ !$omp simd simdlen(scaled(complex(4), 4): 8) ! { dg-message "sorry, unimplemented: 'simdlen' clause with 'scaled' modifier" }
+ do i = 1, 1
+ d(i) = 0.0
+ end do
+end
+
+! { dg-final { scan-tree-dump "#pragma omp simd linear\\(i:1\\) simdlen\\(scaled\\(integer\\(kind=4\\),1\\):1\\)" "original" } }
+! { dg-final { scan-tree-dump "#pragma omp simd linear\\(i:1\\) simdlen\\(scaled\\(integer\\(kind=8\\)\\):2\\)" "original" } }
+! { dg-final { scan-tree-dump "#pragma omp simd linear\\(i:1\\) simdlen\\(scaled\\(complex\\(kind=4\\),4\\):8\\)" "original" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/simdlen-scaled-3.f90 b/gcc/testsuite/gfortran.dg/gomp/simdlen-scaled-3.f90
new file mode 100644
index 00000000000..363376147d6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/simdlen-scaled-3.f90
@@ -0,0 +1,49 @@
+! { dg-do compile }
+
+! PR middle-end/127723
+
+module m
+ implicit none
+ type t
+ end type t
+contains
+subroutine f (n, a, d)
+ integer :: i, n, a(*)
+ real :: d(*)
+
+ !$omp simd simdlen(scaled(integer,1)) ! { dg-error "Expected '\\:' at .1." }
+ do i = 1, 1
+ a(i) = a(i) + 5
+ end do
+
+ !$omp simd simdlen(scaled(integer + 3): 2) ! { dg-error "Expected '\\)' at .1." }
+ do i = 1, 1
+ a(i) = a(i) + 5
+ end do
+
+ !$omp simd simdlen(scaled(4): 8) ! { dg-error "Expected numerical type name at .1." }
+ do i = 1, 1
+ d(i) = 0.0
+ end do
+
+ !$omp simd simdlen(scaled(type(t)): 8) ! { dg-error "Expected numerical type name at .1." }
+ do i = 1, 1
+ d(i) = 0.0
+ end do
+
+ !$omp simd simdlen(scaled(real, n): 8) ! { dg-error "Divisor expression at .1. of the SCALED modifier to SIMDLEN must be a positive scalar constant integer expression" }
+ do i = 1, 1
+ d(i) = 0.0
+ end do
+
+ !$omp simd simdlen(scaled(complex, 0): 8) ! { dg-error "Divisor expression at .1. of the SCALED modifier to SIMDLEN must be a positive scalar constant integer expression" }
+ do i = 1, 1
+ d(i) = 0.0
+ end do
+
+ !$omp simd simdlen(scaled(complex, 1, 0): 8) ! { dg-error "Expected '\\)' at .1." }
+ do i = 1, 1
+ d(i) = 0.0
+ end do
+end
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/simdlen-scaled-4.f90 b/gcc/testsuite/gfortran.dg/gomp/simdlen-scaled-4.f90
new file mode 100644
index 00000000000..55d4d7257f2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/simdlen-scaled-4.f90
@@ -0,0 +1,75 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-gimple -w" }
+
+! PR middle-end/127723
+
+module m
+ implicit none
+ interface
+ subroutine fvarInt3(x); integer, value :: x; end
+ subroutine fvarInt2(x); integer, value :: x; end
+ subroutine fvarInt0(x); integer, value :: x; end
+ subroutine fvar0(x); integer, value :: x; end
+ end interface
+contains
+subroutine fbase (x)
+ integer, value :: x
+ !$omp declare_variant(fvarInt3) match(construct={parallel,simd(simdlen(scaled(integer,2): 8))})
+ !$omp declare_variant(fvarInt2) match(construct={simd(simdlen(scaled(integer,2): 8))})
+ !$omp declare_variant(fvarInt0) match(construct={simd(simdlen(scaled(integer): 8))})
+ !$omp declare_variant(fvar0) match(construct={simd(simdlen(4))})
+end
+end
+
+subroutine f()
+ use m
+ implicit none
+ integer :: i
+
+ !$omp simd simdlen(scaled(integer,2): 8)
+ do i = 1, 1
+ call fbase (1); ! -> fvarInt2
+ end do
+
+ !$omp parallel
+ block
+ !$omp simd simdlen(scaled(integer,2): 8)
+ do i = 1, 1
+ call fbase (11); ! -> fvarInt2
+ end do
+ end block
+
+
+ !$omp simd simdlen(scaled(integer): 8)
+ do i = 1, 1
+ call fbase (2); ! -> fvarInt0
+ end do
+
+ !$omp simd simdlen(4)
+ do i = 1, 1
+ call fbase (3); ! -> fvar0
+ end do
+
+ !$omp simd simdlen(8)
+ do i = 1, 1
+ call fbase (4); ! -> fbase
+ end do
+end subroutine
+
+! Once implemented remove ...
+! { dg-message "sorry, unimplemented: 'simdlen' clause with 'scaled' modifier" "" { target *-*-* } 17 }
+! { dg-message "sorry, unimplemented: 'simdlen' clause with 'scaled' modifier" "" { target *-*-* } 18 }
+! { dg-message "sorry, unimplemented: 'simdlen' clause with 'scaled' modifier" "" { target *-*-* } 19 }
+! { dg-message "sorry, unimplemented: 'simdlen' clause with 'scaled' modifier" "" { target *-*-* } 29 }
+! { dg-message "sorry, unimplemented: 'simdlen' clause with 'scaled' modifier" "" { target *-*-* } 36 }
+! { dg-message "sorry, unimplemented: 'simdlen' clause with 'scaled' modifier" "" { target *-*-* } 43 }
+
+! ... and the following XFAIL should work ... (it fails because the clause is removed)
+! { dg-final { scan-tree-dump-times "fvarint2 \\(1\\);" 1 "gimple" { xfail *-*-* } } }
+! { dg-final { scan-tree-dump-times "fvarint3 \\(11\\);" 1 "gimple" { xfail *-*-* } } }
+! { dg-final { scan-tree-dump-times "fvarint0 \\(2\\);" 1 "gimple" { xfail *-*-* } } }
+
+! { dg-final { scan-tree-dump-times "fvar0 \\(3\\);" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "fbase \\(4\\);" 1 "gimple" } }
+
+! { dg-final { scan-tree-dump "__attribute__\\(\\(omp declare variant base \\(fvar0 match construct = {simd \\(simdlen\\(4\\)\\)}\\), omp declare variant base \\(fvarint0 match construct = {simd \\(simdlen\\(scaled\\(integer\\(kind=4\\)\\):8\\)\\)}\\), omp declare variant base \\(fvarint2 match construct = {simd \\(simdlen\\(scaled\\(integer\\(kind=4\\),2\\):8\\)\\)}\\), omp declare variant base \\(fvarint3 match construct = {parallel, simd \\(simdlen\\(scaled\\(integer\\(kind=4\\),2\\):8\\)\\)}\\)\\)\\)" "gimple" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/simdlen-scaled-5-1.f90 b/gcc/testsuite/gfortran.dg/gomp/simdlen-scaled-5-1.f90
new file mode 100644
index 00000000000..55d4d7257f2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/simdlen-scaled-5-1.f90
@@ -0,0 +1,75 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-gimple -w" }
+
+! PR middle-end/127723
+
+module m
+ implicit none
+ interface
+ subroutine fvarInt3(x); integer, value :: x; end
+ subroutine fvarInt2(x); integer, value :: x; end
+ subroutine fvarInt0(x); integer, value :: x; end
+ subroutine fvar0(x); integer, value :: x; end
+ end interface
+contains
+subroutine fbase (x)
+ integer, value :: x
+ !$omp declare_variant(fvarInt3) match(construct={parallel,simd(simdlen(scaled(integer,2): 8))})
+ !$omp declare_variant(fvarInt2) match(construct={simd(simdlen(scaled(integer,2): 8))})
+ !$omp declare_variant(fvarInt0) match(construct={simd(simdlen(scaled(integer): 8))})
+ !$omp declare_variant(fvar0) match(construct={simd(simdlen(4))})
+end
+end
+
+subroutine f()
+ use m
+ implicit none
+ integer :: i
+
+ !$omp simd simdlen(scaled(integer,2): 8)
+ do i = 1, 1
+ call fbase (1); ! -> fvarInt2
+ end do
+
+ !$omp parallel
+ block
+ !$omp simd simdlen(scaled(integer,2): 8)
+ do i = 1, 1
+ call fbase (11); ! -> fvarInt2
+ end do
+ end block
+
+
+ !$omp simd simdlen(scaled(integer): 8)
+ do i = 1, 1
+ call fbase (2); ! -> fvarInt0
+ end do
+
+ !$omp simd simdlen(4)
+ do i = 1, 1
+ call fbase (3); ! -> fvar0
+ end do
+
+ !$omp simd simdlen(8)
+ do i = 1, 1
+ call fbase (4); ! -> fbase
+ end do
+end subroutine
+
+! Once implemented remove ...
+! { dg-message "sorry, unimplemented: 'simdlen' clause with 'scaled' modifier" "" { target *-*-* } 17 }
+! { dg-message "sorry, unimplemented: 'simdlen' clause with 'scaled' modifier" "" { target *-*-* } 18 }
+! { dg-message "sorry, unimplemented: 'simdlen' clause with 'scaled' modifier" "" { target *-*-* } 19 }
+! { dg-message "sorry, unimplemented: 'simdlen' clause with 'scaled' modifier" "" { target *-*-* } 29 }
+! { dg-message "sorry, unimplemented: 'simdlen' clause with 'scaled' modifier" "" { target *-*-* } 36 }
+! { dg-message "sorry, unimplemented: 'simdlen' clause with 'scaled' modifier" "" { target *-*-* } 43 }
+
+! ... and the following XFAIL should work ... (it fails because the clause is removed)
+! { dg-final { scan-tree-dump-times "fvarint2 \\(1\\);" 1 "gimple" { xfail *-*-* } } }
+! { dg-final { scan-tree-dump-times "fvarint3 \\(11\\);" 1 "gimple" { xfail *-*-* } } }
+! { dg-final { scan-tree-dump-times "fvarint0 \\(2\\);" 1 "gimple" { xfail *-*-* } } }
+
+! { dg-final { scan-tree-dump-times "fvar0 \\(3\\);" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "fbase \\(4\\);" 1 "gimple" } }
+
+! { dg-final { scan-tree-dump "__attribute__\\(\\(omp declare variant base \\(fvar0 match construct = {simd \\(simdlen\\(4\\)\\)}\\), omp declare variant base \\(fvarint0 match construct = {simd \\(simdlen\\(scaled\\(integer\\(kind=4\\)\\):8\\)\\)}\\), omp declare variant base \\(fvarint2 match construct = {simd \\(simdlen\\(scaled\\(integer\\(kind=4\\),2\\):8\\)\\)}\\), omp declare variant base \\(fvarint3 match construct = {parallel, simd \\(simdlen\\(scaled\\(integer\\(kind=4\\),2\\):8\\)\\)}\\)\\)\\)" "gimple" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/simdlen-scaled-5-2.f90 b/gcc/testsuite/gfortran.dg/gomp/simdlen-scaled-5-2.f90
new file mode 100644
index 00000000000..a3e10882538
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/simdlen-scaled-5-2.f90
@@ -0,0 +1,40 @@
+! { dg-do compile { target skip-all-targets } }
+
+! Used via simdlen-scaled-5-1.f90
+
+! PR middle-end/127723
+
+subroutine f()
+ use m
+ implicit none
+ integer :: i
+
+ !$omp simd simdlen(scaled(integer,2): 8)
+ do i = 1, 1
+ call fbase (1); ! -> fvarInt2
+ end do
+
+ !$omp parallel
+ block
+ !$omp simd simdlen(scaled(integer,2): 8)
+ do i = 1, 1
+ call fbase (11); ! -> fvarInt2
+ end do
+ end block
+
+
+ !$omp simd simdlen(scaled(integer): 8)
+ do i = 1, 1
+ call fbase (2); ! -> fvarInt0
+ end do
+
+ !$omp simd simdlen(4)
+ do i = 1, 1
+ call fbase (3); ! -> fvar0
+ end do
+
+ !$omp simd simdlen(8)
+ do i = 1, 1
+ call fbase (4); ! -> fbase
+ end do
+end subroutine
diff --git a/gcc/testsuite/gfortran.dg/gomp/target2.f90 b/gcc/testsuite/gfortran.dg/gomp/target2.f90
index dfe0ec3aefa..1a4cc350cc5 100644
--- a/gcc/testsuite/gfortran.dg/gomp/target2.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/target2.f90
@@ -1,8 +1,9 @@
! { dg-do compile }
! { dg-additional-options "-ffree-line-length-160" }
-subroutine foo (n, s, t, u, v, w)
- integer :: n, i, s, t, u, v, w
+subroutine foo (n, t, u, v, w)
+ integer :: n, i, t, u, v, w
+ integer, parameter :: s = 4
common /bar/ i
!$omp simd safelen(s + 1)
do i = 1, n
diff --git a/gcc/testsuite/gfortran.dg/gomp/taskloop-1.f90 b/gcc/testsuite/gfortran.dg/gomp/taskloop-1.f90
index 46901712a24..e3fef34b219 100644
--- a/gcc/testsuite/gfortran.dg/gomp/taskloop-1.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/taskloop-1.f90
@@ -7,13 +7,14 @@ module m
!$omp declare target to(f, l, ll, r, r2)
end module m
-subroutine foo(fi, p, pp, g, s, nta, nth, ntm, i1, i2, i3, q)
+subroutine foo(fi, p, g, s, nta, nth, ntm, i1, i2, i3, q)
use m
implicit none
- integer, value :: p, pp, g, s, nta, nth, ntm
+ integer, value :: p, g, s, nta, nth, ntm
logical, value :: fi, i1, i2, i3
integer, pointer :: q(:)
integer :: i
+ integer, parameter :: pp = 3
!$omp taskgroup task_reduction(+:r2) !allocate (r2)
!$omp taskloop simd &
diff --git a/gcc/testsuite/gfortran.dg/gomp/taskloop-2.f90 b/gcc/testsuite/gfortran.dg/gomp/taskloop-2.f90
index 15ddea8e69d..6a81295d546 100644
--- a/gcc/testsuite/gfortran.dg/gomp/taskloop-2.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/taskloop-2.f90
@@ -41,6 +41,10 @@ end do
!$omp parallel master taskloop simd reduction(inscan, +: r) ! { dg-error "'inscan' REDUCTION clause on construct other than DO, SIMD, DO SIMD, PARALLEL DO, PARALLEL DO SIMD" }
do i = 1, 64 ! { dg-error "OMP SCAN between two structured block sequences" "" { target *-*-* } .-1 }
end do
+
+!$omp parallel master taskloop reduction(+: r) priority(r) ! { dg-error "INTEGER expression of PRIORITY clause at .1. must be non-negtive and constant" }
+do i = 1, 64
+end do
end
diff --git a/gcc/testsuite/gfortran.dg/gomp/tile-7.f90 b/gcc/testsuite/gfortran.dg/gomp/tile-7.f90
index 58559331c5f..2e35e891c57 100644
--- a/gcc/testsuite/gfortran.dg/gomp/tile-7.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/tile-7.f90
@@ -14,7 +14,7 @@ subroutine test
end do
!$omp end tile
- !$omp tile sizes(i) ! { dg-error "SIZES requires constant expression" }
+ !$omp tile sizes(i) ! { dg-error "INTEGER expression of SIZES clause at .1. must be positive and constant" }
do i = 1,100
call dummy(i)
end do
diff --git a/libgomp/testsuite/libgomp.fortran/nestedfn5.f90 b/libgomp/testsuite/libgomp.fortran/nestedfn5.f90
index 28c9b00da67..63210966a2f 100644
--- a/libgomp/testsuite/libgomp.fortran/nestedfn5.f90
+++ b/libgomp/testsuite/libgomp.fortran/nestedfn5.f90
@@ -11,7 +11,7 @@
end
subroutine bar (q)
use iso_c_binding, only: c_ptr, c_loc, c_int
- integer :: a, b, c, d(2:3,4:5), q(19:), h, k, m, n, o, p
+ integer :: a, b, c, d(2:3,4:5), q(19:), h, m, o, p
integer(c_int), target :: e(64)
type (c_ptr) :: f, g(64)
logical :: l
@@ -80,9 +80,10 @@ contains
c = 100
h = 8
m = 0
- n = 64
o = 16
if (l) stop 6
+ block
+ integer, parameter :: n = 64
!$omp target teams distribute parallel do simd if (.not.l) device(a) &
!$omp & num_teams(b) dist_schedule(static, c) num_threads (h) &
!$omp & reduction (+: m) safelen (n) schedule(static, o) &
@@ -91,6 +92,7 @@ contains
m = m + 1
end do
!$omp end target teams distribute parallel do simd
+ end block
if (m /= 64) stop 7
!$omp end target data
end subroutine foo