Shower thoughts: Since virtually every C/C++ program relies on undefined behavior somewhere (e.g. dlsym casts between void */void (*)(), BSD sockets), there have basically never been miscompilation bugs in the wild, technically speaking.
this is funny but the actual situation is also funny: all real C and C++ applications are written in a non-standardized, undocumented programming language that closely resembles standard C and C++ but has less undefined behavior
It's mostly that, but it happens the other way around to some extent too.
Compilers sometimes decide they should be able to do something and the standard is overly permissive. Then, eventually, maybe the standard gets aligned to what compilers actually felt like doing.
I think it's quite rare for anything significant / prominent but I don't think it's rare for subtle things. They often add text saying something is undefined, when previously it was glossed over, poorly defined or implementations just screwed it up and did broken things.
I just find it quite odd for something to be 'clarified' as making your entire program invalid, because it was previously glossed over. A lot of type punning, infinite loop stuff and now trying to standardize pointer provenance is basically retroactively allowing optimizations.
Compilers consider some optimization important enough to do it even if it's somewhat wrong or not allowed. They do it. Standard catches up and gives them the wording they need to do it. This kind of thing isn't particularly common, but they actually do this in prominent ways.
The usual thing I see which is actually common is they need to deal with these weird edge cases in the language or especially the libraries. They often handle it by adding wording saying it's undefined. Sometimes they do it in a really annoying way that makes lots of code UB.
There are a lot of things where if you actually look at C89, it's hard to see how that could have ended up being considered UB later. Things that we just take for granted as being UB now. I accept that it's how C is, but it's pretty weird to be building on quicksand like that.
If they find a major broken implementation of something, they don't want to declare it unspecified / implementation defined and therefore define that implementation as being broken. Instead, it seems they prefer to gradually add more and more subtle UB where programs are invalid.