Skip to content

Commit 6085f3f

Browse files
authored
[OpenMP] Address __kmp_dist_for_static_init issue (llvm#129902)
This patch attempts to provide a fix for an issue that appears when the `__kmp_dist_for_static_init` function is called from a serialized team. This is triggered by code generated by flang for `distribute parallel do` constructs whenever an `if` clause for the `parallel` leaf construct is present. This results in the introduction of a call to `__kmpc_fork_call_if` in place of `__kmpc_fork_call`. When it evaluates to `false`, it defers execution to `__kmp_serialized_parallel`, which creates a new serial team that is picked up by `__kmp_dist_for_static_init`, resulting in an incorrect `team` pointer that causes the `nteams == (kmp_uint32)team->t.t_parent->t.t_nproc` assertion to fail. The sequence of calls replicating this issue can be summarized as: - `__kmpc_fork_teams` - `__kmpc_fork_call_if` - `__kmpc_dist_for_static_init_*` Since I am not familiar with the implementation of the OpenMP runtime, it is possible that the above sequence of calls is incorrect, or that the bug can be better fixed in another way, so I am open to discussing this. The following Fortran program can be compiled with flang to show the issue: ```f90 ! Compile and run: flang -fopenmp test.f90 -o test && ./test ! Check LLVM IR: flang -fc1 -emit-llvm -fopenmp test.f90 -o - program main implicit none integer, parameter :: n = 10 integer :: i, idx(n) !$omp teams !$omp distribute parallel do if(.false.) do i=1,n idx(i) = i end do !$omp end teams print *, idx end program ```
1 parent f4feab9 commit 6085f3f

File tree

1 file changed

+6
-0
lines changed

1 file changed

+6
-0
lines changed

openmp/runtime/src/kmp_sched.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,12 @@ static void __kmp_dist_for_static_init(ident_t *loc, kmp_int32 gtid,
542542
nth = th->th.th_team_nproc;
543543
team = th->th.th_team;
544544
KMP_DEBUG_ASSERT(th->th.th_teams_microtask); // we are in the teams construct
545+
// skip optional serialized teams to prevent this from using the wrong teams
546+
// information when called after __kmp_serialized_parallel
547+
// TODO: make __kmp_serialized_parallel eventually call __kmp_fork_in_teams
548+
// to address this edge case
549+
while (team->t.t_parent && team->t.t_serialized)
550+
team = team->t.t_parent;
545551
nteams = th->th.th_teams_size.nteams;
546552
team_id = team->t.t_master_tid;
547553
KMP_DEBUG_ASSERT(nteams == (kmp_uint32)team->t.t_parent->t.t_nproc);

0 commit comments

Comments
 (0)