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

Ralf Jung via llvm-dev llvm-dev at lists.llvm.org
Sat Dec 23 05:42:02 PST 2017


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?
    *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


More information about the llvm-dev mailing list