The Typed Racket optimizer takes a different approach, which (IME) is a bit more robust to unrelated compiler changes.
Every time it applies an optimization, the optimizer emits a log message describing the optimization it just applied. The tests then compare the logs produced when compiling test programs to an expected log that includes all the optimizations that should have happened.
Details here:
This works best with optimizations that are distinct transformations, rather than more global things like register allocation, as Sam said.
Credit: Eli Barzilay initially suggested that approach.