If you're on a multi-core or multi-threaded systems then memory/cache behavior is more important...and out of your control.
Nobody cares about CSE, constant hoisting, anymore, because speculative execution will obviate that.
For consumer stuff, you're waiting for the user for 99% of your cycles, so who cares.
For processing environments, overall throughput is more important.
IMO, compiler optimizations these days should mean outputting simple, straight-ahead code that's speculative execution friendly and accesses data sequentially. Work with the branch predictor and with the cache behavior of the CPU. Anything clever will founder at the chip level.