[llvm-dev] Memory barrier problem

Johannes Doerfert via llvm-dev llvm-dev at lists.llvm.org
Wed Feb 3 10:52:02 PST 2021


On 2/3/21 12:44 PM, Jeroen Dobbelaere wrote:
>>>> 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.

The way I interpret this is consistent with Eli's opinion and what we 
basically do so far,
restrict is stronger than synchronization since the local arrays are not 
synchronized across
threads. If two threads access the same memory (even well synchronized) 
it breaks the restrict
requirement and is therefor UB.

So a weaker `noalias` or a way to mark uses seems therefore required for 
`noalias` deduction.

~ Johannes


> 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