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.

Reply via email to