Unfortunately you have to choose what you want your C compiler to be.
It can be little more than a macro assembler that preserves "the obvious" behavior of undefined constructs on the target platform. Most compilers will do this by default (-O0).
Or you can opt into using an optimizing compiler (-O2). But when optimization passes ignore the possibility of undefined behavior with unpredictable results (as explicitly allowed by the standard), you get, well, unpredictable results.
Nowadays compilers even offer the "terminating a translation or execution" variant that the standard proposes (-fsanitize=undefined,address). So really, the choice is up to you.
But what people really want is of course: keep the undefined behavior that my program happens to use predictable, but given that constraint, optimize as much as possible (=exploit all the other undefined behavior).
Example: inlining functions is an acceptable optimization, because of course I'm not intentionally using out-of-bounds pointers to grab the return address from the stack.
I'm pretty sure in some compilers (eg llvm) there's no such thing as "no optimizations". -O0 means "I'm politely asking not to spend extra time making my program more efficient", but it's sometimes less efficient to compile the more obvious slower version of something, plus "the less efficient more obvious version" has intuitive meaning but isn't well-defined.
(But I may be wrong for C. I only know this is true for Rust. I'm pretty sure though the reason it's true for Rust has to do with the steps that happen in llvm, and thus would probably also be true for c).
There is zero evidence that this dichotomy is our only choice. You are also conflating two different things. Ignoring possible out of bounds pointers is perfectly fine. Deleting assignments from aliased pointers is not. Very different things.
Or you can opt into using an optimizing compiler (-O2). But when optimization passes ignore the possibility of undefined behavior with unpredictable results (as explicitly allowed by the standard), you get, well, unpredictable results.
Nowadays compilers even offer the "terminating a translation or execution" variant that the standard proposes (-fsanitize=undefined,address). So really, the choice is up to you.
But what people really want is of course: keep the undefined behavior that my program happens to use predictable, but given that constraint, optimize as much as possible (=exploit all the other undefined behavior).
Example: inlining functions is an acceptable optimization, because of course I'm not intentionally using out-of-bounds pointers to grab the return address from the stack.