[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


================
@@ -377,16 +398,11 @@ static APInt getVariantMatchScore(const VariantMatchInfo &VMI,
     }
   }
 
-  unsigned ConstructIdx = 0;
-  assert(NoConstructTraits == ConstructMatches.size() &&
+  assert(NoConstructTraits >= ConstructMatches.size() &&
          "Mismatch in the construct traits!");
-  for (TraitProperty Property : VMI.ConstructTraits) {
-    assert(getOpenMPContextTraitSetForProperty(Property) ==
-               TraitSet::construct &&
-           "Ill-formed variant match info!");
-    (void)Property;
+  for (unsigned Match : ConstructMatches) {
     // ConstructMatches is the position p - 1 and we need 2^(p-1).
-    Score += (1ULL << ConstructMatches[ConstructIdx++]);
+    Score += (1ULL << Match);
----------------
MattPD wrote:

Valid non-negative scores can still wrap the 64-bit total to zero and reach the null `BestVMI` comparison. The total in the Fortran reproducer is `1 + (2^63 - 1) + (2^63 - 1) + 1`, which equals `2^64`.

Save the Fortran reproducer below as `repro.f90` and run `flang -fc1 -fopenmp -fopenmp-version=52 -fsyntax-only repro.f90`. Revision `398137ee50c7` segfaults in `isStrictSubset`, while [the exact base](https://github.com/llvm/llvm-project/commit/6c68a1661af7dce1f121fd20dfce72f4ddc4afc9) completes semantic checking.

```fortran
subroutine s(n)
  integer :: n, i
  !$omp parallel
  !$omp metadirective &
  !$omp& when(user={condition(score(9223372036854775807_8): .true.)}, &
  !$omp& implementation={vendor(score(9223372036854775807_8): llvm)}, &
  !$omp& construct={parallel}: barrier) &
  !$omp& when(user={condition(.true.)}: taskyield) &
  !$omp& otherwise(nothing)
  !$omp end parallel
end subroutine
```

The new backwards match also reaches `1ULL << 64` for a selector matching construct position 65. The generated case below loses its COLLAPSE diagnostic on `398137ee50c7`. Both the exact base and [the previous reviewed head](https://github.com/llvm/llvm-project/commit/7f525837ea63510daf8d9a5db5d15695a565ff11) report it. Could the scorer preserve the mathematical values and ordering without fixed-width wrap or native-width shifts? Guarding only the null pointer would leave the wrong-ranking case unfixed.

Save this generator as `deep.py`, run `python3 deep.py > deep.f90`, then run the same syntax-only command on `deep.f90`:

```python
print("subroutine deep(n)\n  integer :: n, i\n  !$omp teams")
print("  !$omp parallel\n" * 64, end="")
print("""  !$omp metadirective &
  !$omp& when(user={condition(score(1): .true.)}: nothing) &
  !$omp& when(construct={parallel}: simd collapse(2)) otherwise(nothing)
  do i = 1, n
  end do""")
print("  !$omp end parallel\n" * 64, end="")
print("  !$omp end teams\nend subroutine")
```

https://github.com/llvm/llvm-project/pull/219014


More information about the flang-commits mailing list