https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109767

            Bug ID: 109767
           Summary: [OpenMP][5.2] Missing loop-variable privatization
                    inside 'teams'
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Keywords: openmp, wrong-code
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: burnus at gcc dot gnu.org
  Target Milestone: ---

Cf. https://github.com/SOLLVE/sollve_vv/issues/731

OpenMP 5.1 had:
* "Loop iteration variables inside 'parallel' or task generating constructs are
private in the innermost such construct that encloses the loop."

OpenMP 5.2 added 'teams':
* "Loop iteration variables inside 'parallel', 'teams', or task generating
constructs are private in the innermost such construct that encloses the loop."


In GCC, the 'j' is shared, causing race issues. Testcases:

==> teams-loop-var.c <==
#define N 10
int
main ()
{
  int x[N][N], y[N][N];
  int j;

  #pragma omp teams  // in GCC implied: shared(j)  <<< (!) >>>
                     // [but 'private(j) with gfortran]
    for (int i = 0; i < N; i++)
      for (j = 0; j < N; j++)
        // TR12: #pragma omp atomic write
        x[i][j] = 2*j;

  #pragma omp teams   // in GCC implied: shared(j)  <<< (!) >>>
                      // [but 'private(j) with gfortran]
    #pragma omp loop  // in GCC implied: omp parallel shared(j)  <<< (!) >>>
    for (int i = 0; i < N; i++)
      for (j = 0; j < N; j++)
        // TR12: #pragma omp atomic write
        y[i][j] = j + x[i][j];

  for (int i = 0; i < N; i++)
    for (j = 0; j < N; j++)
      if (y[i][j] != j + 2*j)
        __builtin_abort ();
  return 0;
}


==> teams-loop-var.f90 <==
implicit none
integer, parameter :: N = 10
integer :: x(N,N), y(N,N)
integer :: i, j

!$omp teams  ! in GCC implied: private(j)  [but shared(j) with gcc/g++]
  do i = 1, N
    do j = 1, N
      ! TR12: !$omp atomic write
      x(j,i) = 2*j
    end do
  end do
!$omp end teams

!$omp teams   ! in GCC implied: private(j)  [but shared(j) with gcc/g++]
  !$omp loop  ! gcc generated: omp parallel shared(j) <<< (!) >>>
  do i = 1, N
    do j = 1, N
      ! TR12: !$omp atomic write
      y(j,i) = j + x(j, i)
    end do
  end do
!$omp end teams

do i = 1, N
  do j = 1, N
    if (y(j,i) /= j + 2*j)  &
      stop 1
  end do
end do
end

Reply via email to