[OpenMP] Publish target-init team state with acq_rel barrier (#208701)
In __kmpc_target_init, thread 0 initializes the team state in LDS
(HasThreadState = 0, ThreadStates = nullptr) and then releases the other
threads with synchronize::threadsAligned(atomic::relaxed). Because the
relaxed ordering emits no memory fence, the initializing LDS stores are
not guaranteed to be visible to the worker threads before they proceed.
A worker thread can then read the uninitialized team state and produce
wrong results or crash. This is the flow that causes the race as I
understand it.
```
__kmpc_target_init (Kernel.cpp:107)
-> initializeRuntime (Kernel.cpp:38)
-> state::init (State.cpp:286)
-> TeamState.init(IsSPMD) (State.cpp:295)
-> HasThreadState = false (State.cpp:248) // <-- the value later read stale
ThreadStates = nullptr (State.cpp:296)
-> synchronize::threadsAligned(atomic::relaxed) (Kernel.cpp:115) // <-- insufficient barrier:
// relaxed emits no fence, so the state stores above are not published to the other threads
... worker threads continue past the barrier ...
__kmpc_parallel_60 (Parallelism.cpp:143)
if (OMP_UNLIKELY(!if_expr || state::HasThreadState || ...)) (Parallelism.cpp:158)
^ reads HasThreadState from LDS; a stale/unpublished value (!= 0)
diverts the worker onto the wrong (serialized) path
```
The fix changes the barrier at Kernel.cpp:115 from atomic::relaxed to
atomic::acq_rel so that the memory fences are emitted.
Reproducing the problem requires an `if` clause with a non-constant
condition on the target region. The worker's read of HasThreadState
originates from the serialized-region check in __kmpc_parallel_60. When
the `if` condition is constant (or absent), the optimizer can prove that
branch is dead and eliminates the HasThreadState load entirely, so the
race has nothing to observe. A non-constant `if` keeps if_expr, and
hence the LDS read alive, exposing the problem.
I have added a Fortran offload regression test that launches a target
region many times to make the timing-dependent race likely to surface.
Fixes https://github.com/llvm/llvm-project/issues/208698.
Assisted-by: Cursor
GitOrigin-RevId: abd72b0eb7807a98c261a6cac35a969f954a76cd
1 file changed