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).