Inserting a compiler fence fixes it (obviously, because it's a reordering issue).

(The correct output is 1.)

C++ repro (Rust version is part of a large project I don't want to reduce)

```
#include <array>
#include <atomic>
#include <cstddef>
#include <cstdio>
#include <cstring>
#include <sys/mman.h>
#include <unistd.h>

int main() {
// Setup a mirrored ring buffer
const size_t sz = 16 * 1024;
const auto fd = fileno(std::tmpfile());
ftruncate(fd, sz);
char* buffer = (char*)mmap(NULL, 2 * sz, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
mmap(buffer, sz, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0);
mmap(buffer + sz, sz, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0);

// Write to memory
std::array<char, 12> a{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
std::memcpy(buffer + sz - 6, a.data(), 6);
std::memcpy(buffer, a.data() + 6, 6);

// Maybe do a fence
#if DO_FENCE
asm volatile("" : : : "memory");
#endif

// Read from memory (using mirror)
std::array<char, 12> b;
std::memcpy(b.data(), buffer + sz - 6, 12);

std::printf("%i\n", a == b);
}
```

Offending clang++ output with reordered stores/loads circled:

I'm not sure how to express how much the fact that I now know that LLVM can do this in this particular case is worldview breaking; like I've written and have seen code written by other people that has made the wrong assumptions for the last 15+ years.

It is something that makes one go "oh of course it does this" when you see the pieces on the page; especially because it would be highly unlikely for one to be bitten by this on x86.

Follow

@mary I only know C which has different rules than C++, but I'm pretty sure that the C standard wouldn't allow clang to do this. When dereferencing pointers of the same type (or char*), they may alias, and there are sequence points inbetween, so the compiler really shouldn't reorder the access.

So, perhaps this is a compiler bug?

· · Web · 0 · 0 · 0
Sign in to participate in the conversation
Awoo Space

Awoo.space is a Mastodon instance where members can rely on a team of moderators to help resolve conflict, and limits federation with other instances using a specific access list to minimize abuse.

While mature content is allowed here, we strongly believe in being able to choose to engage with content on your own terms, so please make sure to put mature and potentially sensitive content behind the CW feature with enough description that people know what it's about.

Before signing up, please read our community guidelines. While it's a very broad swath of topics it covers, please do your best! We believe that as long as you're putting forth genuine effort to limit harm you might cause – even if you haven't read the document – you'll be okay!