The "begin declare variant" has different rules for determining
whether a context selector cannot match for purposes of code elision
than we normally use; it excludes the case of a constant false
"condition" selector for the "user" set.

gcc/ChangeLog
        * omp-general.cc (omp_context_selector_matches): Add an optional
        bool argument for the code elision case.
        * omp-general.h (omp_context_selector_matches): Likewise.
---
 gcc/omp-general.cc | 28 ++++++++++++++++++++++++----
 gcc/omp-general.h  |  2 +-
 2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/gcc/omp-general.cc b/gcc/omp-general.cc
index c7b8e17d1f7..2edc0a65abf 100644
--- a/gcc/omp-general.cc
+++ b/gcc/omp-general.cc
@@ -1735,13 +1735,19 @@ omp_construct_traits_match (tree selector_traits, tree 
context_traits,
    CONSTRUCT_CONTEXT is known to be complete and not missing constructs
    filled in later during compilation.
 
+   If DECLARE_VARIANT_ELISION_P is true, the function implements the test
+   for elision of preprocessed code in "begin declare variant" constructs,
+   and returns 0 only for failure to match traits in the device and
+   implementation sets.
+
    Dynamic properties (which are evaluated at run-time) should always
    return 1.  */
 
 int
 omp_context_selector_matches (tree ctx,
                              tree construct_context,
-                             bool complete_p)
+                             bool complete_p,
+                             bool declare_variant_elision_p)
 {
   int ret = 1;
   bool maybe_offloaded = omp_maybe_offloaded (construct_context);
@@ -1753,9 +1759,12 @@ omp_context_selector_matches (tree ctx,
 
       /* Immediately reject the match if there are any ignored
         selectors present.  */
-      for (tree ts = selectors; ts; ts = TREE_CHAIN (ts))
-       if (OMP_TS_CODE (ts) == OMP_TRAIT_INVALID)
-         return 0;
+      if (!declare_variant_elision_p
+         || set == OMP_TRAIT_SET_DEVICE
+         || set == OMP_TRAIT_SET_IMPLEMENTATION)
+       for (tree ts = selectors; ts; ts = TREE_CHAIN (ts))
+         if (OMP_TS_CODE (ts) == OMP_TRAIT_INVALID)
+           return 0;
 
       if (set == OMP_TRAIT_SET_CONSTRUCT)
        {
@@ -2109,6 +2118,13 @@ omp_context_selector_matches (tree ctx,
              break;
            case OMP_TRAIT_USER_CONDITION:
              gcc_assert (set == OMP_TRAIT_SET_USER);
+             /* The spec does not include the "user" set in the things that
+                can trigger code elision in "begin declare variant".  */
+             if (declare_variant_elision_p)
+               {
+                 ret = -1;
+                 break;
+               }
              for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p))
                if (OMP_TP_NAME (p) == NULL_TREE)
                  {
@@ -2124,6 +2140,10 @@ omp_context_selector_matches (tree ctx,
                    ret = -1;
                  }
              break;
+           case OMP_TRAIT_INVALID:
+             /* This is only for the declare_variant_elision_p case.  */
+             ret = -1;
+             break;
            default:
              break;
            }
diff --git a/gcc/omp-general.h b/gcc/omp-general.h
index 466a70c9485..ec5a40fe6fa 100644
--- a/gcc/omp-general.h
+++ b/gcc/omp-general.h
@@ -205,7 +205,7 @@ extern bool omp_check_for_duplicate_variant (location_t loc,
                                             tree base_decl, tree ctx);
 extern void omp_mark_declare_variant (location_t loc, tree variant,
                                      tree construct);
-extern int omp_context_selector_matches (tree, tree, bool);
+extern int omp_context_selector_matches (tree, tree, bool, bool = false);
 extern tree omp_merge_context_selectors (location_t, tree, tree,
                                         enum omp_ctx_directive);
 extern tree resolve_omp_target_device_matches (tree node);
-- 
2.34.1

Reply via email to