[flang][CUDA] Crash lowering !$cuf kernel do(n) over a mixed DO / DO CONCURRENT nest
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
A `!$cuf kernel do(n)` directive whose loop nest mixes an ordinary counted DO
with an inner multi-index DO CONCURRENT is accepted by semantic analysis but
crashes the compiler during lowering:
```fortran
subroutine cuf_mixed(n, a)
integer :: n
integer, device :: a(n,n,n)
integer :: i, j, k
!$cuf kernel do(3) <<<*,*>>>
do i = 1, n
do concurrent (j=1:n, k=1:n)
a(k,j,i) = 1
end do
end do
end subroutine
```
```
$ bbc -fcuda -emit-hlfir cuf_mixed.cuf -o -
bbc: .../flang/lib/Lower/Bridge.cpp:4054: void (anonymous namespace)::FirConverter::genFIR(
const Fortran::parser::CUFKernelDoConstruct &):
Assertion `bounds && "Expected bounds on the loop construct"' failed.
```
(assertions-enabled build; with assertions off this dereferences an invalid
`std::get_if` result instead).
## Analysis
The semantic check (`DoConstructTightNesting`,
`flang/lib/Semantics/check-cuda.cpp`) counts a DO CONCURRENT's concurrent
control indices toward the required depth, so `do(3)` over
`do` + `do concurrent (j,k)` passes (1 + 2 indices). But the lowering's
bounds-gathering loop in `genFIR(CUFKernelDoConstruct)` branches once, up
front, on whether the *outer* construct is DO CONCURRENT: on the counted-DO
branch it then expects every nested level to be a counted DO with
`LoopControl::Bounds`, and asserts when the descent reaches the inner
DO CONCURRENT (whose loop control holds `LoopControl::Concurrent`, not
`Bounds`).
## Expected behavior
Either semantic analysis should reject a mixed counted-DO / DO CONCURRENT
nest under `!$cuf kernel do(n)` (if it is not meant to be supported), or
lowering should handle the inner DO CONCURRENT's concurrent controls the way
it already does when DO CONCURRENT is the outer construct. A compile-time
error is fine; an assertion failure is not.
## Versions
Reproduced on current main (`33cc9981`, which includes #223579, at
Bridge.cpp:4054) and on earlier revisions; pre-existing, not introduced by
#223579 (verified by A/B against the commit before it — same assert both
sides).
(Submitted with the help of AI.)
Contributor guide
Research direction
Reproduce the failure with the bbc command in the issue, then read genFIR(CUFKernelDoConstruct) in flang/lib/Lower/Bridge.cpp and DoConstructTightNesting in flang/lib/Semantics/check-cuda.cpp. Trace how counted DO and DO CONCURRENT controls are gathered for mixed nests. Done means the example produces a compile-time diagnostic or lowers without an assertion or invalid std::get_if access.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- fortran
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100