https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93224
--- Comment #2 from Martin Liška <marxin at gcc dot gnu.org> --- One more test-case: $ #include <atomic> int main() { long double value; if constexpr (std::atomic_ref<long double>::is_always_lock_free) { bool ok; const auto mo = std::memory_order_relaxed; std::atomic_ref<long double> a(value); a.exchange(1.0l); auto expected = 1.0l; ok = a.compare_exchange_strong(expected, 204.8l, mo); expected = a.load() + 2; ok = a.compare_exchange_strong(expected, 1.0l, mo); a.fetch_add(3.2l); long double tmp = a.load(); __builtin_printf ("a.load() - 208.0l: %Lf\n", tmp- 208.0l); if ( a.load() != 208.0l ) __builtin_abort (); } return 0; } Running with -O0: a.load() - 208.0l: 0.000000 with -O2: a.load() - 208.0l: -0.000000 Aborted So a negative zero is reached ;)