[llvm-dev] Meaning of loads/stores marked both atomic and volatile

Tim Northover via llvm-dev llvm-dev at lists.llvm.org
Mon Nov 20 23:53:55 PST 2017

On 20 November 2017 at 21:17, PaweĊ‚ Batko <pawel.batko at gmail.com> wrote:
> > There are only a couple of valid uses for volatile these days
> Do you mean volatile used alone or also the combination 'atomic volatile'?

Volatile alone.

> Example 1.
> // shared variable
> int i = 0;
> // call this method from 10 threads
> void foo(){
>     int i = rand() % 2;
>     int j = i;
>     while(i == j){
>         printf("In the loop\n");
>     }
> }
> I claim that the loop can be optimized to an infinite loop by a
> compiler, because apparently j == i at all times in a single threaded
> program.

The global variable i is shadowed by the local there and I can't be
sure exactly what you intended so I won't comment on it directly.

But in general terms atomic LLVM operations with at least "monotonic"
ordering forbid unrestricted store-forwarding within a thread (which I
think would be the first step in eliminating the loop). See
where it's explicitly called out: "If an address is written
monotonic-ally by one thread, and other threads monotonic-ally read
that address repeatedly, the other threads must eventually see the

> Example 2.
> // shared variable
> int i = 0;
> void signalHandler(){
>     i = 1;
> }
> void main(){
>     while(i == 0){
>         printf("In the loop\n");
>     }
> }
> Here I also claim that the loop can be optimized into an infinite loop
> if volatile is not used.

This is an interesting one. Monotonic atomic is again sufficient to
synchronize with another thread (or signal handler I'd argue). But if
this is a signal handler within a thread then that is actually one of
the other valid uses of volatile in C (nearly, it has to be a
sig_atomic_t too). In LLVM IR I think you'd use an atomic with
synchscope("singlethread") for that instead.



More information about the llvm-dev mailing list