[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