[flang][OpenMP] lastprivate on a distribute construct aborts with not-yet-implemented; adding simd avoids it
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
`lastprivate` on any construct containing `distribute` aborts the compiler with a not-yet-implemented error, unless `simd` is also present.
```fortran
subroutine k(a, b, n, last)
real(8), intent(in) :: a(*)
real(8), intent(inout) :: b(*)
integer, intent(in) :: n
real(8), intent(out) :: last
integer :: i
real(8) :: t
!$omp target teams distribute parallel do lastprivate(t)
do i = 1, n
t = a(i) * 2.0d0
b(i) = t
end do
last = t
end subroutine
```
```
$ flang -fopenmp --offload-arch=gfx90a -O3 -c repro.f90
error: loc(...): flang/lib/Lower/OpenMP/DataSharingProcessor.cpp:424: not yet implemented:
lastprivate clause in constructs other than simd/worksharing-loop/taskloop
LLVM ERROR: aborting
```
Which constructs are affected, same body, only the directive changed:
| directive | result |
|---|---|
| `parallel do lastprivate(t)` | ok |
| `target parallel do lastprivate(t)` | ok |
| `target teams distribute parallel do lastprivate(t)` | **not yet implemented** |
| `target teams distribute lastprivate(t)` | **not yet implemented** |
| `target teams distribute parallel do simd lastprivate(t)` | ok |
So it is `distribute` specifically, and adding `simd` avoids it — presumably because the innermost op is then a `SimdOp`, which `DataSharingProcessor::insertLastPrivateCompare` handles, while `omp::DistributeOp` falls through to the `TODO`.
Workaround: add `simd`. Verified to produce the correct value on gfx90a, three runs of three, `lastprivate` returning 2000.0 for a 1000-iteration loop writing `a(i)*2`.
I am not proposing a patch. Getting `lastprivate` right on `distribute` means identifying the last logical iteration across teams rather than within one loop nest, which looks like it needs more than extending the `isa<>` chain, and I would rather not guess at the semantics.
Raising it because `target teams distribute parallel do` with `lastprivate` is a common shape in offloaded Fortran, and today it is a hard compiler abort rather than a diagnostic the user can act on.
This affects performance-critical applications on large AMD GPU supercomputers, including [MFC](https://github.com/MFlowCode/MFC).
All results above come from validated reproducers and are independently reproducible; they stand on their own.
This was found and root-caused with the assistance of AI tools.
Contributor guide
Research direction
Start with flang/lib/Lower/OpenMP/DataSharingProcessor.cpp, especially insertLastPrivateCompare and the handling of omp::DistributeOp. Use the reproducer in the issue and compare the affected distribute directives with the working parallel do and simd cases. Done means lastprivate no longer aborts for the reported constructs and preserves the expected value on the provided offload test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- fortran
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100