That's called "implementation-defined".
Permissible 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).
However, an update to the standard made this definition non-binding. It is still in the standard, verbatim, but compiler writers have interpreted that to mean they can completely ignore it and build compilers whose behavior goes way outside the "permissible" range.
See https://blog.metaobject.com/2018/07/a-one-word-change-to-c-s...
I have no idea what the authors of the standard would have in mind in putting a non-binding constraint in a standard, unless there's a faction that hopes to make it binding in the future, and hopes this will pave the way.
(I can live without the optimizations, as most code I write is bounded by algorithmic complexity, IO, or not performance sensitive. If I find it neccessary, I'd tune the options for a specific piece of code.)
I know about: -fno-delete-null-pointer-checks -fno-strict-aliasing -fwrapv
Are there any other such options?
It would be just another option to choose from. Solving some of those undefined behaviors may even provide other benefits (e.g., better compiler error messages, optimizations, or portability).