On Sat, Jul 20, 2024 at 02:42:27PM -0600, Sandra Loosemore wrote:
> The OpenMP spec says:
>
> "If trait-property any is specified in the kind trait-selector of the
> device selector set or the target_device selector sets, no other
> trait-property may be specified in the same selector set."
That is OpenMP 5.1 addition, the code was written for OpenMP 5.0, so it was
valid at that time.
> GCC was not previously enforcing this restriction and several testcases
> included such valid constructs. This patch fixes it.
>
> gcc/ChangeLog
> * omp-general.cc (omp_check_context_selector): Reject other
> properties in the same selector set with kind(any).
>
> gcc/testsuite/ChangeLog
> * c-c++-common/gomp/declare-variant-10.c: Fix broken tests.
> * c-c++-common/gomp/declare-variant-3.c: Likewise.
> * c-c++-common/gomp/declare-variant-9.c: Likewise.
> * c-c++-common/gomp/declare-variant-any.c: New.
> * gfortran.dg/gomp/declare-variant-10.f90: Fix broken tests.
> * gfortran.dg/gomp/declare-variant-3.f90: Likewise.
> * gfortran.dg/gomp/declare-variant-9.f90: Likewise.
> * gfortran.dg/gomp/declare-variant-any.f90: Likewise.
> ---
> gcc/omp-general.cc | 31 +++++++++++++++++++
> .../c-c++-common/gomp/declare-variant-10.c | 4 +--
> .../c-c++-common/gomp/declare-variant-3.c | 10 ++----
> .../c-c++-common/gomp/declare-variant-9.c | 4 +--
> .../c-c++-common/gomp/declare-variant-any.c | 10 ++++++
> .../gfortran.dg/gomp/declare-variant-10.f90 | 4 +--
> .../gfortran.dg/gomp/declare-variant-3.f90 | 12 ++-----
> .../gfortran.dg/gomp/declare-variant-9.f90 | 2 +-
> .../gfortran.dg/gomp/declare-variant-any.f90 | 28 +++++++++++++++++
> 9 files changed, 82 insertions(+), 23 deletions(-)
> create mode 100644 gcc/testsuite/c-c++-common/gomp/declare-variant-any.c
> create mode 100644 gcc/testsuite/gfortran.dg/gomp/declare-variant-any.f90
>
> diff --git a/gcc/omp-general.cc b/gcc/omp-general.cc
> index 87a245ec8b3..12f178c5a2d 100644
> --- a/gcc/omp-general.cc
> +++ b/gcc/omp-general.cc
> @@ -1288,6 +1288,8 @@ omp_check_context_selector (location_t loc, tree ctx,
> bool metadirective_p)
> for (tree tss = ctx; tss; tss = TREE_CHAIN (tss))
> {
> enum omp_tss_code tss_code = OMP_TSS_CODE (tss);
> + bool saw_any_prop = false;
> + bool saw_other_prop = false;
>
> /* FIXME: not implemented yet. */
> if (!metadirective_p && tss_code == OMP_TRAIT_SET_TARGET_DEVICE)
> @@ -1325,6 +1327,27 @@ omp_check_context_selector (location_t loc, tree ctx,
> bool metadirective_p)
> else
> ts_seen[ts_code] = true;
>
> +
> + /* If trait-property "any" is specified in the "kind"
> + trait-selector of the "device" selector set or the
> + "target_device" selector sets, no other trait-property
> + may be specified in the same selector set. */
> + if (ts_code == OMP_TRAIT_DEVICE_KIND)
> + for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p))
> + {
> + const char *prop = omp_context_name_list_prop (p);
> + if (!prop)
> + continue;
> + else if (strcmp (prop, "any") == 0)
> + saw_any_prop = true;
> + else
> + saw_other_prop = true;
> + }
> + else if (ts_code == OMP_TRAIT_DEVICE_ARCH
The indentation looks wrong here, should be indented by 2 more columns to
the right.
Anyway, while 5.0/5.1/5.2 had
"Each trait-selector-name can only be specified once."
restriction and in 5.0 it made perfect sense, with the addition
of target_device set in 5.1 this seems to be weird and TR13 has
"Each trait-selector-name may only be specified once in a trait selector set."
So, in 5.1/5.2 pedantically
device={kind(host)},target_device={device_num(whatever),kind(nohost)}
was invalid and I think the code still rejects it, for 6.0 it will be
valid, so wonder if we shouldn't have
OMP_TRAIT_TARGET_DEVICE_KIND,
OMP_TRAIT_TARGET_DEVICE_ISA,
OMP_TRAIT_TARGET_DEVICE_ARCH,
and whether
OMP_TRAIT_DEVICE_NUM,
is appropriate and shouldn't be instead
OMP_TRAIT_TARGET_DEVICE_DEVICE_NUM,
Also wonder if
"If trait-property any is specified in the kind trait-selector of the device
selector set or
the target_device selector sets, no other trait-property may be specified in
the same
selector set."
shouldn't have an exception for device_num, one could possibly just want to
declare that some particular device_num has any kind, so
target_device={device_num(whatever),kind(any)}
rather than just the only pedantically allowed
target_device={kind(any)}
where the latter specifies something (well, nothing) about the default device
num while the
former would specify something (well, nothing) about a chosen device num.
Anyway, if OMP_TRAIT_TARGET_DEVICE_{KIND,ISA,ARCH} are separate from
OMP_TRAIT_DEVICE_{KIND,ISA,ARCH}, all this checking could be done simply by
looking at tss_seen array rather than remembering saw_other_prop. Unhandled
extension selectors don't make it through here anyway.
> + || ts_code == OMP_TRAIT_DEVICE_ISA
> + || ts_code == OMP_TRAIT_DEVICE_NUM)
> + saw_other_prop = true;
> +
> if (omp_ts_map[ts_code].valid_properties == NULL)
> continue;
>
> @@ -1377,6 +1400,14 @@ omp_check_context_selector (location_t loc, tree ctx,
> bool metadirective_p)
> break;
> }
> }
> +
> + if (saw_any_prop && saw_other_prop)
> + {
> + error_at (loc,
> + "no other trait-property may be specified "
> + "in the same selector set with %<kind(\"any\")%>");
> + return error_mark_node;
> + }
> }
> return ctx;
> }
If this can apply (perhaps with small fuzz) to vanilla trunk, guess it can
be committed right now, doesn't need to wait for the rest of the
metadirective patch set.
Jakub