It's more that things were left undefined for portability and compiler authors (ab)used them for optimization enough for that to become de facto true (especially now that portability is easier).
And if all C users decided that, now that portability is much easier, it was time to define some of that behavior, it would happen.
But, as much as people want to blame optimizing compilers for their behavior around UB, absolutely no one is going to sacrifice C's performance for safety.
This is absolutely correct. The specs of C allow so much undefined behavior in order to let the compiler just emit the instructions for the arithmetic operation or memory access or whatever. For edge cases like overflow and bounds, C deliberately says "not my problem" and you just get whatever that hardware architecture happens to do with that instruction. It's a deliberately leaky abstraction.