IIRC you formally can't promote some memory orders without in some case introducing new behaviors. (You formally can't serialize in some cases, which is quite insane.)

But this is only anecdotal to my point.

What I'm especially against is situations like when we loose a behavior and a culture that was there for C programmers for something like 3 decades, that is rooted on experience on big project with an high number of regular programmers (and not just the Aristotelian idea of what a programmer should be according to (not even really existing) formal logic), and the justification is nothing else than lossy reading of a spec that in a lot of cases never had been written with the intent attributed to it by such compiler authors. Like I said; if you have an obscure arch (and/or mode) on which something results in an undefined behavior, the way the standard is constructed implies it has to call for undefined behavior. At the same time, it is hinted that you should provide stronger guarantee if you can. If e.g. you are considering a shift instruction on your target architecture I see nothing than more appropriate than to map the shift of the langage to such instruction to define the least astonishment behavior. You have no business in the programming langage area if you don't reason like that.

Again: "undefined behavior: behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements" and there even is a note that states: "Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).
EXAMPLE An example of undefined behavior is the behavior on integer overflow."

Now the interpretation of those young clueless hippies is most of the time: just fuck the programmer, his program should be able to run on that DSP that does not exist anymore, so let's fuck it as well on x86 so it will crash faster where it ran flawlessly during 3 decades and each one of the hundreds of programmers who reviewed it at that time agreed on what it should do, because at least it will crash faster, and this is what we do now.

And honestly, the only reaction that kind of attitude inspire is: fuck them and that kind of bullshit. I have no confidence in people that even think for 1sec it could a good idea to discuss about how technically uint8_t is not mandated to alias everything, and to my horror I've witness that very thread... When you pretend to be a compiler author and get to that point, you should just change your career before you become too dangerous.

Now for practical purposes, if you want the list of options to get back a half-sane compiler behavior take a look at what Linux uses, because Linus is even less tolerant than I am to technical insanity and wicked default choices. Then triple check the current manpage of your exact version to see if you need to disable some extra "optimizations". Only then you (and your team) can start to program some general purpose stuff without putting your users in danger -- and you should still strive to be as compliant as possible BTW, but that's what of the thing real engineering is about: safety in depth.