https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110799
--- Comment #16 from Alexander Monakov <amonakov at gcc dot gnu.org> --- In C11 and C++11 the issue of compiler-introduced racing loads is discussed as follows (5.1.2.4 Multi-threaded executions and data races in C11): 28 NOTE 14 Transformations that introduce a speculative read of a potentially shared memory location may not preserve the semantics of the program as defined in this standard, since they potentially introduce a data race. However, they are typically valid in the context of an optimizing compiler that targets a specific machine with well-defined semantics for data races. They would be invalid for a hypothetical machine that is not tolerant of races or provides hardware race detection. So for TSan we'd allow hoisting only after TSan instrumentation, and for Helgrind we'd ask them to handle load-load-cmov combo as only consuming one of the loads? I think the other optimizations from comment #8 introduce racing loads more rarely in practice, because they are limited to non-trapping accesses.