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

            Bug ID: 68640
           Summary: foo restrict propagated to foo._omp_fn.0
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Severity: minor
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vries at gcc dot gnu.org
  Target Milestone: ---

I.

Consider parallel-alias.c:
...
#define N 1024

int
foo (int *__restrict__ ap, int *__restrict__ bp)
{
#pragma omp parallel for
  for (unsigned int idx = 0; idx < N; idx++)
    ap[idx] = bp[idx];
}
...

compile with:
...
$ gcc parallel-alias.c -O2 -fopenmp -S
...

At ealias in foo._omp_fn.0, we have:
...
ap_9 = { PARM_NOALIAS(10) }
_24 = { PARM_NOALIAS(10) }
bp_8 = { PARM_NOALIAS(12) }
_27 = { PARM_NOALIAS(12) }
...

resulting in:
...
  # VUSE <.MEM_4>
  _28 = MEM[(intD.6 *)_27 clique 1 base 3];

  # .MEM_29 = VDEF <.MEM_4>
  MEM[(intD.6 *)_24 clique 1 base 2] = _28;
...

So the restrict in foo had an effect in foo._omp_fn.0.

While doing omp-lower, we enter install_var_field with a var with restrict
type:
...
Breakpoint 1, install_var_field (var=0x7ffff61b2080, by_ref=false, mask=3,
ctx=0x2aad910)
    at src/gcc/omp-low.c:1374
1374      tree field, type, sfield = NULL_TREE;
(gdb) call debug_generic_expr (var)
bp
(gdb) call debug_generic_expr (var.typed.type)
int * restrict
...

And declare the field with the same type:
...
1389      type = TREE_TYPE (var);
   ...
1400      field = build_decl (DECL_SOURCE_LOCATION (var),
1401                          FIELD_DECL, DECL_NAME (var), type);
...


II.

Now we rewrite the example a bit to introduce aliasing between ap and bp:
...
#define N 1024

int
foo (int *__restrict__ ap)
{
  int *bp = ap;
#pragma omp parallel for
  for (unsigned int idx = 0; idx < N; idx++)
    ap[idx] = bp[idx];
}
...

at ealias, we have:
...
ap_9 = { PARM_NOALIAS(10) }
_24 = { PARM_NOALIAS(10) }
bp_8 = { NONLOCAL }
_27 = { NONLOCAL }
...

Resulting in:
...
  # VUSE <.MEM_4>
  _28 = *_27;

  # .MEM_29 = VDEF <.MEM_4>
  MEM[(intD.6 *)_24 clique 1 base 2] = _28;
...

So, atm I cannot find an example where we generate wrong code (but that might
happen when we make compute_dependence_clique more aggressive).

But I do wonder whether the usage of the restrict of foo in foo._omp_fn.0 is
intentional or accidental.

Reply via email to