Is this compiler transformation allowed?

c++, c++11, data-race, multithreading

Solution

Unlike I wrote in my incorrect comment, this transformation is actually not allowed if `y` is potentially shared between threads and the compiler cannot prove any existing UB in the original code.

The standard explicitly says:

Compiler transformations that introduce assignments to a potentially shared memory location that would not be modified by the abstract machine are generally precluded by this standard, since such an assignment might overwrite another assignment by a different thread in cases in which an abstract machine execution would not have encountered a data race.

[intro.multithread] (1.10/22) in N3337, (1.10/25) in N4141.

So if `x` is always 0, the original code would be race-free, while the transformed one wouldn't. Thus the transformation is not legal.

Problem

Consider this code, where `x` and `y` are integers: ``` if (x) y = 42; ``` Is the following compiler transformation allowed ? ``` int tmp = y; y = 42; if (!x) y = tmp; ``` context: This is from Bjarne Stroustrup's FAQ: ``` // start with x==0 and y==0 if (x) y = 1; // Thread 1 if (y) x = 1; // Thread 2 ``` The FAQ states this is data race free; with `x` and `y` both 0, none of the vars should be written to. But what if the transformation is allowed ?

Original source