[flang-commits] [flang] [llvm] [flang][OpenMP] Track reachable metadirective replacements (PR #219014)
via flang-commits
flang-commits at lists.llvm.org
Fri Sep 11 22:52:01 PDT 2026
================
@@ -289,11 +290,29 @@ isVariantApplicableInContextHelper(const VariantMatchInfo &VMI,
// TODO: Verify SIMD
}
- assert(isSubset<TraitProperty>(VMI.ConstructTraits, Ctx.ConstructTraits) &&
- "Broken invariant!");
+ // A complete ordered match can have several embeddings in the context.
+ // Match backwards to choose the highest-valued one for scoring. Keep the
+ // forward scan's partial matches for the match_any extension.
+ if (ConstructMatches &&
+ ConstructMatches->size() == VMI.ConstructTraits.size()) {
+ ConstructIdx = NoConstructTraits;
+ for (unsigned I = VMI.ConstructTraits.size(); I > 0; --I) {
+ TraitProperty Property = VMI.ConstructTraits[I - 1];
+ while (ConstructIdx > 0 &&
+ Ctx.ConstructTraits[ConstructIdx - 1] != Property)
+ --ConstructIdx;
+ assert(ConstructIdx > 0 && "Previously matched construct not found!");
+ (*ConstructMatches)[I - 1] = --ConstructIdx;
----------------
MattPD wrote:
The highest-match change exposes a device-weight discrepancy in `getVariantMatchScore`. `NoConstructTraits` counts the candidate's construct selectors. [OpenMP 5.2 section 7.3](https://www.openmp.org/wp-content/uploads/OpenMP-API-Specification-5-2.pdf) uses the enclosing context's construct-trait count for the device exponent.
In this two-PARALLEL context, `kind(cpu)` should score 5, and the PARALLEL selector should score 3. Save the reproducer below as `repro.f90` and run `flang -fc1 -fopenmp -fopenmp-version=52 -emit-hlfir -o - repro.f90`. Revision `398137ee50c7` emits `omp.barrier`, while [the exact base](https://github.com/llvm/llvm-project/commit/6c68a1661af7dce1f121fd20dfce72f4ddc4afc9) emits the required `omp.taskyield`. With one PARALLEL, both revisions emit `omp.taskyield`. DECLARE VARIANT also selects the PARALLEL variant instead of the CPU variant in this context.
Could the device weights use the enclosing context's construct-trait count while retaining the correct highest-valued construct match?
```fortran
subroutine device_meta
!$omp parallel
!$omp parallel
!$omp metadirective when(device={kind(cpu)}: taskyield) &
!$omp& when(construct={parallel}: barrier)
!$omp end parallel
!$omp end parallel
end subroutine
```
https://github.com/llvm/llvm-project/pull/219014
More information about the flang-commits
mailing list