[llvm-dev] Memory barrier problem

Jeroen Dobbelaere via llvm-dev llvm-dev at lists.llvm.org
Wed Feb 3 10:44:50 PST 2021


> >> W.r.t. restrict, I'd like to hear more from the language lawyers on their
> original intent when the language construct was born and the current
> interpretation of it in the presence of threading.
> > I would have assumed `__restrict` predates "common" multi-processing in C.
> Since the language of restrict is to this day implying other threads cannot
> access those pointers, I would not dare to argue we should weaken it in order
> to deduce `noalias`.
> >
> > ~ Johannes
> >

Having interacted recently with wg14 to get a better understanding about some of the
corner cases around restrict, I can add the following:

One way to look at a restrict pointer[1], is as if you get a local array.
That means that following code:

  void foo_a(int *restrict rpDest, int *restrict rpSrc, int n) {
     for (int i=0; i<n; ++i)
       rpDest[i] = rpSrc[i]+1;
  }

is allowed to behave as if it was written as follows:
  void foo_b(int *pDest, int *pSrc, int n) {
    int localDest[n];
    int localSrc[n];
    memcpy(&localDest[0], pDest, n*sizeof(int));
    memcpy(&localSrct[0], pSrc, n*sizeof(int));
    for (int i=0; i<n; ++i)
       localDest[i] = localSrc[i]+1;
    memcpy(pDest, &localDest[0], n*sizeof(int));
  }

Calling foo_a and foo_b with overlapping arrays can show different results, depending
on how the loop was optimized. That is an indication that this usage of 'foo_a' is
triggering undefined behavior and should not be done.

Wrt to threading: as long as the restrict pointer (rpDest, rpSrc; localDest, localSrc) is not escaping,
a different thread should not be able to access the memory, as there is no way it can get a pointer 'based on'
the restrict pointer.

Note [1]: things get more interesting when having a 'pointer to a restrict pointer' (aka int *restrict *prp).

Greetings,

Jeroen Dobbelaere



More information about the llvm-dev mailing list