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