Undefined Behavior (UB) occurs when, via unsafe, you violate the input constraints of the LLVM backend of the compiler. Once you violate those constraints LLVM is free to "miscompile" (from your perspective) every last bit of your code in its quest for hyper-optimization. It doesn't matter whether you actually try to execute the offending code; its mere existence in LLVM's input is what triggers the "miscompilation".
Rust has interior mutability, so a shared static can hold e.g. a Mutex that makes it safely mutable (Mutex and other such types contain special magic UnsafeCell that isn't optimized the way references are).
The UB comes from aliasing information given to LLVM. As soon as the reference exists, LLVM is informed about it, and it can make assumptions about this memory, and everything related to it. Optimizer is evaluating all the "what-ifs" about the code, so even if you don't dereference an invalid reference, LLVM can see what would happen if you did.
To elaborate further, interior mutability works by replacing the rustc compiler's compile-time checks with run-time checking, which require real code and execution time, and which usually result in a panic if/when Rust's exclusive-access constraint is violated.
I just want to point out that interior mutability in itself just prevents some optimizations. The types built on top of it often have a run-time cost however.