[flang-commits] [flang] [flang][OpenMP] Lower DO and SIMD variants in metadirectives (PR #210810)
via flang-commits
flang-commits at lists.llvm.org
Wed Jul 29 21:49:46 PDT 2026
================
@@ -6054,50 +6284,80 @@ static void genMetadirective(lower::AbstractConverter &converter,
TODO(variantLoc, "declarative METADIRECTIVE variant");
}
+ bool hasLoopAssociation =
+ hasDirectiveAssociation(queue, llvm::omp::Association::LoopNest);
+ if (hasLoopAssociation) {
+ // Name resolution cannot give a metadirective variant its own DSA
+ // scope, so marking its loop IV can otherwise contaminate an enclosing
+ // data environment.
+ if (isNestedInOpenMPDataEnvironment(
+ eval, builder.getInsertionBlock()->getParentOp()))
+ TODO(variantLoc, "loop-associated METADIRECTIVE nested in an OpenMP "
+ "data environment");
+ if (hasUnsupportedDataEnvironmentDirective(queue))
----------------
MattPD wrote:
This guard and its neighbors all sit inside `if (hasLoopAssociation)`. A block-associated variant reaches `genOMPDispatch` without an equivalent check, and it then misses the data-sharing attributes that direct lowering provides.
```fortran
subroutine base_par(n, a)
integer :: n, a(n), i
!$omp parallel
do i = 1, n
a(i) = i
end do
!$omp end parallel
end subroutine
subroutine meta_par(n, a)
integer :: n, a(n), i
!$omp begin metadirective when(implementation={vendor(llvm)}: parallel) otherwise(nothing)
do i = 1, n
a(i) = i
end do
!$omp end metadirective
end subroutine
```
`base_par` privatizes the induction variable, and `meta_par` does not:
```
omp.parallel private(@_QFbase_parEi_private_i32 %3#0 -> %arg2 : !fir.ref<i32>) {
omp.parallel {
```
The `meta_par` loop body stores to the outer `i`. Under `-mmlir --enable-delayed-privatization=false`, `base_par` allocates a thread-local `fir.alloca i32 {bindc_name = "i", pinned, uniq_name = "_QFbase_parEi"}` inside the region. `meta_par` allocates none. Every thread therefore shares `i` in both privatization modes.
`task` loses its attributes the same way. Written directly it emits `omp.task private(@_QFbase_taskEx_firstprivate_i32 ...)`, and under a metadirective it emits a bare `omp.task {`.
This path predates the patch, so the answer may be that it is out of scope. Is the block path deliberately exempt from the data-environment restriction the loop path enforces? If it is not, running `hasUnsupportedDataEnvironmentDirective` before the fall-through dispatch would turn silent wrong code into a TODO.
https://github.com/llvm/llvm-project/pull/210810
More information about the flang-commits
mailing list