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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2014-05-16
     Ever confirmed|0                           |1

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
More reduced testcase:
int
main ()
{
  int var = 1;
  #pragma omp parallel
    if (var != 1)
      __builtin_abort ();
  #pragma omp task shared(var)
    var = 2;
  return 0;
}

The problem is that previously non-addressable var needs to be turned into
addressable because it is shared in the task, where we can't use copy-in/out,
but by that time we have already processed the #pragma omp parallel and decided
to copy-in/out var there, but later on it is TREE_ADDRESSABLE and thus we
expect that copy-in/out is not used in that case.

Unfortunately, I believe we really have to force no copy-in/out in that case,
consider:
#include <omp.h>
#include <stdlib.h>
#include <unistd.h>

volatile int x;

void
foo ()
{
  int var = 1;
  int i;

  for (i = 0; i < 2; i++)
    {
      if (i == 1)
        {
          #pragma omp parallel
            if (x)
              var++;
            else
              {
                #pragma omp single
                  sleep (4);
              }
        }
      else
        {
          #pragma omp task shared(var)
          {
            sleep (2);
            var = 2;
          }
        }
    }
  #pragma omp taskwait
  if (var != 2)
    abort ();
}

int
main ()
{
  omp_set_nested (1);
  #pragma omp parallel
    #pragma omp single
      foo ();
  return 0;
}

If we decide to use copy-in/out in #pragma omp parallel for var, but the task
will be run in parallel with the #pragma omp parallel, then if the #pragma omp
parallel is entered before var = 2 is set in another thread, it will copy in
value 1, then var = 2 happens and if #pragma omp parallel finishes after that,
it will copy out the value it copied in (1) and the testcase will break, even
when there is actually no data-race originally (the compiler doesn't know the
parallel will not touch var at all).

Reply via email to