Describe the bug
Originally reported as DevCom-10958910
On 32-bit x86 build, atomic<(u)int64_t> load/store sequence produces unexpected results.
Command-line test case
**********************************************************************
** Visual Studio 2022 Developer Command Prompt v17.14.13-pre.1.0
** Copyright (c) 2025 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x86'
C:\Program Files\Microsoft Visual Studio\2022\Preview>cd %temp%
C:\Users\ALEXG~1\AppData\Local\Temp>type repro.cpp
#include <iostream>
#include <iostream>
#include <atomic>
#include <thread>
struct mre_example {
struct data_t {
alignas(std::hardware_destructive_interference_size) std::atomic<int64_t> atomical{0};
};
data_t* data_ptr;
std::thread reader_thread;
std::thread writer_thread;
mre_example() {
data_ptr = static_cast<data_t *>(_aligned_malloc(sizeof(data_t), 1024));
new (data_ptr) data_t;
reader_thread = std::thread(&reader, data_ptr);
writer_thread = std::thread(&writer, data_ptr);
}
~mre_example() {
reader_thread.join();
writer_thread.join();
_aligned_free(data_ptr);
}
static void writer(data_t* data_ptr) {
auto& data = *data_ptr;
int64_t my_local = 0;
while (true) {
my_local += 100;
if ((my_local % 100) != 0) {
std::cout << "my_local is somehow broken: " << my_local << std::endl;
my_local = 0;
}
data.atomical.store(my_local, std::memory_order_release);
}
}
static void reader(data_t* data_ptr) {
auto& data = *data_ptr;
while (true) {
auto red_atomical = data.atomical.load(std::memory_order_acquire);
if ((red_atomical % 100) != 0) {
std::cout << "red_atomical is broken: " << red_atomical << std::endl;
std::terminate();
}
}
}
};
int main() {
mre_example m1;
mre_example m2;
mre_example m3;
return 0;
}
C:\Users\ALEXG~1\AppData\Local\Temp>clang-cl /std:c++20 /O2 /MT repro.cpp
C:\Users\ALEXG~1\AppData\Local\Temp>repro.exe
red_atomical is broken: 8589933396
Expected behavior
The program should loop forever or until 64-bit integer overflows
STL version
Version 17.14.13 Preview 1.0
Additional context
- Clang bug reported as LLVM-156228
- Workaround using other instirisics or inline assembly may be possible, but may be not worth doing
Describe the bug
Originally reported as DevCom-10958910
On 32-bit x86 build,
atomic<(u)int64_t>load/store sequence produces unexpected results.Command-line test case
Expected behavior
The program should loop forever or until 64-bit integer overflows
STL version
Version 17.14.13 Preview 1.0
Additional context