[llvm-dev] Hoisting in the presence of volatile loads.

Ralf Jung via llvm-dev llvm-dev at lists.llvm.org
Sat Dec 23 09:53:45 PST 2017


Hi,

ah, I must have missed that.  Sorry for the noise!

; Ralf

On 23.12.2017 18:50, George Burgess IV wrote:
> Right. This conversation was primarily about loads, not stores.
> 
> On Sat, Dec 23, 2017 at 6:39 AM, Hal Finkel <hfinkel at anl.gov> wrote:
>>
>> On 12/23/2017 07:42 AM, Ralf Jung wrote:
>>>
>>> Hi all,
>>>
>>>>> I think that this is the right way to approach this: we should change
>>>>> MemorySSA to be less conservative in this regard. LLVM's language
>>>>> reference is
>>>>> pretty explicit about reordering volatile and non-volatile operations:
>>>>>
>>>>>> The optimizers must not change the number of volatile operations or
>>>>>> change
>>>>>> their order of execution relative to other volatile operations. The
>>>>>> optimizers /may/ change the order of volatile operations relative to
>>>>>> non-volatile operations. This is not Java’s “volatile” and has no
>>>>>> cross-thread synchronization behavior.
>>>>>
>>>>> I see no reason to prevent this kind of reordering, even if the volatile
>>>>> and
>>>>> non-volatile accesses might alias.
>>>>
>>>> Just to chime in here since I was explicitly CCd, I agree with this
>>>> conclusion
>>>> and believe this thread reached the proper result per the appropriate
>>>> specs.
>>>
>>> Please forgive my possible naive question, but I do not understand how
>>> "accessing a volatile object through a non-volatile pointer is UB" is
>>> enough to
>>> justify this optimization.  Don't you also need "accessing a non-volatile
>>> object
>>> through a volatile pointer is UB"?
>>>
>>> In other words, if I understand correctly, this proposed reordering could
>>> change
>>> the behavior of the following program:  <https://godbolt.org/g/zH1Tey>
>>>
>>>
>>> static void foo(int *x, volatile int *y) {
>>>      // These may be reordered now?
>>
>>
>> No. Unless we can somehow prove that x and y don't alias, then the ordering
>> must be preserved (because, if they do alias, then the final result must be
>> 5). volatile should have nothing to do with that.
>>
>>  -Hal
>>
>>>      *x = 4;
>>>      *y = 5;
>>> }
>>>
>>> int bar() {
>>>      int x = 0;
>>>      foo(&x, (volatile int*)&x);
>>>      return x; // MUST return 5
>>> }
>>>
>>>
>>> `x` and `y` alias in `foo` and both point to a non-volatile object;
>>> reordering
>>> them changes what `bar` returns.  Notice that casts to volatile pointers
>>> are
>>> pretty common e.g. in the Linux kernel:
>>>
>>>    #define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
>>>
>>> Am I missing something?
>>>
>>> Kind regards,
>>> Ralf
>>
>>
>> --
>> Hal Finkel
>> Lead, Compiler Technology and Programming Languages
>> Leadership Computing Facility
>> Argonne National Laboratory
>>


More information about the llvm-dev mailing list