https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93515
--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Thanks for the report, confirmed. Simpler testcase: #include <omp.h> int main () { int i; int a = 42; #pragma omp target teams distribute parallel for defaultmap(tofrom: scalar) for (i = 0; i < 64; ++i) if (omp_get_team_num () == 0) if (omp_get_thread_num () == 0) a = 142; if (a != 142) __builtin_abort (); return 0; } Quick workaround, tak address of the variable(s) somewhere, even with just (void) &a; For the non-addressable scalar vars, gcc sometimes implements shared by taking address of the variable and at other times by performing copy in/out (of course not possible on task/taskloop). Copy in/out works fine if e.g. the parallel is not nested in another parallel/teams or the shared variable is private in the outer parallel/teams. If it is shared in both, copy in/out is not possible. The reason why the above testcase is miscompiled is that the teams immediately nested inside of target is (intentionally ignored), but we need to treat map clauses similarly to the shared clauses. If you take out the target from the above testcase, then it will work, the shared(a) on teams then forces shared(a) on parallel to be passed through reference instead of copy in/out.