[PATCH][RFC][OpenMP] Forbid target* pragmas in target regions
Ilya Verbin
iverbin@gmail.com
Mon Feb 9 19:46:00 GMT 2015
On 02 Feb 13:15, Jakub Jelinek wrote:
> On Mon, Jan 12, 2015 at 12:22:44AM +0300, Ilya Verbin wrote:
> > Currently if a target* pragma appears within a target region, GCC successfully
> > compiles such code (with a warning). But the binary fails at run-time, since it
> > tries to call GOMP_target* functions on target.
> >
> > The spec says: "If a target, target update, or target data construct appears
> > within a target region then the behavior is unspecified."
> >
> > I see 2 options to make the behavior more user-friendly:
> > 1. To return an error at compile-time.
> > 2. To check at run-time in libgomp whether GOMP_target* is called on target, and
> > perform target-fallback if so.
> >
> > If we will select option #1, the patch is ready.
>
> Option #1 is just wrong. There is nothing wrong with such constructs
> appearing in #pragma omp declare target functions etc., the problem is
> if you hit them at runtime. You can very well have say #pragma omp declare
> target function, that optionally invokes #pragma omp target region e.g.
> based on its parameters, state of global variables, what other functions
> return etc. - and the program can be written so that that condition just
> never happens if the function is already offloaded.
I thought that "If a target, target update, or target data construct appears
within a target region then the behavior is unspecified." applies to '#pragma
omp declare target' functions as well, but evidently this applies only to
'#pragma omp target' regions.
But there is another issue, I forgot to mention it in the first mail.
Here is a testcase:
int main ()
{
#pragma omp target
{
int x;
#pragma omp target map(to: x)
x;
}
}
This causes an ICE in the offload compiler, since .omp_data_sizes.3 and
.omp_data_kinds.4 are used in main._omp_fn.0, which should be compiled for
target, but these variables are static without 'declare target' attribute.
main ()
{
struct .omp_data_t.1 .omp_data_arr.2;
static long unsigned int .omp_data_sizes.3[1] = {4};
static unsigned char .omp_data_kinds.4[1] = {17};
GOMP_target (-1, main._omp_fn.0, 0B, 0, 0B, 0B, 0B);
}
main._omp_fn.0 (void * .omp_data_i)
{
struct .omp_data_t.1 .omp_data_arr.2;
int x;
.omp_data_arr.2.x = &x;
GOMP_target (-1, main._omp_fn.1, 0B, 1, &.omp_data_arr.2,
&.omp_data_sizes.3, &.omp_data_kinds.4);
}
main._omp_fn.1 (struct .omp_data_t.1 & restrict .omp_data_i)
{
int x [value-expr: *.omp_data_i->x];
}
Therefore I wanted just to forbid nested target regions. Or should we make
omp_data_sizes and omp_data_kinds non-static?
-- Ilya
More information about the Gcc-patches
mailing list