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

Hal Finkel via llvm-dev llvm-dev at lists.llvm.org
Sat Dec 23 06:39:34 PST 2017


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