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

Reply via email to