Wouldn't the compiler take care of producing the correct machine code?

The issue is that the C memory model allows more behaviours than the memory model of x86-64 processors. You can thus write code which is incorrect according to the C language specification but will happen to work on x86-64 processors. Moving to arm64 (with its weaker memory model than x86-64) will then reveal the latent bug in your program.

This architecture trick was often used for precisely this - finding bugs in the program that would work in one architecture and fail in another. A very common class of issues like these was about endianness, and PowerPC was very handy because it could boot as both high and low-endian modes (I think I remember different versions of Linux for each mode, but I'm no longer sure).

Starting with POWER8, the Linux kernel and some of the BSDs support 64-bit PowerPC in both big- and little-endian modes. Older PowerPC chips had more limited support for little-endian, and all the commercial desktop/server PowerPC OSes that come immediately to mind (classic Mac OS, Mac OS X, NEXTSTEP / OpenStep, OS/400 / IBM i, AIX, BeOS) are big-endian only.

As you'd expect, Linux distribution support for big- and little-endian varies.

And “happen to work on x86-64 processors” also will depend on the compiler. If you write

  *a = 1;
  *b = 'p';
both the compiler and the CPU can freely pick the order in which those two happen (or even execute them in parallel, or do half of one first, then the other, then the other half of the first, but I think those are hypothetical cases)

x86-64 will never do such a swap, but x86-64 compilers might.

If you write

  *a = 1;
  *b = 2;
, things might be different for the C compiler because a and b can alias. The hardware still is free to change that order, though.

OpenBSD famously keeps a lot of esoteric platforms around, because running the same code on multiple architectures reveal a lot of bugs. At least that was one of the arguments previously.

Which is why Windows NT was multiplatform in 1993.

Developed on Intel i860, then MIPS, and only then on x86, alongside Alpha.

Big endian MIPS, no less! At least initially.

I don't think the i860 port lasted very long. IIRC, the performance in context switches was atrocious.

What is "correct"? If you write code that stores two values and the compiler emits two stores, that's correct. If the programmer has judged that the order of those stores is important, the compiler may not have any obligation to agree with the programmer. And even if it does, the compiler is likely only obligated to ensure the ordering as seen by the current thread, so two plain load instructions in the proper order would be enough to be "correct." But if the programmer is relying on those stores being seen in a particular order by other threads, then there's a problem.

Compilers can only be relied on to emit code that's correct in terms of the language spec, not the programmer's intent.

The compiler relies on the language and programmer to enforce and follow a memory consistency model