https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93554
Tobias Burnus <burnus at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |burnus at gcc dot gnu.org --- Comment #2 from Tobias Burnus <burnus at gcc dot gnu.org> --- The analogous OpenMP variant [omp target / omp do private(x)] works. The problem seems to be that "private(x)" implies that the data is device private and, hence, it is finalized after the loop and before returning to the host. – But the OpenACC code expects that directly after the loop the "omp return" (internal) pragma comes. * * * The code flow is: expand_omp_for -> t (for OpenACC) -> expand_omp_for_static_nochunk (for OpenMP) i.e. the input in those functions is the same. * * * One has: debug_bb(region->entry): <bb 6> : #pragma omp for private(i) private(x) for (i = 0; i <= 31; i = i + 1) debug_bb(region->cont): <bb 7> : x.a = 1; #pragma omp continue (i, i) debug_bb(region->exit): <bb 10> : #pragma omp return HOWEVER: BRANCH_EDGE (entry_bb)->dest is the code after the region->exit (autodeallocation of the allocatable component x%b); namely "debug_bb((*region->entry->succs)[1]->dest)" [with …[0]->flag == 1 == EDGE_FALLTHRU]: D.3967 = x.b.data; if (D.3967 != 0B) goto <bb 9>; [INV] else goto <bb 10>; [INV] Hence, the second condition of the assert fails for OpenACC: gcc_assert (EDGE_COUNT (entry_bb->succs) == 2 && BRANCH_EDGE (entry_bb)->dest == exit_bb); and likewise the later gcc_assert (FALLTHRU_EDGE (cont_bb)->dest == exit_bb); In OpenMP, the result is the same but there one operates checks: BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest [OpenMP: "bool broken_loop = region->cont == NULL", which is similar to the handling of cont == NULL in the OpenACC code.]